# Custom Multi Player SDK Integration Document

**Step 1:** [Prerequisites and Setup](#step-1-prerequisites-and-setup)

**Step 2:** [Register and Initialize SDK](#step-3-initialize-session-and-report-user-intent-to-playback)

**Step 3:** [Report Session Level Details](#step-3-initialize-session-and-report-user-intent-to-playback-1)

**Step 4:** [Report Player Events](#step-3-initialize-session-and-report-user-intent-to-playback-4)

**Step 5:** [Report Stream and Track Related Events](#step-3-initialize-session-and-report-user-intent-to-playback-5)

**Step 6:** [Report Network Related Information](#step-3-initialize-session-and-report-user-intent-to-playback-9)

Step 7: [Report Errors and Fallback](#step-3-initialize-session-and-report-user-intent-to-playback-10)[s](#step-3-initialize-session-and-report-user-intent-to-playback-10)

Step 8: [Report Ad Events](#step-8-report-a-d-events)

### Step 1: Prerequisites and Setup

* MediaMelon Media3 SDK Maven dependencies or the provided AAR file is necessary.

#### Step 1.1: Set up the build environment&#x20;

> `$MEDIA3PROJECT = {Media3 - v1.x.x}`

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

1. Add MediaMelon Media3 Maven dependency to `$MEDIA3PROJECT/demos/main/build.gradle`
2. Copy `mmsmartstreaming.aar` provided in the release package for the Media3 project. Example  `$MEDIA3PROJECT/demos/main/mmsmartstreaming.aar` .

{% tabs %}
{% tab title="Maven" %}

```gradle
dependencies {
   ...
  implementation 'com.github.MediamelonSDK:mm-java-custom-sdk:2.0.1'
}
```

{% endtab %}

{% tab title="AAR file" %}

```gradle
dependencies {
  ...
  api files ('mmsmartstreaming.aar')
}
```

{% endtab %}
{% endtabs %}

#### Step 1.2: Provide Manifest Permissions

Add network permissions to `$MEDIA3PROJECT/demos/main/src/main/AndroidManifest.xml`

```xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
```

#### Step 1.3: Import Packages

`$MEDIA3PROJECT/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java`

```java
import com.mediamelon.core.qubit.ChunkStatus;
import com.mediamelon.core.qubit.ChunkType;
import com.mediamelon.core.qubit.DeviceInfo;
import com.mediamelon.core.qubit.ManifestStatus;
import com.mediamelon.core.qubit.Rendition;
import com.mediamelon.core.qubit.ep.AdInfo;
import com.mediamelon.core.qubit.ep.ContentMetadata;
import com.mediamelon.wrapper.smartstreaming.MMIntegrationWrapper;
import com.mediamelon.wrapper.smartstreaming.MMPlayerState;
import com.mediamelon.wrapper.smartstreaming.custom_sdk.MMSmartStreamingMedia3;
```

### Step 2: Register and Initialise SDK <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

The player application must register the SDK and provide player information once the player is initialized. Please note that values provided in this integration step persist across video sessions.

The SDK must be initialized at the start of each video session. Initialization includes setting the application context, initializing the playback session, and indicating the intent for playback with the SDK.

{% hint style="info" %}
The `enableLogTrace()` feature should be enabled for testing during the integration process. Set this to False before releasing the player to production.

`MMSmartStreamingMedia3.enableLogTrace(false);`
{% endhint %}

{% hint style="info" %}
CUSTOMER\_ID is your MediaMelon assigned Customer ID. If you do not know your Customer ID contact MediaMelon at <customer-support@mediamelon.com>.
{% endhint %}

#### Step 2.1: Get SDK instance&#x20;

For every new player instance create a new sdk instance.

```java
protected boolean initializePlayer() { 
    if (player == null) { 
    Intent intent = getIntent(); ...
    //get the instance of SDK 
    MMIntegrationWrapper sdkInstance = new MMSmartStreamingMedia3(); 
    
    initializeMediaMelon(sdkInstance); 
    ... 
}
```

#### Step 2.2: Initialize session with SDK instance

```java
void initializeMediaMelon(MMIntegrationWrapper sdkInstance){
    sdkInstance.setContext(applicationContext)
    sdkInstance.registerMMSmartStreaming("PLAYER_NAME", "CUSTOMER_ID", "SUBSCRIBER_ID", "DOMAIN_NAME", "SUBSCRIBER_TYPE", "SUBSCRIBER_TAG", false);
    sdkInstance.reportPlayerInfo("PLAYER_BRAND", "PLAYER_MODEL", "PLAYER_VERSION");
    sdkInstance.reportBasePlayerInfo("BASE_PLAYER_NAME", "BASE_PLAYER_VERSION");
    sdkInstance.reportAppInfo("APP_NAME","APP_VERSION");
    sdkInstance.reportDeviceInfo(deviceInfo);
    sdkInstance.reportDeviceID("DEVICE_ID");
    
    ContentMetadata cm  = new ContentMetadata();
    cm.assetName="ASSET_NAME";
    cm.assetId="ASSET_ID";
    cm.videoId="VIDEO_ID";
    cm.seriesTitle="SERIES_TITLE";
    cm.season="SEASON";
    cm.genre="GENRE";
    cm.episodeNumber="EPISODE_NUMBER";
    cm.drmProtection="DRM_PROTECTION";
    cm.contentType="CONTENT_TYPE";
    cm.drmLevel = "DRM_LEVEL"
    
    sdkInstance.initializeSession(cm, "PLAYER_INSTANCE_ID");
    sdkInstance.reportUserInitiatedPlayback();
}
```

#### Device Info

| Parameter       | Data Type |
| --------------- | --------- |
| brand           | String    |
| deviceModel     | String    |
| os              | String    |
| osVersion       | String    |
| telecomOperator | String    |
| screenWidth     | String    |
| screenHeight    | String    |

### Step 3: Report Session level details <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

#### Step 3.1 Report Experiment Name

Report the experiment names as a list of String.

```java
sdkInstance.reportExperimentNames(List<String>);
```

#### Step 3.2: Report View Session Id <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

```java
sdkInstance.reportViewSessionId("VIEW_SESSION_ID");
```

#### Step 3.3: Report Sub Property Id <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

```java
sdkInstance.reportSubPropertyId("SUB_PROPERTY_ID");
```

#### Step 3.4: Report Time Shift Enabled / DVR enabled

```java
sdkInstance.reportTimeShiftEnabled(isTimeShiftEnabled); // isTimeShiftEnabled -> boolean
```

#### Step 3.5: Report Page Type

```java
sdkInstance.reportPageType("PAGE_TYPE");
```

#### Step 3.6: Report PiP Mode

Report the PiP status of the player. If the player goes into PiP mode throughout the session report *true*.

```java
sdkInstance.reportPipEnabled(isPipEnabled); // isPipEnabled -> boolean
```

#### Step 3.7: Report Device Orientation

Report current orientation of device as string.&#x20;

```java
sdkInstance.reportDeviceOrientation("ORIENTATION");
```

#### Step 3.8: Report Custom Metadata

Report additional custom metadata

```java
sdkInstance.reportCustomMetadata("custom_1", "VALUE_1");
```

### Step 4: Report Player Events <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

#### Step 4.1: Report Player State

{% hint style="info" %}
Make sure to report ***MMPlayerState.STOPPED*** at the end of playback completion to mark session as ended.
{% endhint %}

```java
// Report Player State --> Playing, Paused, Stopped
sdkInstance.reportPlayerState(MMPlayerState.PLAYING);
```

| MMPlayerState |
| ------------- |
| PLAYING       |
| PAUSED        |
| STOPPED       |

#### Step 4.2: Report Buffering Events

```java
//buffering start
sdkInstance.reportBufferingStarted();

//buffering complete
sdkInstance.reportBufferingCompleted();
```

#### Step 4.3 Report Seek Events

```java
//seek started
sdkInstance.reportSeekStarted();
      
//seek completed
sdkInstance.reportSeekCompleted();
```

#### Step 4.4: Report Playback Position

Report Playback position in ms.

```java
sdkInstance.reportPlaybackPosition(playbackpos);
```

### Step 5: Report Stream and Track Related Information <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

#### &#x20;Step 5.1: Report Stream URL <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

Report stream url that is currently being used.

```java
sdkInstance.setStreamURL("STREAM_URL");
```

#### Step 5.2: Report Stream  Information

Report Information related to stream

```java
sdkInstance.reportStreamInfo("STREAM_FORMAT", "MEDIA_TYPE", "SOURCE_TYPE", isLive);
```

#### Step 5.3: Report Video Duration <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

```java
sdkInstance.reportVideoDuration(inMilliSeconds);
```

#### Step 5.4:  Report Track Related Information <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

```java
sdkInstance.reportTrackInfo("AUDIO_TRACK", "SUBTITLE_TRACK", isSubtitleActive, isVDSActive, "VIDEO_TRACK");
```

#### Step 5.5: Report Rendition Changes

Report changes in the rendition of current stream  wrapped in the `Rendition` object.

```java
sdkInstance.reportRendition(renditionObject);
```

#### Rendition Object

| Parameter | Data Type |
| --------- | --------- |
| bitrate   | int       |
| width     | int       |
| height    | int       |
| frameRate | double    |
| aCodec    | String    |
| vCodec    | String    |

### Step 6:  Report Network Related Information <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

#### Step 6.1 Report Network Info

```java
sdkInstance.reportNetworkInfo("CDN", "ASN", "HOST_NAME", "NETWORK_TYPE", "NETWORK_OPERATOR"); 
```

#### Step 6.2: Report Request Status

```java
sdkInstance.reportRequestStatus(RequestStatus, "REQUEST_TYPE", map); // map -> Map<String, String>
```

| RequestStatus |
| ------------- |
| FAILED        |
| CANCELLED     |

#### Step 6.3: Report Player Download rate

```java
sdkInstance.reportPlayerDownloadRate(bps) //  bps -> Long 
```

### Step 7: Report Errors & Fallbacks <a href="#step-3-initialize-session-and-report-user-intent-to-playback" id="step-3-initialize-session-and-report-user-intent-to-playback"></a>

#### Step 7.1: Report Fatal Errors

```java
//Custom Errors 
sdkInstance.reportError(ERROR_CODE_INT, "ERROR_MESSAGE", "ERROR_DETAILS");
```

#### Step 7.2: Report Warnings

```java
sdkInstance.reportWarning(ERROR_CODE_INT, "ERROR_MESSAGE", "ERROR_DETAILS");
```

#### Step 7.3: Report Stream Fallback event

Report fallback events in case a fallback strategy is applied.&#x20;

```java
sdkInstance.reportFallbackEvent("FALLBACK_STREAM_URL", "DESCRIPTION");
```

#### Step 7.4: Update DRM Type

```java
sdkInstance.updateDRMType("DRM_TYPE", "DRM_LEVEL");
```

#### Step 7.5: Update Content Metadata

```java
sdkInstance.updateContentMetadata(cm);
```

### Step 8: Report Ad Events

#### Step 8.1: Report Ad Breaks

```java
sdkInstance.reportAdBreakStarted();
sdkInstance.reportAdBreakEnded();
```

#### Step 8.2: Report Ad Start and End

```java
sdkInstance.reportAdStarted(adInfoObject);
sdkInstance.reportAdEnd();
```

#### Step 8.3 Report Ad Quartile Events

```java
sdkInstance.reportAdFirstQuartile();
sdkInstance.reportAdMidpoint();
sdkInstance.reportAdThirdQuartile();
```

#### Step 8.4 Report Ad Request/Response (Optional)

```java
sdkInstance.reportAdRequest(map) // map -> Map<String, String>
sdkInstance.reportAdResponse(map)
```

#### AdInfo Object

<table data-header-hidden><thead><tr><th width="238.8984375">Field</th><th>Description</th></tr></thead><tbody><tr><td>adInfo.adTitle</td><td>The title or name of the ad, usually provided in the VAST metadata or by the ad server.</td></tr><tr><td>adInfo.adId</td><td>A unique identifier for the ad creative, often defined by the ad server or DSP.</td></tr><tr><td>adInfo.adCreativeId</td><td>The creative ID associated with the specific ad asset (video, image, etc.). Helps in tracking and reporting creative-level performance.</td></tr><tr><td>adInfo.adCreativeType</td><td>The format or type of the ad creative. For example, video/mp4, image/jpeg, etc., or linear, non-linear.</td></tr><tr><td>adInfo.adClient</td><td>The SDK or client library responsible for requesting and playing the ad. Example: Google IMA, Freewheel, SpotX.</td></tr><tr><td>adInfo.adPosition</td><td>The timing of the ad in relation to the main content: "pre" (before), "mid" (during), or "post" (after).</td></tr><tr><td>adInfo.adServer</td><td>The ad server or source that delivered the ad. Example: Google Ad Manager, Freewheel, etc.</td></tr><tr><td>adInfo.adResolution</td><td>The resolution of the ad video (e.g., 1920x1080), useful for reporting and quality monitoring.</td></tr><tr><td>adInfo.adUrl</td><td>The URL from which the ad video is fetched. Typically a media file or stream URL.</td></tr><tr><td>adInfo.adDuration</td><td>The total duration of the ad, in milliseconds. Example: 30000 = 30 seconds.</td></tr><tr><td>adInfo.adPodIndex</td><td>The index of the ad pod within the stream. Ad pods are groups of ads played together (like a commercial break).</td></tr><tr><td>adInfo.adPositionInPod</td><td>The position of the ad within its pod (e.g., 1st ad, 2nd ad in the group).</td></tr><tr><td>adInfo.adPodLendth</td><td>The total number of ads in the current pod. Useful for showing “Ad 2 of 5” type of UI.</td></tr><tr><td>adInfo.isBumper</td><td>A boolean (true/false) indicating whether the ad is a bumper ad (short ad, usually &#x3C;6s, played at the start or end of ad breaks).</td></tr><tr><td>adInfo.adUniversalId</td><td>A String value to report Ad Universal ID.</td></tr></tbody></table>


---

# 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/custom-multi-player-sdk-integration-document.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.
