Appearance
Reference App
For a complete working example, check out the TrueX Roku Reference App.
Overview
In order to support interactive ads on Roku, TrueX has created a renderer component library that can renderer TrueX ads natively, which interfaces with a hosting channel, as well as its existing ad server and content delivery mechanism (e.g. SSAI).
With this library, the host player channel can defer to the TruexAdRenderer when it is required to display a TrueX ad.
For simplicity, publisher implemented code will be referred to as "channel code" while TrueX implemented code will be referred to as "renderer code".
TrueX will provide a Roku TruexLibrary component library that can be loaded into the channel. This library will offer a component, TruexAdRenderer, that will need to be instantiated, initialized and given certain commands (described below in TruexAdRenderer Input Events) by the channel code.
At this point, the renderer code will take on the responsibility of requesting ads from TrueX server, creating the native UI for the TrueX choice card and interactive ad unit, as well as communicating events to the channel code when action is required.
The channel code will still need to parse out the SSAI ad response, detect when a TrueX ad is supposed to display, pause the stream, instantiate TruexAdRenderer and handle any events emitted by the renderer code.
It will also need to handle skipping ads in the current ad pod, if it is notified to do so.
When to show TrueX ad
Upon receiving an ad schedule from your SSAI service, you should be able to detect whether or not TrueX is returned in any of the pods. TrueX ads should have apiFramework set to VPAID or truex.
SSAI or ad server vendors differ in the way they convey information back about ad schedules to clients. Certain vendors such as Verizon / Uplynk expose API’s which return details about the ad schedule in a JSON object. For other vendors, for instance Google DAI, the TrueX payload will be encapsulated as part of a companion payload on the returned VAST ad. The Roku RAF library also exposes various wrappers which encapsulate vendor specific logic into a simple interface. Please work with your TrueX point of contact if you have difficulty identifying the right approach to detecting the TrueX placeholder, which will be the trigger point for the ad experience.
Once the player reaches a TrueX placeholder, it should pause, instantiate the TruexAdRenderer and immediately trigger init followed by start events.
Alternatively, you can instantiate and init the TruexAdRenderer in preparation for an upcoming placeholder, pre-loading the ad. This will give the TruexAdRenderer more time to complete its initial ad request, and will help streamline TrueX load time and minimize wait time for your users. Once the player reaches a placeholder, it can then call start to notify the renderer that it can display the unit to the user.
Handling Events from TruexAdRenderer
Once start has been called on the renderer, it will start to emit events (see TruexAdRenderer Output Events -- Main Flow and TruexAdRenderer Output Events -- Informative).
One of the first events you will receive is adStarted. This notifies the channel that the renderer has received an ad for the user and has started to show the unit to the user. The channel does not need to do anything in response, however it can use this event to facilitate a timeout. If an adStarted event has not fired within a certain amount of time, the host channel can proceed to normal video ads.
At this point, the channel code must listen for the renderer's terminal events (described below), while paying special attention to the adFreePod event. A terminal event signifies that the renderer is done with its activities and the channel may now resume playback of its stream. The adFreePod event signifies that the user has earned a credit with TrueX and all linear video ads remaining in the current pod should be skipped. If the adFreePod event did not fire before a terminal event is emitted, the channel should resume playback without skipping any ads, so the user receives a normal video ad payload.
Terminal Events
The terminal events are:
adCompleted: the user has exited the TrueX aduserCancelStream: the user intends to exit the current stream entirelynoAdsAvailable: there were no TrueX ads available to the useradError: the renderer encountered an unrecoverable error
It's important to note that the player should not immediately resume playback once receiving the adFreePod event -- rather, it should note that it was fired and continue to wait for a terminal event.
Handling Ad Elimination
Skipping video ads is completely the responsibility of the channel code. The SSAI API should provide enough information for the channel to determine where the current pod end-point is, and the channel, when appropriate, should fast-forward directly to this point when resuming playback.
TruexAdRenderer Roku API
This is an outline of TruexAdRenderer input and output events. Input events are assigned on the action field from the interface of the TruexAdRenderer, while output events are emitted against the event field on the same component.
Reference to the TrueX Component Library
The TrueX interactive ad component and its rendering logic are distributed as part of a component library. It is required for the hosting channel to add a reference to the component library in order for it to be used, for instance via the following reference added to your channel’s main scene:
xml
<ComponentLibrary id="TruexAdLibrary"
uri="https://ctv.truex.com/roku/v1/release/TruexAdRenderer-Roku-v1.pkg"/>Note: by default we recommend clients to integrate by linking the component library using the above URL which allows the distribution of performance and functionality updates without requiring a whole new channel release for the client. However a major/minor/build specific component library URL is available on request if it is instead desirable to link to a specific build and not receive updates automatically.
TruexAdRenderer Input Events
init
brightscript
m.tar = m.top.createChild("TruexLibrary:TruexAdRenderer")
m.tar.observeFieldScoped("event", "handleTarEvent")
m.tar.action = {
type : "init",
adParameters : "<Ad parameters associative array as returned by SSAI>",
slotType : "<the type of the current ad pod>",
supportsUserCancelStream : <optional; set to true to enable the userCancelStream event>,
logLevel : <optional; set the verbosity of **TrueX** logging, from 0 (mute) to 5 (verbose), defaults to 5>,
channelWidth : <optional; set the width in pixels of the channel's interface, defaults to 1920>,
channelHeight : <optional; set the height in pixels of the channel's interface, defaults to 1080>
}This event should be triggered by the channel code in order to initialize the TruexAdRenderer. The renderer will parse out the adParameters and slotType passed to it and make a request to the TrueX ad server to see what ads are available.
You may initialize TruexAdRenderer early (a few seconds before the next pod even starts) in order to give it extra time to make the ad request. The renderer will output an adFetchCompleted event at completion of this ad request. This event can be used to facilitate the implementation of a timeout or loading indicator, and when to make the call to start.
The parameters for this method call are:
adParameters: AdParameters as returned by SSAI. It is a JSON object and expected to be passed in as a Roku Associative Array. In the example of Uplynk, this would correspond toresponse.ads.breaks[0].ads[0].adParameters.slotType: the type of the current ad pod,PREROLLorMIDROLLsupportsUserCancelStream: optional -- set totrueto enable the userCancelStream eventlogLevel: optional; set the verbosity of TrueX logging, from 0 (mute) to 5 (verbose), defaults to 5channelWidth: optional; set the width in pixels of the channel's interface, defaults to 1920channelHeight: optional; set the height in pixels of the channel's interface, defaults to 1080
adParameters Syntax
The adParameters object passed in via the init message conveys to TruexAdRenderer the ad creative details necessary to driving the interactive experience with the viewer.
As noted above, it is expected as a JSON object, of a Roku Associative Array type (roAssociativeArray).
This should be populated with the contents of the response from the TrueX VAST tag. This can be found included in a CDATA section as part of the VAST payload's Ad/Inline/Creatives/Creative/Linear/AdParameters XML element. See example below:

Depending on the type of integration, TrueX supports a few different types of payloads passed in. However regardless of how the integration is accomplished, the adParameters will always be found in the VAST payload in the location noted above.
start
brightscript
m.tar.action = {
type : "start"
}This event should be triggered by the channel code when the channel is ready to display the TrueX unit to the user. This can be called anytime after the unit is initialized.
The channel should have as much extraneous UI hidden as possible, including player controls, status bars and soft buttons/keyboards.
After calling start, the channel code should wait for a terminal event before taking any more action, while keeping track of whether or not the adFreePod event has fired.
In a non-error flow, the renderer will first wait for the ad request triggered in init to finish if it has not already. It will then display the TrueX unit to the user in a new component (added to the TruexAdRenderer parent component) and then fire the adStarted event. adFreePod and other events may fire after this point, depending on the user's choices, followed by one of the terminal events.
TruexAdRenderer Output Events -- Main Flow
The following events signal the main flow of the TruexAdRenderer and may require action by the host channel:
adFetchCompleted
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "adFetchCompleted"
' }This event fires in response to the init method when the TrueX ad request has successfully completed and the ad is ready to be presented. The host channel may use this event to facilitate a loading screen for pre-rolls, or to facilitate an ad request timeout for mid-rolls.
For example: init is called for the pre-roll slot, and the channel code shows a loading indicator while waiting for adFetchCompleted. Then, either the event is received (and the channel can call start) or a specific timeout is reached (and the channel can remove the TruexAdRenderer component and resume playback of normal video ads).
Another example: init is called well before a mid-roll slot to give the renderer a chance to preload its ad. If adFetchCompleted is received before the mid-roll slot is encountered, then the channel can call start to immediately present the TrueX ad. If not, the channel can wait for a specific timeout (if not already reached, in case the user has seeked to activate the mid-roll) before removing the TruexAdRenderer component and resuming playback with normal video ads.
adStarted
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "adStarted",
' campaignName : <string representing the campaign name>
' }This event will fire in response to the start input event when the TrueX UI is ready and has been added to the component hierarchy.
The parameters for this event are:
campaignName: The name of the ad campaign available to the user (e.g. "Storebought Coffee - Sample Video Ad #1 - Q1 2017")
adCompleted
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "adCompleted",
' timeSpent : <integer representing the amount of time spent>
' }This is a terminal event. This event will fire when the TrueX unit is finished with its activities -- at this point, the channel should resume playback and remove the TruexAdRenderer component from the Scene Graph.
Here are some examples where adCompleted will fire:
- The user opts for normal video ads (not TrueX)
- The choice card countdown runs out
- The user completes the TrueX ad unit
- After a "skip card" has been shown to a user for its duration
The parameters for this event are:
timeSpent: The amount of time (in seconds) the user spent on the TrueX unit
adError
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "error",
' errorMessage : <string representing the error message>
' }This is a terminal event. This event will fire when the TrueX unit has encountered an unrecoverable error. The channel code should handle this the same way as an adCompleted event - resume playback and remove the TruexAdRenderer component from the Scene Graph.
The parameters for this event are:
errorMessage: A description of the cause of the error.
noAdsAvailable
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "noAdsAvailable"
' }This is a terminal event. This event will fire when the TrueX unit has determined it has no ads available to show the current user. The channel code should handle this the same way as an adCompleted event - resume playback and remove the TruexAdRenderer component from the Scene Graph.
adFreePod
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "adFreePod"
' }This event will fire when the user has earned a credit with TrueX. The channel code should notate that this event has fired, but should not take any further action. Upon receiving a terminal event, if adFreePod was fired, the channel should skip all remaining ads in the current slot. If it was not fired, the channel should resume playback without skipping any ads, so the user receives a normal video ad payload.
userCancelStream
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "userCancelStream"
' }This is a terminal event, and is only enabled when the supportsUserCancelStream property is set to true when triggering the init action.
When enabled, the renderer will fire this event when the user intends to exit the stream entirely. The channel, at this point, should treat this the same way it would handle any other "exit" action from within the stream -- in most cases this will result in the user being returned to an episode/series detail page.
If this event is not enabled, then the renderer will emit an adCompleted event instead.
TruexAdRenderer Output Events -- Informative
All following events are used mostly for tracking purposes -- no action is generally required.
optIn
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "optIn"
' }This event will fire if the user selects to interact with the TrueX interactive ad.
Note that this event may be fired multiple times if a user opts in to the TrueX interactive ad and subsequently backs out.
optOut
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "optOut"
' userInitiated : <true or false>
' }This event will fire if the user opts for a normal video ad experience.
The parameters for this event are:
userInitiated: This will be set totrueif this was actively selected by the user,falseif the user simply allowed the choice card countdown to expire.
adsAvailable
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "adsAvailable"
' }This is an optional event. This event will fire following a successful ad request and adFetchCompleted event to indicate the availability of ad inventory in TruexAdRenderer. This event is the converse of noAdsAvailable and can be useful to determine when the instance of the renderer is will be able to successfully be started in a pre-loading scenario.
skipCardShown
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "skipCardShown"
' }This event will fire anytime a "skip card" is shown to a user as a result of completing a TrueX Sponsored Stream interactive in an earlier pre-roll.
userCancel
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "userCancel"
' }This event will fire when a user backs out of the TrueX interactive ad unit after having opted in. This would be achieved by tapping the "Yes" link to the "Are you sure you want to go back and choose a different ad experience" prompt inside the TrueX interactive ad. The user will be subsequently taken back to the Choice Card (with the countdown timer reset to full).
Note that after a userCancel, the user can opt-in and engage with an interactive ad again, so more optIn or optOut events may then be fired.
videoEvent
brightscript
function handleTarEvent(evt as Object) as Void
adEvent = evt.getData()
' adEvent : {
' type : "videoEvent",
' subType : "<the subType -- see below>",
' videoName : "<the name of the video, if available>",
' url : "<the source URL of the video, if available>"
' }A videoEvent is emitted when noteworthy events occur in a video within a TrueX unit. These events are differentiated by their subType value as follows:
started: A video has startedfirstQuartile: A video has reached its first quartilesecondQuartile: A video has reached its second quartilethirdQuartile: A video has reached its third quartilecompleted: A video has reached completion
The parameters for this event are:
subType: The subType of the emitted video eventvideoName: The name of the video that emitted the event, if availableurl: The source URL of the video that emitted the event, if available

