# MediaMelon JS Custom SDK Integration Document

**Step 1:** [Add MediaMelon Player SDK](#step-1-add-mediamelon-smartstreaming-sdk-hardbreak)

**Step 2:** [Register and Initialize MediaMelon Player SDK](#step-2-register-and-initialize-mediamelon-sdk)

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

**Step 4:** [Stream and Network Information](#step-4-stream-and-network-information)

**Step 5:** [Chunk/Segment Information](#step-5-chunk-segment-information)

**Step 6:** [Player Events](#step-6-player-events)

**Step 7:** [Fallback & Request Status](#step-7-fallback-and-request-status)

**Step 8:** [Ad Data & Ad Events](#step-8-a-d-data-and-ad-events)

**Step 9:** [Custom Events](#step-9-custom-events)

[Release Notes](#release-notes)

### **Step 1: Add** MediaMelon Player SDK <a href="#step-1-add-mediamelon-smartstreaming-sdk-hardbreak" id="step-1-add-mediamelon-smartstreaming-sdk-hardbreak"></a>

* **NPM (1.4.5):**

```bash
npm i mediamelon-js-custom-sdk
```

```javascript
import { mmJSCustomAdapter, MMPlayerState, RenditionInfo, RequestStatus} from 'mediamelon-js-custom-sdk'
```

### **Step 2: Register and Initialize** MediaMelon Player SDK <a href="#step-2-register-and-initialize-mediamelon-sdk" id="step-2-register-and-initialize-mediamelon-sdk"></a>

{% 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: Instantiate and Register SDK:

```javascript
var mmJSPlugin = new mmJSCustomAdapter();
mmJSPlugin.registerMMSmartStreaming("PLAYER_NAME", 
    "CUSTOMER_ID", 
    "SUBSCRIBER_ID", 
    "DOMAIN_NAME", 
    "SUBSCRIBER_TYPE", 
    "SUBSCRIBER_TAG", 
    hashSubscriberId      //Boolean Value
);
```

{% hint style="info" %}
`hashSubscriberId`: Set it to `true` to hash the subscriber ID, and to `false` to process the subscriber ID without hashing.
{% endhint %}

#### Step 2.2: Report Player Information:

```javascript
mmJSPlugin.reportPlayerInfo("PLAYER_BRAND", "PLAYER_MODEL", "PLAYER_VERSION");            
mmJSPlugin.reportBasePlayerInfo("BASE_PLAYER_NAME", "BASE_PLAYER_VERSION");
```

#### Step 2.3: Report Application Information:

```javascript
mmJSPlugin.reportAppInfo("APPLICATION_NAME","APPLICATION_VERSION");
mmJSPlugin.reportAppSessionId("APP_SESSION_ID");
```

#### Step 2.4: Report Device Information:

```javascript
var deviceInfo = {
    "deviceName": "DEVICE_NAME",
    "deviceBrand": "DEVICE_BRAND",      // Device Brand or Manufacturer
    "deviceModel": "DEVICE_MODEL",
    "deviceId": "DEVICE_ID",
    "deviceOS": "DEVICE_OS",
    "deviceOSVersion": "DEVICE_OS_VERSION",            
    "screenWidth": screen_width,        //Integer Value
    "screenHeight": screen_height       //Integer Value
};
mmJSPlugin.reportDeviceInfo(deviceInfo);
```

#### Step 2.5: Report Experiment Name & Sub Property ID:

```javascript
mmJSPlugin.reportExperimentName("EXPERIMENT_NAME");
mmJSPlugin.reportSubPropertyId("SUB_PROPERTY_ID");
```

#### Step 2.6: Initialize Session with Content Metadata:

```javascript
var contentMetaData = {
    "assetName": "ASSET_NAME",
    "assetId": "ASSET_ID",
    "videoId": "VIDEO_ID",
    "contentType": "CONTENT_TYPE",
    "genre": "GENRE",
    "drmProtection": "DRM_PROTECTION",
    "episodeNumber": "EPISODE_NUMBER",
    "season": "SEASON",
    "seriesTitle": "SERIES_TITLE",
    "videoType": "VIDEO_TYPE"
};

mmJSPlugin.initializeSession(contentMetaData, "STREAM_URL");
mmJSPlugin.reportPreload(<boolean>);
mmJSPlugin.reportUserInitiatedPlayback();
```

{% hint style="info" %}
**Preload:** 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 %}

#### Step 2.7: Report View Session ID:

```javascript
mmJSPlugin.reportViewSessionId("VIEW_SESSION_ID");
```

### Step 3: 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.

```javascript
mmJSPlugin.reportCustomMetadata("custom_1", "value1");
mmJSPlugin.reportCustomMetadata("custom_2", "value2");
```

### Step 4: Stream and Network Information

#### Step 4.1: Report Stream Information:

```javascript
mmJSPlugin.reportStreamInfo("STREAM_FORMAT", "MEDIA_TYPE", "SOURCE_TYPE");
```

#### Step 4.2: Update Stream URL:

```javascript
mmJSPlugin.updateStreamURL("STREAM_URL");
```

#### Step 4.3: Report Presentation Info:

```javascript
mmJSPlugin.reportPresentationInfo(<is_live>, <video_duration>);
```

{% hint style="info" %}

* `is_live`: Set to `true` for live video stream and to `false` for the VOD stream.
* `video_duration`: Integer value in milliseconds.
  {% endhint %}

#### Step 4.4: Report Track Information

Call this API with initial values and every time there is a change in the track info. Call this API when the user enables/disables subtitles or when the user changes the audio track.

```javascript
mmJSPlugin.reportTrackinfo(<is_subtitle_active>, "SUBTITLE_TRACK", "AUDIO_TRACK", <is_vds_active>);
```

{% hint style="info" %}
`is_subtitle_active`: Set it to `true` if the subtitles are active; otherwise, set it to `false`.

`is_vds_active`: Set it to `true` if the type of audio is Virtual Dialogue Sound, otherwise, set it to `false`.
{% endhint %}

#### Step 4.5: Report Rendition:

At the start of the video, create a ReditionInfo object, assign initial rendition values to the object, and report it to the SDK. For any subsequent rendition change, update only the fields that changed in the same RenditionInfo object. Leave the unchanged fields as-is, and report the updated object to the SDK.

```javascript
var renditionInfo = new RenditionInfo();
rendition.bitrate = <birate>;            //Integr Value in bps
rendition.width = <width>;               //Integr Value
rendition.height = <height>;             //Integer Value
rendition.frameRate = <frame_rate>;      //Integr Value in fps
rendition.aCodec = "AUDIO_CODEC";
rendition.vCodec = "VIDEO_CODEC";

mmJSPlugin.reportRendition(renditionInfo);
```

#### Step 4.6: Update DRM Type:

```javascript
mmJSPlugin.updateDRMType("NEW_DRM_TYPE");
```

#### Step 4.7: Report Network Information:

```javascript
var networkInfo = {
    "cdn": "CDN",
    "asn": asn,                     //Integer Value
    "hostName": "SOURCE_HOST_NAME",
    "networkType": "NETWORK_TYPE",  // Network Connection Type
    "networkOperator": "NETWORK_OPERATOR"
}
mmJSPlugin.reportNetworkInfo(networkInfo);
```

{% 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 4.8: Report CDN Information:

```javascript
mmJSPlugin.reportCDN("CDN");
```

#### Step 4.9: Report Encoding Service:

```javascript
mmJSPlugin.reportEncodingService("ENCODING_SERVICE");
```

### Step 5: Chunk/Segment Information

#### Step 5.1: Report Download Rate:

Report the latest chunk download rate using this method. Trigger this method for every chunk.

```javascript
mmJSPlugin.reportDownloadRate(downloadRate);    //Integer Value in bps (bits per second
```

### Step 6: Player Events

#### Step 6.1: Report Player State:

```javascript
mmJSPlugin.reportPlayerState(MMPlayerState.PLAYING);

Enum: MMPlayerState
- PLAYING
- PAUSED
- STOPPED
```

#### Step 6.2: Report Buffering:

```javascript
mmJSPlugin.reportBufferingStarted();
mmJSPlugin.reportBufferingCompleted();
```

#### Step 6.3: Report Seek:

```javascript
mmJSPlugin.reportPlayerSeekStarted(); 
mmJSPlugin.reportPlayerSeekCompleted(seekEndPositionInMS); //Integer Value in Milli Seconds
```

#### Step 6.4: Report Error:

```javascript
mmJSPlugin.reportError("ERROR_CODE", "ERROR_MESSAGE", "ERROR_DETAILS");
```

#### Step 6.5: Report Warning:

```javascript
mmJSPlugin.reportWarning("WARNING_CODE", "WARNING_MESSAGE", "WARNING_DETAILS");
```

#### Step 6.6: Report Playback Position:

Call this every 0.5 sec or 1 sec to report the playback position from the player

```javascript
mmJSPlugin.reportPlaybackPosition(playback_position); //Integer Value in Milli Seconds
```

#### Step 6.7: Report Player Resolution:

```javascript
mmJSPlugin.reportPlayerResolution(width, height);
```

### Step 7: Fallback & Request Status

#### Step 7.1: Report Fallback Event:

```javascript
mmJSPlugin.reportFallbackEvent("FALLBACK_MANIFEST_URL", "DESCRIPTION");
```

#### Step 7.2: Report Request Status:

```javascript
var requestInfo = {
    id: "ID",
    error: "ERROR",
    text: "TEXT",
    hostname: "HOSTNAME",
    url: "URL",
    ...
}

mmJSPlugin.reportRequestStatus(RequestStatus.FAILED, "REQUEST_TYPE", requestInfo);

Enum: RequestStatus
- FAILED
- CANCELLED
```

### Step 8: Ad Data & Ad Events

#### Step 8.1: Report Ad Break Start & End:

```javascript
mmJSPlugin.reportAdBreakStart();
mmJSPlugin.reportAdBreakEnd();
```

#### Step 8.2: Report Ad Data, Ad Start & End:

```javascript
var adInfo = {
    "adTitle": "AD_TITLE",
    "adId": "AD_ID",
    "adCreativeId": "AD_CREATIVE_ID",
    "adCreativeType": "AD_CREATIVE_TYPE",
    "adClient": "AD_CLIENT",
    "adPosition": "AD_POSITION",               //pre, mid, post
    "adServer": "AD_SERVER",
    "adResolution": "AD_RESOLUTION",
    "adUrl": "AD_URL",
    "adDuration": ad_duration,              //Double Value
    "adPodIndex": pod_index,                //Integer Value
    "adPositionInPod": ad_position_in_pod,  //Integer Value
    "isBumper": is_bumper                   //Boolean Value
}

mmJSPlugin.reportAdStart(adInfo);
mmJSPlugin.reportAdEnd();
```

<details>

<summary>AdInfo Object description</summary>

<table data-header-hidden><thead><tr><th width="198.04296875">Field</th><th width="116.59375">Data Type</th><th>Description</th></tr></thead><tbody><tr><td>adInfo.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>adInfo.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>adInfo.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>adInfo.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>adInfo.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>adInfo.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>adInfo.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>adInfo.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>adInfo.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>adInfo.adDuration</td><td>Integer</td><td>The total duration of the ad, in milliseconds. Example: 30000 = 30 seconds.</td></tr><tr><td>adInfo.adPodIndex</td><td>Integer</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>Integer</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>Integer</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>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></tbody></table>

</details>

#### Step 8.3: 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.

```javascript
mmJSPlugin.reportAdBufferingStrated();
mmJSPlugin.reportAdBufferingCompleted();
```

### Step 9: 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
mmJSPlugin.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.4.5[^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.4.4[^2]

* Added an additional API to report CDN alone.
* Added `CDN_CHANGE` event.
* Added Seek Duration calculation internally.

#### v1.4.3[^3]

* Improved bitrate reporting for weighted average bitrate calculation
* Updated internal SDK version format

#### v1.4.2[^4]

* Preload field addition
* App Session ID field addition
* Fix to consider Exit in Buffering
* Added rendition metrics for upscale and downscale percentage calculations

</details>

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

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

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

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

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

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

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