# MediaMelon Android Custom SDK Integration Document

**Step 1:** [Set Up Build Environment](#step-1-set-up-the-build-environment)

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

**Step 3:** [Report Custom Metadata](#step-3-report-custom-metadata)

**Step 4:** [Report Playback Events](#step-4-report-playback-events)

**Step 5:** [Report Stream and Network Related Information](#step-5-report-stream-and-network-related-information)

**Step 6:** [Report Request Status and Fallback Events](#step-3-initialize-session-and-report-user-intent-to-playback-8)

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

**Step 8:** [Report Custom Events](#step-8-report-custom-events)

[Release Notes](#release-notes)

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

#### **Step 1.1: Add Gradle Dependency:**

1. Add MediaMelon SDK gradle dependency to `app/build.gradle`

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

#### Step 1.2 Provide Permissions

Add network permissions to `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

```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.core.qubit.RequestStatus;
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 %}

#### Step 2.1:  Set Context

Set the application context

```java
MMSmartStreamingMedia3.setContext(applicationContext)
```

#### Step 2.2: Register SDK

{% 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 %}

```java
MMSmartStreamingMedia3.registerMMSmartStreaming("PLAYER_NAME", "CUSTOMER_ID", "SUBSCRIBER_ID", "DOMAIN_NAME", "SUBSCRIBER_TYPE", "SUBSCRIBER_TAG", true);
```

#### Step 2.3: Report Player Information

```java
MMSmartStreamingMedia3.reportPlayerInfo("PLAYER_BRAND", "PLAYER_MODEL", "PLAYER_VERSION");
```

#### Step 2.4: Report Base Player Information

```java
MMSmartStreamingMedia3.reportBasePlayerInfo("BASE_PLAYER_NAME", "BASE_PLAYER_VERSION");
```

#### Step 2.5: Report Application Information

```java
MMSmartStreamingMedia3.reportAppInfo("APP_NAME","APP_VERSION");
```

#### Step 2.6: Report Device Information

```java
MMSmartStreamingMedia3.reportDeviceInfo(deviceInfo);
```

<details>

<summary>Device Info Object Description</summary>

<table><thead><tr><th width="161.60546875">Parameter</th><th width="116.296875">Data Type</th><th>Description</th></tr></thead><tbody><tr><td>brand</td><td>String</td><td>Company or Brand to which the device belongs. Ex:  Samsung</td></tr><tr><td>deviceModel</td><td>String</td><td>Model Identifier of the device. Ex: SM-1921</td></tr><tr><td>deviceType</td><td>String</td><td>The type of device. Ex: Smart TV</td></tr><tr><td>os</td><td>String</td><td>Operatin system name. Ex: Android, iOS, etc</td></tr><tr><td>osVersion</td><td>String</td><td>Operating system verion. Ex: 14, 18.2.0</td></tr><tr><td>telecomOperator</td><td>String</td><td>Telecom operator currently used.</td></tr><tr><td>screenWidth</td><td>String</td><td>Screen width of the device</td></tr><tr><td>screenHeight</td><td>String</td><td>Screen height of the device</td></tr></tbody></table>

</details>

#### Step 2.7: Initialize session with Content Metadata

```java
ContentMetadata contentMetadata  = new ContentMetadata();
    contentMetadata.assetName="ASSET_NAME";
    contentMetadata.assetId="ASSET_ID";
    contentMetadata.videoId="VIDEO_ID";
    contentMetadata.seriesTitle="SERIES_TITLE";
    contentMetadata.season="SEASON";
    contentMetadata.genre="GENRE";
    contentMetadata.episodeNumber="EPISODE_NUMBER";
    contentMetadata.drmProtection="DRM_PROTECTION";
    contentMetadata.contentType="CONTENT_TYPE";
    
    MMSmartStreamingMedia3.initializeSession(cm);
    MMSmartStreamingMedia3.reportUserInitiatedPlayback();
```

<details>

<summary>Content Metadata Object Description</summary>

<table><thead><tr><th width="148.34765625">Parameter</th><th width="117.17578125">Data Type</th><th>Description</th></tr></thead><tbody><tr><td>assetId</td><td>String</td><td>Unique identifier for the video asset.</td></tr><tr><td>assetName</td><td>String</td><td>Human-readable name or title of the video asset.</td></tr><tr><td>videoId</td><td>String</td><td>Unique identifier for the video content. It can be the same as <strong>Asset ID</strong> or a different logical ID used in your system.</td></tr><tr><td>seriesTitle</td><td>String</td><td>Title of the series to which the episode belongs.</td></tr><tr><td>season</td><td>String</td><td>Name or number of the season (e.g., "Season 1", "S2").</td></tr><tr><td>genre</td><td>String</td><td>Genre of the content, such as "Drama", "Comedy", "Documentary", etc.</td></tr><tr><td>episodeNumber</td><td>String</td><td>Episode number within a season. Useful for TV series or episodic content.</td></tr><tr><td>contentType</td><td>String</td><td>The category or type of content, e.g., "Movie", "Episode", "Clip", "LiveStream".</td></tr><tr><td>drmProtection</td><td>String</td><td>DRM technology used (e.g., “Widevine”, “FairPlay”, “PlayReady”). Use “Unknown” if the content is protected, but the DRM type is unknown. Leave blank for clear (non-DRM) content.</td></tr></tbody></table>

</details>

#### Step 2.8: Report Experiment Name

```java
MMSmartStreamingMedia3.reportExperimentName("EXPERIMENT_NAME");
```

#### Step 2.9: 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>

{% hint style="info" %}
Report the View Session Id attribute after `initializeSession` and before `reportUserInitiatedPlayback`.&#x20;
{% endhint %}

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

#### Step 2.10: 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>

{% hint style="info" %}
Report the Sub Property ID attribute after `initializeSession` and before `reportUserInitiatedPlayback`.&#x20;
{% endhint %}

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

#### Step 2.11: Report Preload

{% hint style="info" %}
Report the preload attribute after `initializeSession` and before `reportUserInitiatedPlayback`. The preload value is reset inside `initializeSession`, so reporting it before this method will be ignored. If you report it after `reportUserInitiatedPlayback`, the first event will not contain the preload field.
{% endhint %}

```java
MMSmartStreamingMedia3.reportPreload(preload);// preload -> boolean
```

#### Step 2.12: Report App Session ID

Report Application Session ID

```java
MMSmartStreamingMedia3.reportAppSessionId("APP_SESSION_ID");
```

#### Step 2.13: Report Device ID

```java
MMSmartStreamingMedia3.reportDeviceId("DEVICE_ID");
```

#### Step 2.14 Report Device Marketing Name

```java
MMSmartStreamingMedia3.reportDeviceMarketingName("DEVICE_MARKETING_NAME");
```

### Step 3: Report Custom Metadata

Check the custom tags configuration in your [dashboard](https://smartsight3.mediamelon.com/settings) and report accordingly. If the custom tags are not configured, please configure and use them accordingly.

```java
MMSmartStreamingMedia3.reportCustomMetadata("custom_1","VALUE_1");
MMSmartStreamingMedia3.reportCustomMetadata("custom_2","VALUE_2");
```

### Step 4: Report Playback Events

#### Step 4.1: Report Player State <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 the player state using the following function.

```java
MMSmartStreamingMedia3.reportPlayerState(MMPlayerState.PLAYING);
```

<details>

<summary>MMPlayerState</summary>

<table><thead><tr><th width="210.51953125">MMPlayerState</th><th>Description</th></tr></thead><tbody><tr><td>PLAYING</td><td>Report when video starts playing froma paused state or on first frame rendered</td></tr><tr><td>PAUSED</td><td>Report when video paused</td></tr><tr><td>STOPPED</td><td>Report when user exits the video playback</td></tr></tbody></table>

</details>

#### Step 4.2: Report Buffering Events

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

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

#### Step 4.3: Report Seek Events

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

#### Step 4.4: Report Errors

```java
MMSmartStreamingMedia3.reportError(ERROR_CODE_INT, "ERROR_MESSAGE", "ERROR_DETAILS");
```

#### Step 4.5: Report Warnings

```java
MMSmartStreamingMedia3.reportWarning(WARNING_INT, "WARNING_MESSAGE", "WARNING_DETAILS");
```

#### Step 4.6: Report Playback Position

```java
MMSmartStreamingMedia3.reportPlaybackPosition(playbackPositionInMs)
```

### Step 5: Report Stream and Network Related Information

#### 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
MMSmartStreamingMedia3.setStreamURL("STREAM_URL");
```

#### Step 5.2: 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
MMSmartStreamingMedia3.reportVideoDuration(inMilliSeconds);
```

#### Step 5.3: Report Stream Information

Report Information related to the stream

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

#### Step 5.4:  Report Network 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
MMSmartStreamingMedia3.reportNetworkInfo("CDN", "ASN", "HOST_NAME", "NETWORK_TYPE", "NETWORK_OPERATOR"); 
```

{% hint style="info" %}
Use the **`reportNetworkInfo`** API to report the CDN along with other network information.\
If additional network information is not available, use **`reportCDN`** instead.
{% endhint %}

#### Step 5.5: Report CDN

```java
MMSmartStreamingMedia3.reportCDN("CDN");
```

#### Step 5.6:  Report Track 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
MMSmartStreamingMedia3.reportTrackInfo("AUDIO_TRACK", "SUBTITLE_TRACK", isSubtitleActive, isVDSActive, "VIDEO_TRACK");
```

#### Step 5.7: Report Rendition

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

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

<details>

<summary>Rendition Object</summary>

<table><thead><tr><th width="144.796875">Parameter</th><th width="168.09765625">Data Type</th><th>Description</th></tr></thead><tbody><tr><td>bitrate</td><td>int</td><td>Current bitrate at which the video is playing</td></tr><tr><td>width</td><td>int</td><td>current width of the video</td></tr><tr><td>height</td><td>int</td><td>current height of the video</td></tr><tr><td>frameRate</td><td>double</td><td>current frame rate of the video</td></tr><tr><td>aCodec</td><td>String</td><td>current Audio Codec of video</td></tr><tr><td>vCodec</td><td>String</td><td>current Video Codec of video</td></tr></tbody></table>

</details>

#### Step 5.7: Update DRM Type

```java
MMSmartStreamingMedia3.updateDRMType("DRM_TYPE");
```

#### Step 5.8: Report Player Download Rate

Report Player download rate in bps

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

#### Step 5.9: Report Frame Loss

```java
MMSmartStreamingMedia3.reportFrameloss(frameloss) // frameloss -> Int
```

#### Step 5.10: Report Encoding Service

```java
MMSmartStreamingMedia3.reportEncodingService("ENCODING_SERVICE");
```

### Step 6: Report Request Status and Fallback 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 6.1: Report Request Status

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

<details>

<summary>RequestStatus (Enum)</summary>

| Request Status | Description                   |
| -------------- | ----------------------------- |
| FAILED         | Report on a failed request    |
| CANCELLED      | Report on a cancelled request |

</details>

#### Step 6.2: Report Fallback event

Report fallback events in case a fallback strategy is applied.

```java
MMSmartStreamingMedia3.reportFallbackEvent("STREAM_URL", "DESCRIPTION");
```

#### Step 6.3: Update Content Metadata

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

#### Step 6.4: Update Subscriber Info

```java
MMSmartStreamingMedia3.updateSubscriberInfo("SUB_ID_NEW", "SUB_TYPE_NEW", "SUB_TAG_NEW");
```

### Step 7: Report Ad Events

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

```java
MMSmartStreamingMedia3.reportAdBreakStarted();
MMSmartStreamingMedia3.reportAdBreakEnded();
MMSmartStreamingMedia3.reportAdStarted(adInfoObject);
MMSmartStreamingMedia3.reportAdEnd();
```

<details>

<summary>AdInfo Object</summary>

<table><thead><tr><th width="160.1796875">Parameter</th><th width="117.765625">Data Type</th><th>Description</th></tr></thead><tbody><tr><td>adClient</td><td>String</td><td>The SDK or client library responsible for requesting and playing the ad. Example: Google IMA, Freewheel, SpotX.</td></tr><tr><td>adId</td><td>String</td><td>A unique identifier for the ad creative, often defined by the ad server or DSP.</td></tr><tr><td>adDuration</td><td>Double</td><td>The total duration of the ad, in milliseconds. Example: 30000 = 30 seconds.</td></tr><tr><td>adPosition</td><td>String</td><td>The timing of the ad in relation to the main content: "pre" (before), "mid" (during), or "post" (after).</td></tr><tr><td>adCreativeType</td><td>String</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>adServer</td><td>String</td><td>The ad server or source that delivered the ad. Example: Google Ad Manager, Freewheel, etc.</td></tr><tr><td>adResolution</td><td>String</td><td>The resolution of the ad video (e.g., 1920x1080), useful for reporting and quality monitoring.</td></tr><tr><td>adPodIndex</td><td>int</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>adPositionInPod</td><td>int</td><td>The position of the ad within its pod (e.g., 1st ad, 2nd ad in the group).</td></tr><tr><td>isBumper</td><td>Boolean</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>adCreativeId</td><td>String</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>adUrl</td><td>String</td><td>The URL from which the ad video is fetched. Typically a media file or stream URL.</td></tr><tr><td>adTitle</td><td>String</td><td>The title or name of the ad, usually provided in the VAST metadata or by the ad server.</td></tr><tr><td>adBitRate</td><td>int</td><td>Bitrate at which the ad is playing</td></tr><tr><td>adTimeStamp</td><td>Long</td><td>Timestamp of ad as received</td></tr></tbody></table>

</details>

#### Step 7.2: Report Ad Buffering:

Use Ad Buffering APIs to report any buffering that occurs during ad playback. For any buffering event, either content buffering or ad buffering should be reported, but not both.

```java
MMSmartStreamingMedia3.reportAdBufferingStarted();
MMSmartStreamingMedia3.reportAdBufferingCompleted();
```

### Step 8: Report Custom Events

The Custom Events API can be used to report events that are not covered by the default MediaMelon-supported events. Custom events must be reported within the SDK activity lifecycle. Events reported before SDK initialization or after session end will be ignored. Please refer to the guidelines and constraints below.

```javascript
MMSmartStreamingMedia3.reportCustomEvent("EVENT_NAME", "EVENT_VALUE");
```

{% hint style="info" %}
**Guidelines & Constraints**

* **Event Name**
  * Maximum length: 35 characters
  * Allowed characters: Alphanumeric and underscore (\_) only
  * Special characters are not supported
  * Recommended format: UPPERCASE with underscores (e.g., DRM\_CHANGE)
* **Event Limits**
  * A maximum of 35 custom events per session is allowed.

Custom events that violate these constraints (invalid event name or exceeding the per-session limit) will be dropped. Event values exceeding 1000 characters will be truncated to 1000 characters.
{% endhint %}

### Release Notes

<details>

<summary>Current Release</summary>

#### v1.2.11[^1]

* Added support for reporting a new field encoding service via `reportEncodingService`.
* Introduced custom event reporting through `reportCustomEvent`.
* Added support for ad buffering events:
  * `reportAdBufferingStarted`
  * `reportAdBufferingCompleted`
* Improved event handling to restrict event reporting after playback has ended.

</details>

***

<details>

<summary>Previous Releases</summary>

#### v1.2.10

* **Skip Release**

#### v1.2.[^2]9

* Added an additional API to report CDN alone.
* Added `CDN_CHANGE` event.
* Added Internal functionality to report seek duration.

#### [**v1.2.8**](#user-content-fn-3)[^3]

* Added Api to report frame loss
* Added Api to report Device ID
* Added Api to report Device Marketing Name
* Internal Improvements for Device Info and Network Info
* Improved bitrate reporting for weighted average bitrate calculation
* Updated internal SDK version format

#### [v**1.2.7**](#user-content-fn-4)[^4]

* Preload field addition
* App Session Id field addition
* Fix to consider Exit in Buffering
* New metrics to enable upscale and downscale %s for bitrate and resolution
* Improved failed and offline payloads queueing

#### [v**1.2.6**](#user-content-fn-5)[^5]

* CPU optimisation
* fix: ENDED event in case of EBVS

</details>

[^1]: **Release Date:** Mar 27, 2026

    **Performance Report:** [here](https://docs.mediamelon.com/mediamelon-sdk-performance-metrics/android/android-custom-sdk-performance-metrics)

[^2]: **Release Date:** Feb 6, 2026

    **Performance Report:** [here](https://docs.mediamelon.com/mediamelon-sdk-performance-metrics/android/android-custom-sdk-performance-metrics)

[^3]: **Release Date: Dec 20, 2025**

    **Performance Report:** [**here**](https://docs.mediamelon.com/mediamelon-sdk-performance-metrics/android/android-custom-sdk-performance-metrics)

[^4]: **Release Date:** Dec 3, 2025

[^5]: **Release Date:** Oct 31, 2025


---

# 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/mediamelon-android-custom-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.
