> For the complete documentation index, see [llms.txt](https://docs.mediamelon.com/mediamelon-jio-ssai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mediamelon.com/mediamelon-jio-ssai/mediamelon-player-sdk-android/exoplayer-sdk-with-nowtilus-ssai.md).

# Exoplayer SDK with Nowtilus SSAI

&#x20;

## STEP 1 :&#x20;

Each SDK release directory contain the class files required for building a jar which is used in the application . The jar can be created as follows<br>

```
jar cvf <name_of_the_jar>.jar .
```

## STEP 2: Add the .jar file as a dependency in the Exoplayer build.gradle file.<br>

```
api files ('name_of_the_jar.jar')
```

## STEP 3: Add the below lines to the Exoplayer PlayerActivity.java.<br>

```
import com.mediamelon.smartstreaming.MMQBRMode;
import com.mediamelon.smartstreaming.MMSmartStreaming;
import com.mediamelon.smartstreaming.MMSmartStreamingExo2;
import com.mediamelon.smartstreaming.MMSmartStreamingInitializationStatus;
import com.mediamelon.smartstreaming.MMSmartStreamingObserver;
import com.mediamelon.qubit.PropertyReader;
```

## STEP 4 :Register Mediamelon SDK using your assigned customerID.

\
Add the below lines in the **onCreate** method of PlayerActivity.java

```java
Log.d("SmartStreamingIntgr", MMSmartStreamingExo2.getVersion());
PropertyReader.setRegistrationURL("$Registration URL for the MMSDK");
  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
   // Please make the registration API call based on the version of the SDK you are using.
   MMSmartStreamingExo2.registerMMSmartStreaming("$PLAYERNAME", "$CustomerID", "$SUBSCRIBERID", "$DOMAINNAME", "$SUBSCRIBERTYPE", "$SUBSCRIBERTAG");
   MMSmartStreamingExo2.reportPlayerInfo("$PlayerBrand", "$PlayerModel", "$PlayerVersion");
   MMSmartStreamingExo2.getInstance().setContext(getApplicationContext()); //Please make sure to provide the application's context here, and not the activity's context
 }
  MMSmartStreamingExo2.disableManifestsFetch(true); // pass true if you want to disable Manifests Fetch 

```

| Variable         | Description                                                                                                                                                                          |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| $PLAYERNAME      | Player Name as in ExoPlayer, KalturaPlayer etc.                                                                                                                                      |
| $CUSTOMERID      | String containing your MediaMelon-assigned Customer ID.                                                                                                                              |
| $SUBSCRIBERID    | String containing your subscriber’s ID. If you do not use subscriber IDs, leave it as it is.                                                                                         |
| $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, leave it as it is.                                                                  |
| $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, leave it as it is.                                                                                                  |
| $PLAYER\_BRAND   | String containing the player brand (e.g. “Exo”).                                                                                                                                     |
| $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 5 : Disable manifest fetching by the SDK.

If your workflow restricts the manifest to be accessible from both player and the MediaMelon Player SDK simultaneously, then, you can disable the fetch of manifest via :

```
MMSmartStreamingExo2.disableManifestsFetch(true);
```

```swift
Log.d("SmartStreamingIntgr", MMSmartStreamingExo2.getVersion());
PropertyReader.setRegistrationURL("$Registration URL for the MMSDK");
  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
   // Please make the registration API call based on the version of the SDK you are using.
   MMSmartStreamingExo2.registerMMSmartStreaming("$PLAYERNAME", "$CustomerID", "$SUBSCRIBERID", "$DOMAINNAME", "$SUBSCRIBERTYPE", "$SUBSCRIBERTAG");
   MMSmartStreamingExo2.reportPlayerInfo("$PlayerBrand", "$PlayerModel", "$PlayerVersion");
   MMSmartStreamingExo2.getInstance().setContext(getApplicationContext()); //Please make sure to provide the application's context here, and not the activity's context
 }
  MMSmartStreamingExo2.disableManifestsFetch(true); // pass true if you want to disable Manifests Fetch 
```

{% hint style="info" %}
Note: Disable Manifest Fetch is Optional
{% endhint %}

## STEP 6: Create the  Content Metadata object inside the **initializePlayer()** method of PlayerActivity.java .<br>

```java
String assetId  = "assetID"; //enter you assetId here
String assetName = "assetNAME"; // enter your assetname here 
String videoId = "videoID"; // enter your videoId here 
ContentMetadata cm  = new ContentMetadata();
String episodeNumber = "EpisodeNumber";
String season = "Season";
String genre = "Genre";
String drmProtection = "drmProtection";
String contentType = "contentType";
String title = "Title";
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;
JSONObject contentMetadata = cm.getJSONObject();
```

## STEP 7: Get the mediaURL and vastURL from the Nowtilus SSAI stream url.

\
**NOTE** - **The player needs to be given the extracted mediaURL as the playback URL.**\
&#x20;

```json
String streamURL = "NOWTILUS SSAI URL";
/*
The streamURL gives the mediaURL and VastURL as a response as shown below ,extract the mediaURL and vastURL from the response
*/
{"mediaURL":"https://ssaipre.serverside.ai/hls/f18e5f62-230a-4cad-baf7-3d0e6d429aa7/master.m3u8?sid=75291960-6256-11ec-823d-5bdd72099bb9&api-key=31c8e40a-ee55-4a49-8af2-c76375b22b6e","vastURL":"https://ssaipre.serverside.ai/hls/f18e5f62-230a-4cad-baf7-3d0e6d429aa7/75291960-6256-11ec-823d-5bdd72099bb9/vast.xml"}
```

## STEP 8: Add the below lines to the ***initializePlayer()*** method. Add the lines after the player is initialized and not null.

\
\&#xNAN;***NOTE*** - `boolean enablePollingforSSAI`  variable indicates whether the Mediamelon SDK needs to poll for the VAST URL or not. Please set it to true if you want to opt for polling else set it to false.<br>

```java
private void initializePlayer() {
...
...
...
...
MMSmartStreamingExo2.getInstance().initializeSession(player, MMQBRMode.QBRModeDisabled, "Extracted MediaURL from Nowtilus SSAI streamURL", null, assetId, assetName, videoId,null,contentMetadata );
MMSmartStreamingExo2.getInstance().reportUserInitiatedPlayback();
MMSmartStreamingExo2.getInstance().vastURLfromApplication ="extracted vastURL from the NOwtilus SSAI URL";
boolean enablePollingforSSAI = false; // set to true if you want to poll for vast
MMSmartStreamingExo2.getInstance().initNewStream("Extracted MediaURL from Nowtilus SSAI streamURL",enablePollingforSSAI);

```

## STEP 9: Subscribe to AD EVENTS .

```java
MMSmartStreamingNowtilusSSAIPlugin mmSmartStreamingNowtilusSSAIPlugin = MMSmartStreamingExo2.getInstance().getSSAIAdManager();
MMSSAIEventsListeners mmssaiEventsListeners = new MMSSAIEventsListeners() {
  @Override
  public void onAdImpression(mmAd ssaiAdInfo) {
  }

  @Override
  public void onAdComplete(mmAd ssaiAdInfo) {
  }
  @Override
  public void onCueTimelineEnter(mmAd ssaiAdInfo) { 
  }

  @Override
  public void onCueTimelineExit(mmAd ssaiAdInfo) {  
  }

  @Override
  public void onCueTimelineAdded(mmAdTimelineInfo timelineInfo) {  
  }
};
mmSmartStreamingNowtilusSSAIPlugin.addListener(mmssaiEventsListeners);
```

## List of AD EVENTS

```
onAdImpression
onAdStarted
onAdFirstQuartile
onAdMidpoint
onAdThirdQuartile
onAdProgress
onAdComplete
onCueTimelineAdded 
onCueTimelineEnter
onCueTimelineExit
```

| Event Callback     | Description                                                               |
| ------------------ | ------------------------------------------------------------------------- |
| onAdImpression     | Fired when an Ad Impression occurs                                        |
| onAdStarted        | Fired when Ad starts playing                                              |
| onAdFirstQuartile  | Fired when Ad playback reaches the First Quartile point                   |
| onAdMidpoint       | Fired when Ad playback reaches the Midpoint                               |
| onAdThirdQuartile  | Fired when Ad playback reaches the Third Quartile point                   |
| onAdProgress       | Fired every second during Ad Playback, used to track Ad Playback progress |
| onAdComplete       | Fired when Ad Playback completes                                          |
| onCueTimelineAdded | Fired when an Ad break information gets added                             |
| onCueTimelineEnter | Fired when an Ad break ( which can contain multiple Ads) starts           |
| onCueTimeLineExit  | Fired when an Ad break ( which can contain multiple Ads) ends             |

## STEP 10: Add the below lines to the ***releasePlayer()*** method.

```
 protected void releasePlayer() {
    if (player != null) {
      MMSmartStreamingExo2.getInstance().reportPlayerState(false, Player.STATE_ENDED); 
    }
  }
```

## Step 11 : Get Ad Related Information.

You can use the below commands from inside any of the AD Events(listed above) that you subscribe to.

1. &#x20;**`ssaiAdInfo.getTotalAds()`**- returns a `int` which signifies the number of Ads in the current Ad break.
2. &#x20;**`ssaiAdInfo.getClickTrackingURLs()`**-returns the click tracking URLs as a *List\<String>.*
3. **`ssaiAdInfo.getClickThroughURLs()`** -returns the clickthrough URLs as a *List\<String>.*
4. **`ssaiAdInfo.getAdSkipOffset()`-** returns the   AD offset in  `seconds.`
5. **`ssaiAdInfo.getCompleteTrackers()`**` ``-` returns the  AD Complete Tracking URLs as a *List\<String>.*
6. **`ssaiAdInfo.getMidpointTrackers()`**` ``-` returns the  AD Midpoint Tracking URLs as a *List\<String>.*
7. **`ssaiAdInfo.getThirdQuartileTrackers()`**` ``-` returns the  AD ThirdQuartile Tracking URLs as a *List\<String>.*
8. **`ssaiAdInfo.getFirstQuartileTrackers()`**` ``-` returns the  AD FirstQuartile Tracking URLs as a *List\<String>.*
9. **`ssaiAdInfo.getImpressionTrackers()`**` ``-` returns the  AD Impression URLs as a *List\<String>.*
10. **`ssaiAdInfo.getAdIndex()`**` ``-` returns the index of the current AD in the AD break.

## Sample Application

The Sample Application for Exoplayer with Nowtilus SSAI can be donwloaded from&#x20;

sdk.mediamelon.com/\<Customer ID>/Android/ExoPlayer\_2.11.8.zip

sdk.mediamelon.com/\<Customer ID>/Android/ExoPlayer\_2.12.2.zip

## Complete Integration

Inside **onCreate** method<br>

```java
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
   // Please make the registration API call based on the version of the SDK you are using.
   MMSmartStreamingExo2.registerMMSmartStreaming("$PLAYERNAME", "$MMCustomerID", "$SUBSCRIBERID", "$DOMAINNAME", "$SUBSCRIBERTYPE", "$SUBSCRIBERTAG");
   MMSmartStreamingExo2.reportPlayerInfo("CustomPlayerName", ExoPlayerLibraryInfo.VERSION, "1.0");
   MMSmartStreamingExo2.getInstance().setContext(getApplicationContext()); //Please make sure to provide the application's context here, and not the activity's context
 }
```

Inside the  ***initializePlayer()** method*<br>

```java
String assetId  = "assetID"; //enter you assetId here 
String assetName = "assetNAME"; // enter your assetname here
String videoId = "videoID"; // enter your videoId here 
ContentMetadata cm  = new ContentMetadata();
String episodeNumber = "EpisodeNumber";
String season = "Season";
String genre = "Genre";
String drmProtection = "drmProtection";
String contentType = "contentType";
String title = "Title";
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;
JSONObject contentMetadata = cm.getJSONObject();

//initializeSession
MMSmartStreamingExo2.getInstance().initializeSession(player, MMQBRMode.QBRModeDisabled, "Extracted MediaURL from Nowtilus SSAI streamURL", null, assetId, assetName, videoId,null,contentMetadata );
MMSmartStreamingExo2.getInstance().reportUserInitiatedPlayback();
MMSmartStreamingExo2.getInstance().vastURLfromApplication ="extracted vastURL from the NOwtilus SSAI URL";
boolean enablePollingforSSAI = false; // set to true if you want to poll for vast
MMSmartStreamingExo2.getInstance().initNewStream("Extracted MediaURL from Nowtilus SSAI streamURL",enablePollingforSSAI);
//get the SSAI Admanager and subscribe to events
MMSmartStreamingNowtilusSSAIPlugin mmSmartStreamingNowtilusSSAIPlugin = MMSmartStreamingExo2.getInstance().getSSAIAdManager();
MMSSAIEventsListeners mmssaiEventsListeners = new MMSSAIEventsListeners() {
  @Override
  public void onAdImpression(mmAd ssaiAdInfo) {
  }

  @Override
  public void onAdComplete(mmAd ssaiAdInfo) {
  }
  @Override
  public void onCueTimelineEnter(mmAd ssaiAdInfo) { 
  }

  @Override
  public void onCueTimelineExit(mmAd ssaiAdInfo) {  
  }

  @Override
  public void onCueTimelineAdded(mmAdTimelineInfo timelineInfo) {  
  }
};
mmSmartStreamingNowtilusSSAIPlugin.addListener(mmssaiEventsListeners);
```

Inside the ***releasePlayer()*** method<br>

```java
 protected void releasePlayer() {
    if (player != null) {
      MMSmartStreamingExo2.getInstance().reportPlayerState(false, Player.STATE_ENDED); 
    }
  }
```

##
