This guide walks through integration with Roku to collect video performance metrics with Mux data.
Features
Include the Mux Data SDK
Setup a new Mux Task
Setup the task to respond to video events
Debugging
Make your data actionable
Advertising configuration
Additional configuration
Release notes
Mux's Roku integration supports Roku SceneGraph applications, in conjunction with standard Video nodes. Mux runs as a Task alongside the Video node, and supports instances where the Video nodes are reused with additional content as well as when the Video nodes are reset between content.
The following data can be collected by the Mux Data SDK when you use the Roku SDK, as described below.
Supported Features:
Video Quality metrics are not available.
Place the SDK file in your libs folder. The latest version of the SDK can be found here:
https://src.litix.io/roku/2/mux-analytics.brsCreate a new Task XML named MuxTask.xml inside your components folder and give it the following interface. This is used to link the mux-analytics.brs file into your application.
<component name="MuxTask" extends="Task">
<interface>
<field id="video" type="node" alwaysNotify="true"/>
<field id="config" type="assocarray" alwaysNotify="true"/>
<field id="rafEvent" type="assocarray" alwaysNotify="true"/>
<field id="error" type="assocarray" alwaysNotify="true"/>
<field id="view" type="String" alwaysNotify="true"/>
<field id="exit" type="Boolean" alwaysNotify="true"/>
<field id="exitType" type="String" alwaysNotify="true" value="hard" />
<field id="useRenderStitchedStream" type="Boolean" alwaysNotify="true" value="false"/>
<field id="useSSAI" type="Boolean" alwaysNotify="true" value="false"/>
<field id="disableAutomaticErrorTracking" type="Boolean" alwaysNotify="true" value="false"/>
<field id="randomMuxViewerId" type="Boolean" value="false"/>
</interface>
<script type="text/brightscript" uri="pkg:/libs/mux-analytics.brs"/>
</component>Within your main application, create the Mux Task node, and pass the Video node that you are tracking to it. This should be done before the content is set into the Video node so that Mux can track the load process.
Get your ENV_KEY from the Mux environments dashboard.
Env Key is different than your API token
ENV_KEY is a client-side key used for Mux Data monitoring. These are not to be confused with API tokens which are created in the admin settings dashboard and meant to access the Mux API from a trusted server.

m.mux = m.top.CreateNode("mux")
m.mux.setField("video", m.video)
muxConfig = {
env_key: "ENV_KEY",
}
m.mux.setField("config", muxConfig)
m.mux.control = "RUN"
' Load the video into the Video nodeAfter you've integrated, start playing a video in the player you've integrated with. A few minutes after you stop watching, you'll see the results in your Mux account. We'll also email you when your first video view has been recorded.
You can also test that Mux is receiving data in the Mux Data dashboard. Login to the dashboard and find the environment that corresponds to your ENV_KEY and look for video views.
Note that it may take a few minutes for views to show up in the Mux Data dashboard.
To help you with the integration process and ensure you have successfully incorporated the SDK within your player, we have provided a number of optional manifest attributes. These attributes can help you better understand how the MUX SDK event tracking works as well as show you the actual data being collected. Some of the benefits of using some of the debugging attributes (mentioned below) are that you will be able to see the SDK events and data collected as it occurs.
NOTE: The outputs illustrated below are printed on a single line within the terminal to reduce clutter.
full, partial or none
Outputs the event at the time it occurs. Default value is none
Property set to partial:
[mux-analytics] EVENT playerreadyProperty set to full:
[mux-analytics] EVENT playing
{
viewer_application_name:Roku,
mux_api_version:2.1,
view_seek_duration:0,
viewer_application_version:9.20,
player_name:Reset Player,
viewer_time:1582317809984,
view_start:1582317808627,
player_model_number:4660X,
video_source_mime_type:mp4,
event:playing,
...full, partial or none
Outputs the data (full) or event(s) (partial) that is being sent (at the time of sending). Default value is none.
Property set to partial:
[mux-analytics] BEACON (2) [ playerready viewstart ]Property set to full:
[mux-analytics] BEACON (2)
[
{
viewer_application_name:Roku,
mux_api_version:2.1,
view_seek_duration:0,
viewer_application_version:9.20,
player_name:Reset Player,
viewer_time:1582317809984,
view_start:1582317808627,
player_model_number:4660X,
video_source_mime_type:mp4,
event:playerready,
...
}, {
viewer_application_name:Roku,
mux_api_version:2.1,
view_seek_duration:0,
viewer_application_version:9.20,
player_name:Reset Player,
viewer_time:1582317809984,
view_start:1582317808627,
player_model_number:4660X,
video_source_mime_type:mp4,
event:viewstart,
...
}
]mux_base_urlProtocol + domain name. Eg. https://img.litix.io
Controls to which domain the data should be sent. Useful for environmental builds of your project
The Roku SDK supports adding metadata via two different mechanisms.
The majority of the metadata should be passed inside the muxConfig object that is passed to the Mux Task. You can read detailed information about the fields that are supported in Metadata. To update any field, update this within muxConfig and then call m.mux.setField("config", muxConfig).
Some other underlying information is mapped from standard Roku content metadata, most of which you probably already set when creating your video. In particular, the metadata fields that you should set (if you do not already) are:
If advertising is to be used, you must send the appropriate events to the Mux Task, as shown below.
function setUpRokuAdFramework
adIface.SetTrackingCallback(adTrackingCallback, adIface)
end function
function adTrackingCallback(obj = Invalid as Dynamic, eventType = Invalid as Dynamic, ctx = Invalid as Dynamic)
m.mux = GetGlobalAA().global.findNode("mux")
adUrl = Invalid
if obj <> Invalid
adUrl = obj.getAdUrl()
end if
m.mux.setField("rafEvent", {obj: { adurl: adUrl }, eventType:eventType, ctx:ctx})
end functionIf you are utilizing RAF's renderStitchedStream method to stitch ads and content together client-side, then you must tell the Mux SDK that this is in use. This is set via useRenderStitchedStream on the Mux Task, set to true, such as:
mux.setField("useRenderStitchedStream", true)If you are not utilizing renderStitchedStream but instead controlling ad and content playback directly, then you need to set useRenderStitchedStream to false.
If you are utilizing server-side ad insertion (SSAI), you should signal that to the SDK by setting useSSAI to true:
mux.setField("useSSAI", true)In some situations, it is necessary to directly signal the beginning or ending of a view to Mux. This is necessary when the Video Node is recycled (i.e. more pieces of content are loaded into the same Node), or when using advertising, as the ads run outside of the lifecycle of the Video.
Note: A view is defined as the user watching a single piece of content, which includes any advertising.
mux = GetGlobalAA().global.findNode("mux")
' To signal the start of a view:
mux.setField("view", "start")
' To signal the end of a view:
mux.setField("view", "end")The exitType setting controls the behavior of the task when a request to exit/terminate the thread is invoked (via mux.exit=true). The default value of exitType is hard.
If the value is set to hard then the thread terminates immediately and any data that has not propagated already to the MUX servers is lost.
If the value is set to soft then the thread sends all the remaining data to the MUX servers and terminates afterward.
To change value to soft call m.mux.setField("exitType", "soft")
NOTE: This means that there might be a time difference between you calling mux.exit=true and the task thread actually terminating. Please ensure you have a single MUX Task running at any given time.
The Mux SDK for Roku tracks error events from the Video node automatically, and reports them as fatal playback errors. If you would like to disable this automatic error tracking, you can set the following in your MuxTask.xml:
<field id="disableAutomaticErrorTracking" type="Boolean" alwaysNotify="true" value="true"/>While it is not advised to control this at runtime, you can also set this by calling
mux.setField("disableAutomaticErrorTracking", true)In order to emit events, you will need to trigger any errors directly, by calling
mux.setField("error", {
player_error_code: errorCode,
player_error_message: errorMessage,
player_error_context: errorContext,
player_error_severity: errorSeverity,
player_error_business_exception: isBusinessException
})The error code and message should always be provided, and you can set the other fields if desired. The possible values or errorSeverity are "warning" or "fatal". Read more about Error Classification for more details.
The Mux SDK for Roku can listen to CDN change events. In order to emit events, you will need to trigger any CDN changes directly, by calling
' The "new_cdn" string should be the new CDN name
mux.setField("cdn", "new_cdn")Mux does not suggest disabling the automatic rebuffer tracking. The following is for advanced usage only.
The Mux SDK for Roku tracks error events from the Video node automatically. If you would like to disable this automatic rebuffer tracking, you can set the following in your MuxTask.xml:
<field id="disablePlayheadRebufferTracking" type="Boolean" alwaysNotify="true" value="true"/>While it is not advised to control this at runtime, you can also set this by calling
mux.setField("disablePlayheadRebufferTracking", true)Rebuffer start and end events can be emitted by calling the following
mux.setField("rebufferstart", true)mux.setField("rebufferend", true)A playback mode event can be emitted by calling the following
mux.setField("playback_mode", {
player_playback_mode: mode,
player_playback_mode_data: data
})The mode should always be provided, suggested values are: inline, fullscreen, mini and pip.
The data is optional, if provided it should be a parse-able JSON string.
A playbackmodechange event will be emitted containing the following fields:
player_playback_mode (containing the mode set)player_playback_mode_data (containing the data set)ad_playing_time_ms_cumulative (containing ad watch time)view_playing_time_ms_cumulative (containing the total content watch time plus ad watch time)ad_playing_time_ms_cumulative as total ad watch time and view_playing_time_ms_cumulative as content watch time plus ad watch timeplayback_mode user event, which triggers a playbackmodechange event, containing the playback mode and dataplaybackmodechange event sent before every viewstart event, containing standard playback modeMAX_VIDEO_POSITION_JUMP not being properly declared, which could cause app crashesvideo_codec and video_audio_codec fields are now sent in renditionchange eventserror event handlingviewer_connection_type is set to invalid if unable to be determined, set to other if connection not Wired or Wirelessviewer_connection_type is now rechecked and updated every 10 secondscdn user event, which triggers a cdnchange analytics event, containing the current and previous CDNclient_application_name and other newer metadata fields could not be setdisableAutomaticErrorTracking was not settable at runtimedisableAutomaticErrorTracking, useRenderStitchedStream, and useSSAI have had their types changed to Boolean, so you will need to make sure to update your MuxTask.xml files to the right types, and anywhere you might set those values dynamically.disableAutomaticErrorTrackinguseRandomMuxViewerIdended event was sent when it should not have beenrenderStitchedStreamplayer_init_time was expected as a string but would not work correctlyrenderStitchedStreambeaconCollectionDomainenv_key instead of property_keyadpause was incorrectly sent as adpaused)-sUpdates:
drmType property to the Mux node. This value is automatically reported from the player if available (#44)droppedFrames property to the Mux node. This value is must be reported from your player. (#44)errorContext field to Error Events. This value is automatically reported from the player if available (#44)video_id value; applications should pass their own video_id in the metadata.player_init_time could cause the application to crash.viewer_device_model was not populated correctly.viewer_user_id was overwritten unintentionally.player_mux_plugin_name and device type were set incorrectly.seeked event was incorrectly named.aderror events.mux_minification. If you set this, it will have no action. Instead, all events and beacons will be logged in an un-minified version, while everything will be sent to the Mux backend minified.player_instance_id (controlled by the Mux SDK) is sent as a GUID rather than a different format of ID.exitType configuration optionwatch_time may have been calculated incorrectly in certain situations