Overview
The Roku Ad Framework (RAF) is responsible for a consistent ad experience across the Roku platform. For channels that implement ads using server-side ad insertion (SSAI), this can prove challenging due to some intricate steps of the process. Developers can, therefore, leverage the Roku-approved SSAI adapters to simplify this process (See the samples below).
Note: Before using the adapters, please refer to Requirements for Server Side Ad Insertion.
Roku Ad Framework Requirements
All channels that have video advertisements are required to meet Roku's certification requirements for RAF. Notably, the channel must always use client-side firing event (All SSAI providers support client-side firing events) through RAF.
The Roku adapters provide two options:
- Firing off all the metrics through the SSAI adapter and RAF
- The channel is responsible for firing the metrics through RAF with the adapter callbacks (See examples for using callback below)
It is encouraged that the developer uses the first option, but with either option, the metrics must be fired using RAF APIs.
The APIs used are different depending on the approach, but audience measurement must be dispatched on the client side. Roku recommends that the channel adopts the comScore VCE-inclusive audience measurement API.
RAFX SSAI Adapters
The RAFX SSAI Adapters provide interfaces to both SSAI manifest servers (stitchers) and RAF, including:
- Parsing of the masterURL response, and extraction of playURL, AdURL, and ad metadata
- Transforming SSAI ad metadata into RAF-usable ad metadata and configuring RAF for playback
- Observing stream events and timed metadata
- Matching the stream events and ad metadata and firing event pixels on time
- Pinging/Polling AdURL as required by the SSAI manifest server, parsing, and reconfiguring RAF
Server-Side Ad Insertion Playback
To playback an SSAI stream, the developer must follow these steps:
- Initialize a playback Task
- Make a request to the masterURL
- Enable the client-side ad tracking and get the playURL, AdURL and/or ad metadata
- Configure playback content and observe stream events
- Start playing stream and fire event pixels on time as responding to observed events and ping/poll ad metadata
How to playback SSAI content using the adapters
Following are the instructions on how to playback server-side ads content using the adapters:
Note: For specific working instructions for a particular adapter, refer to the adapter samples below.
1) Loading the adapter
The following entry loads the adapter into the task:
At the beginning of the playback Task, instantiate the adapter with proper parameters and then initialize it. The valid values of the parameter name are uplynk, adobe, onceux, yospace, awsemt, and ggldai.
adapter = RAFX_SSAI({name:"uplynk"}) ' Supported: uplynk, adobeonceux, yospace, awsemt, ggldai adapter.init()
2) Make an initial request to the SSAI manifest server getting Ad metadata: Request Ad Metadata
request = { type: adapter.SreamType.VOD ' Required, VOD or LIVE url: "http://admanifest.ssai.com/api?assetid=abcdefg"' Ad metadata URL, provided by SSAI } result = adapter.requestStream(request)
The value of the parameter URL depends on which SSAI manifest servers are to be integrated and which type of stream is used (The channel may query the initial request to SSAI manifest server by itself rather than using the adapter.requestStream() call). Valid values of the parameter type are VOD or LIVE. VOD is used when ad metadata is fetched before the playback starts; LIVE is used when ad metadata is provided as ping/poll/in-stream (such as X-MARKER) content playback.
3) Read Stream Info
The initial request to SSAI manifest servers returns content URL (like Adobe and Uplynk). The following entry gets the content URL:
streamInfo = adapter.getStreamInfo() url = streamInfo["playURL"]
4) Enable Ads
Once the content playback URL is known, the adapter is ready to track ads. Pass the adapter player object and observe the position event on the video node.
The value of params.player is given to RAF internally as the second parameter of RAF.stitchedAdHandledEvent(). adapter.enableAds() parses ad metadata and/or configures additional settings such as observing timedMetadata2 of given video node. It then calls RAF.stitchedAdsInit() when valid ad metadata is found in the initial response from the SSAI manifest servers.
port = CreateObject("roMessagePort") params = {player: {sgnode:m.top.video, port:port}} adapter.enableAds(params) m.top.video.observeField("position", port)
The channel can provide an optional parameter, params.useStitched = false. If the parameter is set to false, the channel is required to:
- Set the callback functions to proper AdEvents
- Fire pixels by using RAF.fireTrackingEvents()
- Run and manage Interactive ads
By default, params.useStitched is set to true. In this case:
- Setting callback functions is optional
- Pixels are fired internally by the adapter and RAF
- Interactive ads are ran and managed by the adapter and RAF
a) Optional: Enable Ads Without stitchedAdHandledEvent
params = { player: {sgnode:m.top.video, port:port}, useStitched: false } adapter.enableAds(params) ' adapter will not call RAF.stitchedAdHandledEvent() and RAF will not play Interactive Ad
b) Optional: Set Callbacks
A callback parameter is an object with keys, event, and position.
When using PODS, the object has an additional key, adPods, and the value of the parameter is an array of the adPod metadata.
When using POD_START, the object has an additional key, adPod, and the value of the parameter is the current adPod metadata.
Supported callbacks are:
- PODS
- POD_START
- POD_END
- IMPRESSION
- FIRST_QUARTILE
- MIDPOINT
- THIRD_QUARTILE
- COMPLETE
Note: When params.useStiched = true or, not provided in the param (this is the default), setting callbacks is optional and for informational purposes only. The channel MUST NOT call RAF.fireTrackingEvents() in such a case.
When params.useStitched = false, it is required to set callbacks and the channel MUST call RAF.fireTrackingEvents().
Setting the callback functions to the Adapter:
' Set adapter callback functions adapter.addEventListener(adapter.AdEvent.POD_START, rafxCallback) adapter.addEventListener(adapter.AdEvent.POD_END, rafxCallback) adapter.addEventListener(adapter.AdEvent.IMPRESSION, rafxCallback) ... ... function rafxCallback(eventInfo as object) as void if adapter.AdEvent.POD_START = eventInfo.event m.top.adPlaying = true else if adapter.AdEvent.POD_COMPLETE = eventInfo.event m.top.adPlaying = false end if print "Callback at : ";eventInfo.position end function
5) Enable Ad Measurements
When the channel is ready to start playback, configure RAF by enabling ad measurements:
It is recommended to use enableAdMeasurements.
adIface = Roku_Ads() adIface.enableAdMeasurements(true) ' Required adIface.setContentLength(...) ' Set app/content specific info adIface.setNielsenProgramId(...) ' Set app/content specific info adIface.setNielsenGenre(...) ' Set app/content specific info adIface.setNielsenAppId(...) ' Set app/content specific info
6) Playback Loop
The developer can now start the playback and run the message loop:
video.control = "play" ' start playback while true msg = wait(1000, port) curAd = adapter.onMessage(msg) if invalid = curAd video.setFocus(true) ' recommended end if ' exit while loop when condition met ... end while
adapter.onMessage() calls RAF.stitchedAdHandledEvent() and returns the object as it is. It is thus recommended to evaluate the returned value and call setFocus() on the video node in case the interactive ad changes focus while playing.
When not using RAF.stitchedAdHandledEvent(), the app must fire AdEvent pixels in the callback functions.
Once the playback is completed, discard the adapter. Do not reference the adapter outside of the Task or re-use the same adapter instance.
Roku Ad Framework APIs
For channels playing SSAI streams, it is required to call RAF APIs using the guidelines below.
It is required for channels to call the following every time the content is played back in the Task:
- Enable ad measurement: enableAdMeasurements(true)
- Set content/app info: setNielsenProgramId(), setNielsenGenre(), setNielsenAppId(), setContentLength()
When useStitched is set to true, the adapter itself:
- Generates RAF ad metadata from SSAI specific format and calls stitchedAdsInit(), stitchedAdHandledEvent() to fire ad events and measurement pixels
When useStitched is set to false, the developer should make sure that the channel:
- Sets callback functions to the adapter
- Fires event pixels via: fireTrackingEvents() when called back
RAFX SSAI Adapter Samples
The following RAFX SSAI Adapter samples are built to provide client-side integration with SSAI, for both VOD and LIVE.
Note that VOD mode means ad metadata is fed from the SSAI server before content playback.
LIVE mode means ad metadata is given as a part of the content stream such as ID3 (HLS) and emsg (DASH), and/or periodic ping/poll request to SSAI server.
Before using the adapter samples, the developer must be familiar with the SSAI providers’ documentation:
Note: The SSAI providers may have undocumented formats, parameters and API behaviors.
Uplynk Adapter
Uplynk Adapter | File |
---|---|
RAFX SSAI Adapter for Uplynk Preplay and Ping mode, showing ad rendering via stitchedAdsInit()/stitchedAdHandledEvent(). The Uplynk Adapter provides the following services:
| See UplynkTask.brs to find out how to use the adapter. Copy rafxssai.brs to your project and integrate it with the content playback Task. |
Adobe Adapter
Adobe Adapter | File |
---|---|
RAFX SSAI Adapter for Adobe Manifest Server simple and x-marker mode, showing ad rendering via stitchedAdsInit()/stitchedAdHandledEvent(). Adobe Adapter provides the following services:
| See AdobeTask.brs to find out how to use the adapter. Copy rafxssai.brs to your project and integrate it with the content playback Task. |
Brightcove/OnceUX Adapter
Brightcove/OnceUX Adapter | File |
---|---|
RAFX SSAI Adapter for OnceUX VOD mode, showing ad rendering via stitchedAdInit()/stitchedAdHandledEvent(). OnceUX Adapter provides the following services:
When reading stream info, "playURL" field is not available because OnceUX provides a pair of video contentURL and metadata URL. Read Stream Info:
However, the returned value of getStreamInfo() includes a field called tracking. This returns a list of event info generated from XML element: <uo:contentImpressions><uo:Impression>. The app is responsible for sending those pixels when playback starts. For example: Sending Content Start Beacon:
| See OnceUXTask.brs to find how to use the adapter. Copy rafxssai.brs to your project and integrate it with the content playback Task. |
Yospace Adapter
Yospace Adapter | File |
---|---|
RAFX SSAI Adapter for Yospace server, showing ad rendering via stitchedAdInit()/stitchedAdHandledEvent(). Yospace Adapter provides the following services:
| See YospaceTask.brs to find how to use the adapter. Copy rafxssai.brs to your project and integrate it with the content playback Task. |
AWS Adapter
AWS Elemental MediaTailor Adapter | File |
---|---|
RAFX SSAI Adapter for AWS Elemental MediaTailor(AWSEMT), showing ad rendering via stitchedAdInit()/stitchedAdHandledEvent() . AWSEMT Adapter provides following services:
| See AEMTTask.brs to find how to use the adapter. Copy rafxssai.brs to your project and integrate it with the content playback Task. |
Attachments:
rsgadb.zip (application/zip)
rsgoux.zip (application/zip)
rsgyspc.zip (application/zip)
rsgemt.zip (application/zip)
rsgggl.zip (application/zip)
rsgemt.zip (application/zip)
rsgupl.zip (application/zip)
rsgadb.zip (application/zip)
rsgoux.zip (application/zip)
rsgyspc.zip (application/zip)
rsgemt.zip (application/zip)
rsgggl.zip (application/zip)
rsgupl.zip (application/zip)
rsgadb.zip (application/zip)
rsgoux.zip (application/zip)
rsgoux.zip (application/zip)
rsgyspc.zip (application/zip)
rsgemt.zip (application/zip)
rsgggl.zip (application/zip)
rsgggl.zip (application/zip)
rsgupl.zip (application/zip)
rsgadb.zip (application/zip)
rsgoux.zip (application/zip)
rsgyspc.zip (application/zip)
rsgemt.zip (application/zip)
rsgadb.zip (application/zip)
rsgadb.zip (application/zip)
rsgupl.zip (application/zip)
rsgyspc.zip (application/zip)
rsgemt.zip (application/zip)
rsgoux.zip (application/zip)
rsgadb.zip (application/zip)
rsgupl.zip (application/zip)
rsgadb.zip (application/zip)
rsgoux.zip (application/zip)
rsgyspc.zip (application/zip)
rsgemt.zip (application/zip)
rsgadb.zip (application/zip)
rsgyspc.zip (application/zip)
rsgadb.zip (application/zip)
rsgupl.zip (application/zip)
rsgemt.zip (application/zip)
rsgadb.zip (application/zip)
rsgupl.zip (application/zip)
rsgupl.zip (application/zip)
rsgadb.zip (application/zip)
rsgadb.zip (application/zip)
rsgoux.zip (application/zip)
rsgoux.zip (application/zip)
rsgyspc.zip (application/zip)
rsgyspc.zip (application/zip)
rsgemt.zip (application/zip)
rsgemt.zip (application/zip)
rsgadb.zip (application/zip)
rsgadb.zip (application/zip)