# ExoPlayer v2.17.1 MediaMelon SDK with 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 SDK`exoplayer-smartstreaming-release.aar`
3. MediaMelon-assigned Customer ID

**Note:** If you do not know your Customer ID contact mediamelon at [support@mediamelon.com](mailto:support%40mediamelon.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` :-<br>

   ```
   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:\
\&#xNAN;*BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/MyActivity.java*

```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*

```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: \
\&#xNAN;*BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/SampleAdsWrapper.java*

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

### &#x20;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 :-

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

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

```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>
};
```

```java
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:\
\&#xNAN;*BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/MyActivity.java*

```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: \
\&#xNAN;*BasicExample\app\src\main\java\com\google\ads\interactivemedia\v3\samples\videoplayerapp/SampleAdsWrapper.java*

```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>
```

```java
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);
}
```

```java
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());
  .
  . 
}
```

```java
 @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>

```java
  @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();
}
```

## <br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mediamelon.com/mediamelon/smartsight-player-sdk-integration/android/exo-ima-sdk-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
