EXOPlayer-Android(V2.17.1) MediaMelon SDK with Google IMA DAI

This procedure describes the MediaMelon SDK(with Google IMA DAI) Integration with a ExoPlayer Android . This is a sample integration done with the sample application from the Google IMA DAI.

Prerequisites:

  1. Google IMA DAI Sample app (link for the sample app - https://github.com/googleads/googleads-ima-android-dai) Documentation of the sample app -https://developers.google.com/interactive-media-ads/docs/sdks/android/dai

  2. MediaMelon SmartSight SDKexoplayer-smartstreaming-release.aar

  3. MediaMelon-assigned Customer ID

Note: If you do not know your Customer ID contact mediamelon at support@mediamelon.com

Step 1: Set up the build environment

The SDK files are added to the build environment and the required network permissions are enabled.

  1. Copy exoplayer-smartstreaming-release.aar provided with the release package to BasicExample/app/

  2. Add the following library to BasicExample/app/build.gradle :-

    dependencies {
        .
        .
        implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.24.0'
        implementation 'com.google.android.exoplayer:exoplayer:2.17.1'
        api files ('exoplayer-smartstreaming-release.aar')
        .
        .
    }

Step 2: Add MediaMelon library to Sample App.

Step 2.1 : Add the below imports to: BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/MyActivity.java

import com.mediamelon.smartstreaming.MMAVAssetInformation;
import com.mediamelon.smartstreaming.MMQBRMode;
import com.mediamelon.smartstreaming.MMRegistrationInformation;
import com.mediamelon.smartstreaming.MMSmartStreaming;
import com.mediamelon.smartstreaming.MMSmartStreamingExo2;

Step 2.2 : Add the below imports to: BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\samplevideoplayer/SampleVideoPlayer.java

import com.mediamelon.qubit.ep.ContentMetadata;
import com.mediamelon.smartstreaming.MMQBRMode;
import com.mediamelon.smartstreaming.MMSmartStreamingExo2;

Step 2.3 : Add the below imports to: BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/SampleAdsWrapper.java

import com.mediamelon.smartstreaming.MMAnalyticsBridge;
import com.mediamelon.smartstreaming.MMSmartStreamingExo2;

Step 3 : Integrate MediaMelon code to the Sample App

The below steps shows the procedure to integrate the MediaMelon library to the sample app. Note - Only the code written inside the <MediaMelon Integration> tag is to be added for MediaMelon specific integration , the rest of the code above and below the <MediaMelon Integration> tag is shown just to give a context ,as shown below :-

<MediaMelon Integration>
Code for MediaMelon specific integration
<//MediaMelon Integration>

Step 3.1: Add the following code to: BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\samplevideoplayer/SampleVideoPlayer.java

private void initPlayer() { // this is the function that creates/initialises the EXO player
  release();
  simpleExoPlayer = new SimpleExoPlayer.Builder(context).build();
  playerView.setPlayer(simpleExoPlayer);
  .
  .
  .
  .
  <MediaMelon Integration>
  String assetId  = "assetID"; //enter you assetId here
  String assetName = "assetNAME"; // enter your assetname here
  String videoId = "videoID"; // enter your videoId here

  //optional content metadata
  ContentMetadata cm  = new ContentMetadata();
  String episodeNumber ="$episodeNumber ";
  String season = "$season";
  String genre = "$genre";
  String drmProtection = "$drmProtection";
  String contentType = "$contentType";
  String title = "$title";
  String videoType  = "$videoType";
  cm.videoId=videoId;
  cm.seriesTitle=title;
  cm.season=season;
  cm.genre=genre;
  cm.episodeNumber=episodeNumber;
  cm.drmProtection=drmProtection;
  cm.contentType=contentType;
  cm.assetName=assetName;
  cm.assetId=assetId;
  cm.videoType = videoType;
  JSONObject ContentMetadataAsJSON = cm.getJSONObject();
  //the below initializeSession() call is to be made only after the EXO player instance has been created
  MMSmartStreamingExo2.getInstance().initializeSession(simpleExoPlayer,MMQBRMode.QBRModeDisabled,"$streamUrl",null,assetId,assetName,videoId,null,ContentMetadataAsJSON);
  //(optional) add custom tags
  MMSmartStreamingExo2.getInstance().reportCustomMetadata("key","value");
  MMSmartStreamingExo2.getInstance().reportUserInitiatedPlayback();
  <//MediaMelon Integration>
};

private void release() {
  if (simpleExoPlayer != null) {
    simpleExoPlayer.release();
    simpleExoPlayer = null;
    streamRequested = false;
    <MediaMelon Integration>
    MMSmartStreamingExo2.getInstance().reportPlayerState(false, Player.STATE_ENDED);
    <//MediaMelon Integration>
  }
}

Step 3.2: Add the following code to: BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/MyActivity.java

@Override
  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    .
    .
    .
    .
    <MediaMelon Integration>
    Log.d("SmartStreamingIntgr", MMSmartStreamingExo2.getVersion());
    MMSmartStreamingExo2.enableLogTrace(true); //set to "false" before releasing player to production
    if (MMSmartStreamingExo2.getRegistrationStatus() == false){ //Check if it is the first time Registration process is done
      MMSmartStreamingExo2.registerMMSmartStreaming("$PLAYERNAME", "$CustomerId", "$SUBSCRIBERID", "$DOMAINNAME", "$SUBSCRIBERTYPE", "$SUBSCRIBERTAG");
      MMSmartStreamingExo2.reportPlayerInfo("$Brand", "$Model", "$Version");
      MMSmartStreamingExo2.getInstance().setContext(getApplicationContext()); //Please make sure to provide the application's context here, and not the activity's context
    }
    <//MediaMelon Integration>
    .
    .
    .
    .

  }

Variable

Description

$PLAYERNAME

String containing the player version (e.g. “Bitmovin_Android_Player_2.28.0”).

$CUSTOMERID

String containing your MediaMelon-assigned Customer ID.

$SUBSCRIBERID

String containing your subscriber’s ID. If you do not use subscriber IDs, enter null

$DOMAINNAME

String containing your section of your subscriber or assets. (Optional)

$SUBSCRIBERTYPE

String containing the subscriber type (e.g. “Free”, “Paid”). If you do not use subscriber types, enter null

$SUBSCRIBERTAG

String containing an additional subscriber-specific information. This is sent in clear (not hashed) to SmartSight and it is advised to not send sensitive information in this field.

$ASSETID

String containing Asset Id.

$ASSETNAME

String containing Asset Name.

$VIDEOID

String containing your video’s ID. If you do not use videos IDs, enter null.

$PLAYER_BRAND

String containing the player brand (e.g. “bitmovin”).

$PLAYER_MODEL

String containing the player model. For example - This could be a variant of player. Say name of third party player used by organisation. Or any human readable name of the player.

$PLAYER_VERSION

String containing the player version.

Step 3.3 : Add the following code to: BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/SampleAdsWrapper.java

private final ImaSdkFactory sdkFactory;
private AdsLoader adsLoader;
private StreamDisplayContainer displayContainer;
private StreamManager streamManager;
private final List<VideoStreamPlayer.VideoStreamPlayerCallback> playerCallbacks;
.
.
<MediaMelon Integration>
MMAnalyticsBridge analyticsBridgeObject; // Declaration of Analytics Bridge object , wherever the IMA AdsLoader and IMA StreamManager are declared in your application
<//MediaMelon Integration>
private void createAdsLoader() { // this functions creates the Google IMA DAI ads loader (which is preferably a singleton - only one ads loader for the entire lifecyle)
  ImaSdkSettings settings = sdkFactory.createImaSdkSettings();
  <MediaMelon Integration>
  analyticsBridgeObject = MMSmartStreamingExo2.getInstance().getAnalyticsBridge(); // get the Analytics Bridge Object ,this should be done wherever in your application the Google IMA adsLoader is created
  <//MediaMelon Integration>
  .
  .
  .
  adsLoader = sdkFactory.createAdsLoader(context, settings, displayContainer);
}
public void requestAndPlayAds() {  
  .
  .
  <MediaMelon Integration>
  adsLoader.addAdErrorListener(analyticsBridgeObject); // pass the Analytics Bridge object to the ads error listeners
  adsLoader.addAdsLoadedListener(analyticsBridgeObject); // pass the Analytics Bridge object to the ads loaded listeners
  <//MediaMelon Integration>
  .
  .
  adsLoader.addAdErrorListener(this);
  adsLoader.addAdsLoadedListener(this); 
  adsLoader.requestStream(buildStreamRequest());
  .
  . 
}
 @Override
  public void onAdsManagerLoaded(AdsManagerLoadedEvent event) {
    .
    .
    <MediaMelon Integration>
    streamManager.addAdErrorListener(analyticsBridgeObject); // pass the Analytics Bridge object to the ad error listeners
    streamManager.addAdEventListener(analyticsBridgeObject); // pass the Analytics Bridge object to the ad event listeners
    <//MediaMelon Integration>
    .
    .
    streamManager.addAdErrorListener(this);
    streamManager.addAdEventListener(this);
    streamManager.init();
    .
    .
  }

Step 4: Access the various ad events. You can implement your own business logic on one or more AD events .Please make sure all custom logic for each AD event is implemented here ONLY. List of all Google IMA DAI AD events can be found here :-https://developers.google.com/interactive-media-ads/docs/sdks/android/dai/api/reference/com/google/ads/interactivemedia/v3/api/AdEvent.AdEventType

  @Override
  public void onAdEvent(AdEvent event) { // this is a callback which gets called whenever a AD event occurs
    switch (event.getType()) {
     // Access all ad events here , this method will be automatically called whenever an ad event occurs
      case AD_PROGRESS:
      // write your own logic inside each case
        break;
      case FIRST_QUARTILE:
        // write your own logic inside each case
        break;
      case MIDPOINT:
        // write your own logic inside each case
        break;
      case THIRD_QUARTILE:
        // write your own logic inside each case
        break;
      case COMPLETED:
        // write your own logic inside each case
        break;
      default:
        log(String.format("Event: %s\n", event.getType()));
        break;
    }
  }

Step 5:

Exoplayer has a bug where playerState doesnt change sometimes after a preroll AD has finished, so please call this function whenever your application gets the signal that Ad Break has ended or all ADs in the current break are completed. The below function call is a sample call made from the onAdBreakEnded() callback (https://developers.google.com/interactive-media-ads/docs/sdks/android/dai/api/reference/com/google/ads/interactivemedia/v3/api/player/VideoStreamPlayer.html#public-abstract-void-onadbreakended) fired by Exoplayer when the AD break ends.

@Override
public void onAdBreakEnded() // Re-enable player controls.
{
  MMAnalyticsBridge.reportStartAfterAdBreakEnded();
}

Last updated