Roku with IMA SDK

This document describes the Roku MediaMelon Player IMA SDK Integration with the Roku media player.

Step 1: Include MediaMelon SmartStreaming SDK

Step 2: Setup a new MediaMelon Task

Step 3: MediaMelon Code Integrate

Step 4: Error Handling

Step 5: Google IMA Ads Integration

Step 6: Variables and Description

Step 1: Include MediaMelon SmartStreaming SDK

To integrate, unzip the MediaMelon Roku library and place the MMSmartStream folder in the components directory.

SDK: MediaMelon Roku IMA SDK

Step 2: Setup a new MediaMelon Task

Create a new XML file MMTask.xml inside your components folder. This is used to link MediaMelon’s brsfiles into your application.

The MMTask.xmlfile should contain the following:

<component name="MMTask" extends="Task">
<interface>
    <field id="video" type="node" alwaysNotify="true"/>
    <field id="config" type="assocarray" alwaysNotify="true"/>
    <field id="customConfig" type="assocarray" alwaysNotify="true" /> 
    <field id="contentMetadata" type="assocarray" alwaysNotify="true"/> 
    <field id="customTags" type="assocarray" alwaysNotify="true"/>
    <field id="error" type="assocarray" alwaysNotify="true"/>
    <field id="adError" type="assocarray" alwaysNotify="true"/>
    <field id="view" type="String" alwaysNotify="true"/>
    <field id="exit" type="Boolean" alwaysNotify="true"/>
    <field id="imaads" type="assocarray" alwaysNotify="true"/>
    <field id="isAdImpressionSent" type="Boolean" alwaysNotify="true"/>
    <field id="sdk_version" type="String" alwaysNotify="true"/>
    <field id="seekThreshold" type="Integer" alwaysNotify="true"/>
    <field id="codecs" type="assocarray" alwaysNotify="true" />
    <field id="isVideoLive" type="Boolean" alwaysNotify="true" />
    <field id="enableCustomErrorReporting" type="Boolean" alwaysNotify="true" />
</interface>

<script type="text/brightscript" uri="pkg:/Components/MMSmartStream/MMSmartStreamWrapper.brs"/>
<script type="text/brightscript" uri="pkg:/Components/MMSmartStream/MMSmartStreamEngine.brs"/>
<script type="text/brightscript" uri="pkg:/Components/MMSmartStream/MMSmartStreamRokuPlugin.brs"/>
<script type="text/brightscript" uri="pkg:/Components/MMSmartStream/Utilities.brs"/>
</component>

Step 3: MediaMelon Code Integrate

3.1. Add MMTask Child Component:

Add the MediaMelon MMTask as a child component to the main video scene custom-playback-channel-master/components/MainScene.xml

<component name="MainScene" extends="Scene" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd">
<!-- importing main handler -->
<script type="text/brightscript" uri="pkg:/components/MainScene.brs" />
<children>
    <MMTask id="MM"/>
</children>

3.2. Create MM Task Node:

In the main application, after the video instance has been created, create a MediaMelon Task node, and pass the Video node to it.

CUSTOMER_ID is your MediaMelon assigned Customer ID. If you do not know your Customer ID contact MediaMelon at customer-support@mediamelon.com.

m.MM = m.top.FindNode("MM")
m.MM.setField("video", m.video)

3.3. Set Configuration Details:

MMConfig = {
  customerID: "CUSTOMER_ID"
  subscriberId: "SUBSCRIBER_ID"
  subscriberType: "SUBSCRIBER_TYPE"
  subscriberTag: "SUBSCRIBER_TAG"
  playerName: "Roku"
  disableManifestFetch: false
  domainName: "DOMAIN_NAME"
  appName: "APP_NAME"
  appSdkVersion: "APP_VERSION"
  viewSessionId: "VIEW_SESSION_ID"
}
m.MM.setField("config", MMConfig)

If your workflow restricts the manifest to be accessible from both the player and SDK simultaneously, then you can disable manifest fetch. This is an optional step.

3.4. Set Content Metadata:

contentMetadata = {
  "assetName": "ASSET_NAME",
  "assetId": "ASSET_ID",
  "videoId": "VIDEO_ID",
  "genre": "GENRE",
  "drmProtection": "DRM_PROTECTION",
  "episodeNumber": "EPISODE_NUMBER",
  "season": "SEASON",
  "seriesTitle": "SERIES_TITLE",
  "contentType": "CONTENT_TYPE",
}
m.MM.setField("contentMetadata", contentMetadata)

3.5. Set Custom Configuration Details:

customConfig = {
  cdn: "CDN"
  experimentName: "EXPERIMENT_NAME"
  subPropertyId: "SUB_PROPERTY_ID"
  streamFormat: "STREAM_FORMAT"
  mediaType: "MEDIA_TYPE"
  drmProtection: "DRM_PROTECTION"
}
m.MM.setField("customConfig", customConfig)

3.6. Set Codecs:

codecs = {
  video: "VIDEO_CODEC"
  audio: "AUDIO_CODEC"
}
m.MM.setField("codecs", codecs)

3.7. Set Custom Metadata:

customMetadata = {
  "CUSTOM_KEY_1": "VALUE_1",
  "CUSTOM_KEY_2": "VALUE_2"
}
m.MM.setField("customTags", customMetadata)

3.8. Set Seek Threshold:

By default seek threshold is set to 2 seconds in the SDK.

m.MM.setField("seekThreshold", 5)

3.9. Set is Video Live:

Set isVideoLive to true for live video stream and to false for VOD stream

m.MM.setField("isVideoLive", true)

3.10. Set View:

It's important to set the view field start for every new view starts and to end when a view ends.

  • Start View:

m.MM.setField("exit", false)
m.MM.setField("view", "start")
  • End View:

m.MM.setField("view", "end")
m.MM.setField("exit", true)

3.11. Run the SDK:

m.MM.control = "RUN"
m.player.setFocus(true)

Step 4: Error Handling

By default, SDK listens to the video node for errors. To report custom errors set enableCustomErrorReporting flag to true and report the errors in the following way;

Upon setting enableCustomErrorReporting flag to true, SDK will stop listening to the video node errors. Only custom errors will be reported.

m.MM.setField("enableCustomErrorReporting", true)

4.1. Video Error Reporting:

m.MM.error = { 
    errorCode: "ERROR_CODE",
    errorMessage: "ERROR_MESSAGE",
    errorDetails: "ERROR_DETAILS"
}

4.2. Ad Error Reporting:

m.MM.adError = { 
    errorCode: "ERROR_CODE",
    errorMessage: "ERROR_MESSAGE",
    errorDetails: "ERROR_DETAILS"
}

Step 5: Google IMA Ads Integration

This guide demonstrates how to integrate the Mediamelon Roku SDK into a sample video player app with Google Ima Ads, downloaded the basic example from GitHub.

5.1. Include MediaMelon Ad Plugin:

Include MMImaAdsPlugin.brs file into SDK.xml as shown below.

<?xml version = "1.0" encoding = "utf-8" ?>
<component name = "imasdk" extends = "Task">

<script type = "text/brightscript">
    <![CDATA[
        <!-- Your code goes here -->
    ]]>
</script>

<!-- MediaMelon IMA AdPlugin -->
<script type = "text/brightscript" uri="pkg:/Components/MMSmartStream/MMImaAdsPlugin.brs"/>
</component>

5.2. Create an IMA Stream Player:

Call MediaMelon APIs to notify adBreakStarted and adBreakEnded as shown below.

...
sub setupVideoPlayer()
  sdk = m.sdk
  m.player = sdk.createPlayer()
  ...
  m.player.adBreakStarted = Function(adBreakInfo as Object)
    ...
    'MediaMelon API to notify AdBreakStart'
    mmAdBreakStarted(adBreakInfo)
  End Function
  m.player.adBreakEnded = Function(adBreakInfo as Object)
    ...
    'MediaMelon API to notify AdBreakEnd'
    mmAdBreakEnded(adBreakInfo)
  End Function
End Sub

5.3. Add Event Listeners and Start the Stream:

After requesting your stream, add event listeners to track ad progress from MediaMelon SDK by calling an API addMediaMelonAdCallbacks .

Sub loadStream()
  sdk = m.sdk
  sdk.initSdk()
  setupVideoPlayer()
  request = sdk.CreateStreamRequest()
  ...
  m.streamManager = Invalid
  While m.streamManager = Invalid
    sleep(50)
    m.streamManager = sdk.getStreamManager()
  End While
  ...
  'MediaMelon Callback Register'
  addMediaMelonAdCallbacks(m.sdk, m.streamManager)
  m.streamManager.start()
End Sub

Step 6: Variables and Description

Variable

Description

Optional/Mandatory

PLAYER_NAME

String containing the Player Name.

Mandatory

CUSTOMER_ID

String containing your MediaMelon-assigned Customer ID.

Mandatory

SUBSCRIBER_ID

String containing your Subscriber’s ID.

Mandatory

DOMAIN_NAME

String containing your section of your subscriber or assets.

Mandatory

SUBSCRIBER_TYPE

String containing the Subscriber Type (e.g. “Free”, “Paid”).

Mandatory

SUBSCRIBER_TAG

String containing additional subscriber-specific information. This is sent in clear (not hashed) to SmartSight and it is advised not to send sensitive information in this field.

Optional

ASSET_ID

String containing Asset Id.

Mandatory

ASSET_NAME

String containing Asset Name.

Mandatory

VIDEO_ID

String containing your video’s ID.

Mandatory

CONTENT_TYPE

String containing the type of the Content. For example - "Movie", "Special", "Clip", "Scene" or "Episode".

Mandatory

GENRE

String containing the Genre of the content. For example - "Comedy", "Horror".

Mandatory

DRM_PROTECTION

Widevine, Fairplay, Playready, etc. Unknown means content is protected, but the protection type is unknown. For clear contents, do not set this field

Mandatory

EPISODE_NUMBER

String containing sequence number of the Episode.

Mandatory

SEASON

String containing the Season. For example - "Season 1".

Mandatory

SERIES_TITLE

String containing Title of the Series.

Mandatory

VIDEO_TYPE

String containing Video Type. For example - "LIVE", and "VOD".

Optional

PLAYER_BRAND

String containing Player Brand (e.g. “Exo Player”).

Mandatory

PLAYER_MODEL

String containing Player Model. For example - This could be a variant of a player. Say the name of third third-party player used by the organisation. Or any human-readable name of the player.

Mandatory

PLAYER_VERSION

String containing Player Version.

Mandatory

CUSTOM_KEY_1

Custom metadata key can be added here if required.

Optional

VALUE_1

Custom metadata value can be added here if required.

Optional

BASE_PLAYER_NAME

String containing base player name

Optional

BASE_PLAYER_VERSION

String containing base player version

Optional

EXPERIMENT_NAME

You can use this field to categorise views into different experiments, allowing you to filter by this dimension later.

Optional

SUB_PROPERTY_ID

A sub-property is an optional feature that allows you to organize data within a property. For instance, a video platform could use sub-properties to group data by customer, or a media company might use them to differentiate between its various websites.

Optional

VIEW_SESSION_ID

An ID that can be used to link the view with upstream platform services, such as CDN or origin logs, for correlation purposes.

Optional

hashSubscriberId

To hash the subscriber ID set this boolean variable to true, else set it to false.

Optional

player

Player Object.

Mandatory

streamURL

Current playing content stream URL.

Mandatory

isLive

Set this boolean variable to true if the content is Live else set it to false for VOD content.

Optional

playerWidth

Integer value that represents width of the player

Mandatory

playerHeight

Integer value that represents height of the player

Mandatory

Last updated

Was this helpful?