Skip to main content

Roku media tracking (v2)

Media version 2

Media tracking has multiple versions of schemas available. This document is for version 2 of the schemas; tracker versions earlier than v0.3.0 only support v1 tracking.

The Snowplow media tracking APIs enable you to track events from media playback on the web and in mobile apps. Track changes in playback state (play, pause, seek), playback position (ping and percentage progress events), and ad playback (ad breaks, ad progress, ad clicks).

For details on the events and entities tracked, see the media tracking overview.

Example app

See the tracked media events and entities live as you watch a video in our React example app. View the source code.

Quick start

A media tracking session follows this lifecycle:

  1. Start tracking when the player loads (before playback begins)
  2. Update player state every second during playback
  3. Track events as they occur (play, pause, seek, etc.)
  4. End tracking when the user leaves
brightscript
' 1. Start tracking when player loads (events are auto-tracked)
m.global.snowplow.enableMediaTracking = {
media: m.Video,
version: 2,
label: "My Video Title"
}

' 2-3. Player state and events are automatically tracked from the Video node

' 4. End tracking when done
m.global.snowplow.disableMediaTracking = {
media: m.Video
}

Configuration

Configure media tracking when you call startMediaTracking. All configuration is optional.

Player properties

Set initial player properties to populate the media player entity. The label property is recommended as it helps identify content during analysis.

The Roku tracker automatically reads most player properties from the Audio/Video node. Configure additional options in enableMediaTracking:

brightscript
m.global.snowplow.enableMediaTracking = {
media: m.Video, ' Audio/Video node to track (required)
version: 2, ' Schema version (defaults to 2)
id: "session-123", ' Custom session ID (auto-generated if not set)
label: "My Video", ' Human-readable title for the media_player entity
rokuVideoContext: true ' Whether to include the roku_video_context entity
}

Ping events

Media ping events are sent at regular intervals (default: 30 seconds) to report playback position. You can configure ping behavior in the starting configuration.

brightscript
m.global.snowplow.enableMediaTracking = {
media: m.Video,
version: 2,
pings: true, ' Enabled by default
pingInterval: 30 ' Seconds between pings (default: 30)
}

' Or turn off pings entirely
m.global.snowplow.enableMediaTracking = {
media: m.Video,
version: 2,
pings: false
}

Percentage progress

Track events when playback reaches specified percentage boundaries.

brightscript
m.global.snowplow.enableMediaTracking = {
media: m.Video,
version: 2,
boundaries: [25, 50, 75] ' By default, the tracker will fire events at these percentages
}

Session tracking

The media session entity is attached to all media events by default. It's optional for the Media Player data model, so you could choose not to include it.

We recommend tracking this entity.

brightscript
m.global.snowplow.enableMediaTracking = {
media: m.Video,
version: 2,
sessions: true
}

Custom entities

You can attach custom entities to all events for this media tracking instance.

brightscript
m.global.snowplow.enableMediaTracking = {
media: m.Video,
version: 2,
entities: [
{
schema: "iglu:com.example/video_metadata/jsonschema/1-0-0",
data: {"contentId": "abc123", "category": "tutorial"}
}
]
}

Filter events

Only track specific event types by providing an allowlist:

brightscript
m.global.snowplow.enableMediaTracking = {
media: m.Video,
version: 2,
captureEvents: ["play", "pause", "end"]
}

Tracking events

Track events by calling the appropriate function when player events occur. For a complete list of available events and their properties, see the media events reference.

Playback events

The Roku tracker automatically tracks the following events from Audio/Video nodes:

  • Ready, play, pause, end events
  • Seek start, seek end events
  • Ping events
  • Percent progress events (if configured)
  • Buffer start, buffer end events
  • Quality change events
  • Error events

To track events manually or track events not auto-tracked, use trackMediaEvent:

brightscript
m.global.snowplow.trackMediaEvent = {
media: m.Video,
schema: "iglu:com.snowplowanalytics.snowplow.media/ad_click_event/jsonschema/1-0-0",
data: { "percentProgress": 50 }
}

Player state events

brightscript
m.global.snowplow.trackMediaEvent = {
media: m.Video,
schema: "iglu:com.snowplowanalytics.snowplow.media/playback_rate_change_event/jsonschema/1-0-0",
data: { "newRate": 1.5 }
}

m.global.snowplow.trackMediaEvent = {
media: m.Video,
schema: "iglu:com.snowplowanalytics.snowplow.media/volume_change_event/jsonschema/1-0-0",
data: { "newVolume": 80 }
}

Ad events

Track advertising events with ad and ad break information. See the media ad and media ad break entity schemas for property details.

brightscript
' Ad break start
m.global.snowplow.trackMediaEvent = {
media: m.Video,
schema: "iglu:com.snowplowanalytics.snowplow.media/ad_break_start_event/jsonschema/1-0-0",
data: {},
adBreak: {
"breakId": "break-1",
"name": "pre-roll",
"breakType": "linear",
"podSize": 3
}
}

' Ad start
m.global.snowplow.trackMediaEvent = {
media: m.Video,
schema: "iglu:com.snowplowanalytics.snowplow.media/ad_start_event/jsonschema/1-0-0",
data: {},
ad: {
"adId": "ad-1",
"name": "Product Ad",
"duration": 30
}
}

Custom events

Track custom self-describing events within the media session. The tracker automatically attaches media entities.

brightscript
m.global.snowplow.trackMediaEvent = {
media: m.Video,
schema: "iglu:com.example/video_interaction/jsonschema/1-0-0",
data: { "action": "share", "platform": "twitter" }
}

Update player state

Manual player state updates aren't needed for the Roku tracker. The tracker automatically tracks player state from the registered media node.

Roku video entity

By default, the Roku tracker attaches a video entity to all media events.

video

Entity
Schema for a Roku video event (reflects the Video node: https://developer.roku.com/en-gb/docs/references/scenegraph/media-playback-nodes/video.md)
Schema URIiglu:com.roku/video/jsonschema/1-0-0
Example
json
{
"videoId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"contentId": "movie-12345",
"contentTitle": "Sample Movie",
"contentType": "movie",
"streamFormat": "mp4",
"measuredBitrate": 5000000,
"streamBitrate": 4500000,
"videoFormat": "hevc",
"timeToStartStreaming": 1.5,
"width": 1920,
"height": 1080
}
Properties and schema
PropertyDescription
videoId
string
Required. ID generated when video tracking of the video node was initialized.
contentId
string
Optional. ID of video provided in content metadata.
contentTitle
string
Optional. Title of video provided in content metadata.
contentUrl
string
Optional. URL of video provided in content metadata.
contentType
string
Optional. Category of video (e.g., movie, season, series) provided in content metadata.
streamFormat
string
Optional. Container format of video (e.g., mp4, wma, mkv) provided in content metadata.
streamUrl
string
Optional. URL of the current stream.
measuredBitrate
integer
Optional. Measured bitrate (bps) of the network when the stream was selected.
streamBitrate
integer
Optional. Current bitrate of the stream.
isUnderrun
boolean
Optional. Indicates whether the stream was downloaded due to an underrun.
isResumed
boolean
Optional. Indicates whether the playback was resumed after trickplay.
videoFormat
string
Optional. Video codec of the currently playing video stream (e.g., hevc, mpeg2, mpeg4_15).
timeToStartStreaming
number
Optional. Time in seconds from playback being started until the video actually began playing.
width
integer
Required. Width of the video play window in pixels. 0 if the play window is set to the width of the entire display screen.
height
integer
Required. Height of the video play window in pixels. 0 if the play window is set to the height of the entire display screen.
errorStr
string
Optional. A diagnostic message indicating a video play error. Refer to the Roku Video documentation for the format of the string.

Migrating from media v1 APIs

If you are migrating from the v1 media tracking, v2 has compatibility options to make the change easier.

For backwards compatibility with the earlier tracking API, you can continue using enableVideoTracking or enableAudioTracking instead of enableMediaTracking, and pass the node via the audio/video option instead of media. For most other options, v2 will accept either v1 or v2 roAssociativeArray formats. The tracking will work with any combination of these method and option names regardless of node type, as long as version: 2 is specified. You can also specifically opt into version 1 by passing version: 1 for any of these methods, though v2 options may not be recognized.

If using specific version values, the same version should also be specified for the corresponding disable*Tracking method. Similarly, mixing enableVideoTracking and disableMediaTracking will not work unless versions are specified consistently.

The additional options differ by version; but version 2 will accept the options from version 1 if it can't find the newer equivalent settings.

v2 Attributev1 FallbackTypeDescription
media / audio / videomedia / audio / videoAudio / VideoAudio/Video node to be tracked
versionversionIntegerTracking schema version to use; should be set to 2 if not using enableMediaTracking
idN/AUUIDA unique ID to use for the media session entity to group all tracked events
labeloptions.labelStringAn identifiable custom label sent with the event in the media_player entity
sessionsDefault enabledbooleanWhether to attach the media session entity on tracked events
pingsDefault enabledbooleanWhether to periodically generate media ping_events while content is playing
pingIntervaloptions.positionIntervalIntegerInterval in seconds in which ping_events should be reported
boundariesoptions.boundariesInteger[]Percentage boundaries in playback for which percentage_progress_events will be sent
captureEventsoptions.captureEventsString[]Types of events to capture. If specified, the event names should not have the _event suffix
context / entitiescontextSelfDescribingJSON[]Array of custom entities to include with all generated events