# MediaMelon C++ Custom SDK Integration Document

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

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

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

**Step 4:** [Network and Stream Information](#step-4-network-and-stream-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 SDK <a href="#step-1-add-mediamelon-smartstreaming-sdk-hardbreak" id="step-1-add-mediamelon-smartstreaming-sdk-hardbreak"></a>

Add the provided static (.a) or shared (.so) library to the project.&#x20;

### **Step 2: Register and Initialize** MediaMelon 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 Set SDK Registration Information:

```cpp
#include "cpp_mmsmartstreaming.h"

using namespace MMSmartStreamingSDK;

MMSmartStreaming &mmSmartStreaming = MMSmartStreaming::getInstance();

MMSmartStreaming::registerMMSmartStreaming("PLAYER_NAME", "CUSTOMER_ID", "SUBSCRIBER_CPP", "DOMAIN_NAME", "SUBSCRIBER_TYPE", "SUBSCRIBER_TAG", hashSubscriberID);
MMSmartStreaming::reportPlayerInfo("PLAYER_BRAND", "PLAYER_MODEL", "PLAYER_VERSION");
MMSmartStreaming::reportBasePlayerInfo("BASE_PLAYER_NAME", "BASE_PLAYER_VERSION");
```

{% 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.3: Report Application Information:

```cpp
MMSmartStreaming::reportAppData("APP_NAME", "APP_VERSION");
```

#### Step 2.4: Report Application Session ID:

```cpp
MMSmartStreaming::reportAppSessionID("APP_SESSION_ID");
```

#### Step 2.5: Set Device Information:

```cpp
MMDeviceInformation deviceInfo;
deviceInfo.setDeviceType("DEVICE_TYPE");
deviceInfo.setDeviceBrand("DEVICE_BRAND");      //Device Brand or Manufacturer
deviceInfo.setDeviceModel("DEVICE_MODEL");
deviceInfo.setDeviceOSInfo("DEVICE_OS", "DEVICE_OS_VERSION");  
deviceInfo.setScreenResolution(<screen_width>, <screen_height>);
  
MMSmartStreaming::reportDeviceInfo(deviceInfo);
```

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

```cpp
MMSmartStreaming::reportExperimentName("EXPERIMENT_NAME");
MMSmartStreaming::reportSubPropertyID("SUB_PROPERTY_ID");
```

#### Step 2.7: Set Content Metadata:

```cpp
MMContentMetadata contentMetadata;
contentMetadata.setAssetInfo("ASSET_ID", "ASSET_NAME", "VIDEO_ID");
contentMetadata.setContentType("CONTENT_TYPE");
contentMetadata.setDrmProtection("DRM_PROTECTION");
contentMetadata.setEpisodeNumber("EPISODE_NUMBER");
contentMetadata.setGenre("GENRE");
contentMetadata.setSeason("SEASON");
contentMetadata.setSeriesTitle("SERIES_TITLE");

mmSmartStreaming.reportViewSessionID("VIEW_SESSIOND_ID");
```

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

```cpp
mmSmartStreaming.initializeSession("STREAM_URL", contentMetadata)
mmSmartStreaming.reportPreload(<bool>);
mmSmartStreaming.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 3: Additional 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.

```cpp
mmSmartStreaming.reportCustomMetadata("KEY1", "VALUE1");
mmSmartStreaming.reportCustomMetadata("KEY2", "VALUE2");
```

### Step 4: Network and Stream Information

#### Step 4.1: Report Network Information:

```cpp
mmSmartStreaming.reportNetworkInfo("CDN",
                                   <asn>,                 //Integer Value
                                   "SOURCE_HOST_NAME", 
                                   "NETWORK_TYPE",        // Network Connection 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 4.2: Report CDN Information:

```cpp
mmSmartStreaming.reportCDN("CDN");
```

#### Step 4.2: Report Stream Information:

```cpp
mmSmartStreaming.reportStreamInfo("STREAM_FORMAT", "MEDIA_TYPE", "SORUCE_TYPE");
```

#### Step 4.3: Update Stream URL:

```cpp
mmSmartStreaming.updateStreamURL("NEW_STREAM_URL");
```

#### Step 4.4: Report Video Presentation Information:

```cpp
MMPresentationInfo presentationInfo;
presentationInfo.isLive = false;
presentationInfo.duration = 100*1000; 

mmSmartStreaming.setPresentationInformation(presentationInfo);
```

{% hint style="info" %}

* `isLive`: Set to `true` for live video stream and to `false` for the VOD stream.
* `duration`: Video duration in milliseconds.
  {% endhint %}

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

```cpp
mmSmartStreaming.reportMediaTrackInfo(<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.6: 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.

```cpp
MMRenditionInfo renditionInfo;
renditionInfo.bitrate = <bitrate>            //Integr Value in bps
renditionInfo.width = <width>                //Integer Value
renditionInfo.height = <height>              //Integer Value
renditionInfo.frameRate = <frame_rate>       //Double Value in fps
renditionInfo.setAudioCodec("ACODEC");
renditionInfo.setVideoCodec("VCODEC");

mmSmartStreaming.reportRenditionInformation(renditionInfo);
```

#### Step 4.7: Update DRM Type:

```cpp
mmSmartStreaming.updateDRMType("NEW_DRM_TYPE");
```

#### Step 4.8: Report Encoding Service:

```cpp
mmSmartStreaming.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.

```cpp
mmSmartStreaming.reportDownloadRate(<downloadRate>)  //Integer Value in bps
```

### Step 6: Player Events

#### Step 6.1: Report Player State:

```cpp
mmSmartStreaming.reportPlayerState(MMPlayerState::PLAYING);

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

#### Step 6.2: Report Buffering:

```cpp
mmSmartStreaming.reportBufferingStarted();
mmSmartStreaming.reportBufferingCompleted();
```

#### Step 6.3: Report Seek:

```cpp
mmSmartStreaming.reportPlayerSeekStarted();
mmSmartStreaming.reportPlayerSeekCompleted(<seek_end_position>); //Integer Value in Milli Seconds
```

#### Step 6.4: Report Error:

```cpp
mmSmartStreaming.reportError("ERROR_CODE", "ERROR_MESSAGE", "ERROR_DETAILS");
```

#### Step 6.5: Report Warning:

```cpp
mmSmartStreaming.reportWarning("WARNING_CODE", "WARNING_MESSAGE", "WARNING_DETAILS");
```

#### Step 6.5: Report Playback Position:

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

```cpp
mmSmartStreaming.reportPlaybackPosition(<playback_position>) //Integer Value in Milli Seconds
```

#### Step 6.6: Report Player Resolution:

```cpp
mmSmartStreaming.reportPlayerResolution(<player_width>, <player_height>);
```

### Step 7: Fallback & Request Status

#### Step 7.1: Report Fallback Event:

```cpp
mmSmartStreaming.reportFallbackEvent("NEW_FALLBACK_STREAM_URL", "FALLBACK_DESCRIPTION");
```

#### Step 7.2: Report Request Status:

Report `FAILED` or `CANCELLED` requests for the following request types:

* PIR
* MANIFEST
* AUDIO\_CHUNK
* VIDEO\_CHUNK
* DRM
* SUBTITLE

```cpp
map<string, string> requestInfoMap;
requestInfoMap["ID"] = "ID";
requestInfoMap["URL"] = "URL";
requestInfoMap["ERROR"] = "ERROR";
requestInfoMap["DESC"] = "DESC";

mmSmartStreaming.reportRequestStatus(RequestStatus::CANCELLED, "REQUEST_TYPE", requestInfoMap);

Enum: RequestStatus
- FAILED
- CANCELLED
```

### Step 8: Ad Data & Ad Events

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

```cpp
mmSmartStreaming.reportAdBreakStart();
mmSmartStreaming.reportAdBreakEnd();
```

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

```cpp
MMAdInfo adInfo;
adInfo.adTitle = "AD_TITLE";
adInfo.adId = "AD_ID";
adInfo.adCreativeId = "AD_CREATIVE_ID";
adInfo.adCreativeType = "AD_CREATIVE_TYPE";
adInfo.adClient = "AD_CLIENT"
adInfo.adPosition = "AD_POSITION";                    //pre, mid, post
adInfo.adServer = "AD_SERVER";
adInfo.adResolution = "AD_RESOLUTION";
adInfo.adUrl = "AD_URL";
adInfo.adDuration = <ad_duration>;                    //Integer Value in Milli Seconds
adInfo.adPodIndex = <pod_index>;                      //Integer Value
adInfo.adPositionInPod = <ad_position_in_pod>;        //Integer Value
adInfo.adPodLendth = <pod_length>;                    //Integer Value
adInfo.isBumper = <is_bumper>;                        //Boolean Value

mmSmartStreaming.reportAdInfo(mmadInfo);

mmSmartStreaming.reportAdStart();
mmSmartStreaming.reportAdEnd();
```

<details>

<summary>Ad Info Fields &#x26; Description</summary>

<table data-header-hidden><thead><tr><th width="204.65234375">Field</th><th width="114.8046875">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.

```cpp
mmSmartStreaming.reportAdBufferingStrated();
mmSmartStreaming.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.

```cpp
mmSmartStreaming.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>

#### v3.3.0[^1]

* Added support for reporting a new field encoding service via `reportEncodingService`.
* Introduced custom event reporting through `reportCustomEvent`.
* Fixed response parsing failures caused by HTTP headers being included in the body under certain conditions (e.g., when using proxy tools like Charles).

</details>

***

<details>

<summary>Previous Releases</summary>

#### v3.2.0[^2]

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

#### v[**3.1.0**](#user-content-fn-3)[^3]

* Preload field addition
* App Session ID field addition
* Fix to consider Exit in Buffering

</details>

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

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

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