--- url: /infillion-ads-integration-docs/platforms/android.md --- # Android TV Integration TrueX Ad Renderer for Android provides native Android integration for Android TV and mobile devices. ## Overview The TrueX Android integration supports both Android TV (CTV) and mobile Android devices using native Android SDKs. ## Platform Support * Android TV devices * Google TV * Fire TV (Android-based apps) * Android mobile phones and tablets ## Documentation For complete integration documentation, please refer to: * [Android Integration Guide](https://github.com/socialvibe/truex-android-integrations/blob/develop/DOCS.md) ## Quick Start ```gradle // Add dependency dependencies { implementation 'com.truex:TruexAdRenderer-Android:x.x.x' } ``` ```kotlin // Initialize TrueX renderer val truexAdRenderer = TruexAdRenderer(context) truexAdRenderer.init(vastConfigUrl) { event -> when (event.type) { TruexAdEvent.AD_COMPLETED -> resumeVideo() TruexAdEvent.AD_ERROR -> { Log.e("TrueX", "Error: ${event.errorMessage}") resumeVideo() } TruexAdEvent.NO_ADS_AVAILABLE -> resumeVideo() } } ``` ## Repository Access the official Android integration repository: * [TrueX Android Integrations](https://github.com/socialvibe/truex-android-integrations) ## Migration Notice Full Android integration documentation will be migrated to this site in a future update. For now, please refer to the GitHub repository linked above. --- --- url: /infillion-ads-integration-docs/platforms/vega/events.md --- # Event Handling The TrueX Ad Renderer uses an event-driven architecture to communicate ad lifecycle states to your application. ## Event Flow Diagram Typical event sequence for a successful ad interaction: ``` ◇ adStarted │ ↓ ◇ adFetchCompleted │ ↓ ◇ adDisplayed │ ↓ ◇ optIn (if user chooses interactive ad) │ ↓ ◆ [User interacts with ad] │ ↓ ◇ adFreePod (if user completes interaction) │ ↓ ◇ adCompleted ``` ## Event Handler Implementation ### Basic Event Handler ```tsx import { TruexAdEvent, TruexAdEventType, TruexAdEventHandler } from '@truex/ad-renderer-vega'; const [ shouldSkipRemainingAds, setShouldSkipRemainingAds ] = useState(false); const handleTruexAdEvent = useCallback( (event: TruexAdEvent) => { console.log('Event:', event.type); switch (event.type) { case TruexAdEventType.AD_COMPLETED: (shouldSkipRemainingAds) ? discardCurrentAdBreak() : startNextAdInCurrentAdBreak(); break; case TruexAdEventType.AD_ERROR: startNextAdInCurrentAdBreak(); break; case TruexAdEventType.NO_ADS_AVAILABLE: startNextAdInCurrentAdBreak(); break; case TruexAdEventType.USER_CANCEL_STREAM: exitPlaybackScreen(); break; case TruexAdEventType.AD_FREE_POD: setShouldSkipRemainingAds(true); break } }, [ shouldSkipRemainingAds ] ); ``` ### Type-Safe Event Handling TypeScript provides discriminated union types for type-safe event handling: ```tsx const handleTruexAdEvent = useCallback( (event: TruexAdEvent) => { switch (event.type) { case TruexAdEventType.AD_ERROR: // TypeScript knows errorMessage exists on this event logError(event.errorMessage); break; case TruexAdEventType.POPUP_WEBSITE: // TypeScript knows url exists on this event openBrowser(event.url); break; case TruexAdEventType.AD_COMPLETED: // TypeScript knows this event has only type property (and timeSpent) resumePlayback(); break; } }, [] ); ``` ## Terminal Events Terminal events indicate that the ad experience has concluded and your application should resume normal operation: *** ### `adCompleted` ```typescript { type: TruexAdEventType.AD_COMPLETED, timeSpent: number } ``` User successfully completed the interactive ad experience. Resume video playback. **Properties**: * `timeSpent`: Time spent in the ad experience in seconds. *** ### `adError` ```typescript { type: TruexAdEventType.AD_ERROR, errorMessage: string } ``` An error occurred during ad playback. Resume video playback and log the error. **Properties**: * `errorMessage`: Human-readable error description *** ### `noAdsAvailable` ```typescript { type: TruexAdEventType.NO_ADS_AVAILABLE } ``` No ads are available to display. Resume video playback immediately. *** ### `userCancelStream` ```typescript { type: TruexAdEventType.USER_CANCEL_STREAM } ``` User chose to exit the stream entirely. Navigate away from video playback. **Note**: Only fired when `supportsUserCancelStream: true` is set in options. ## Informational Events Informational events provide status updates but don't require immediate action: *** ### `adStarted` ```typescript { type: TruexAdEventType.AD_STARTED } ``` Ad UI construction has begun. Consider showing a loading indicator. *** ### `adFetchCompleted` ```typescript { type: TruexAdEventType.AD_FETCH_COMPLETED } ``` Ad creative has been fetched and is ready to be presented. *** ### `adDisplayed` ```typescript { type: TruexAdEventType.AD_DISPLAYED } ``` Ad is fully loaded and displayed to the user. Hide loading indicators. *** ### `adFreePod` ```typescript { type: TruexAdEventType.AD_FREE_POD } ``` User has earned ad-free viewing credit. Skip remaining ads in the current pod. *** ### `optIn` ```typescript { type: TruexAdEventType.OPT_IN, userInitiated: boolean } ``` User chose to engage with the interactive ad experience. **Properties**: * `userInitiated` - `true` if actively selected by user, `false` if choice card countdown expired. *** ### `optOut` ```typescript { type: TruexAdEventType.OPT_OUT, userInitiated: boolean } ``` User declined to engage with the interactive ad. **Properties**: * `userInitiated`: `true` if actively selected by user, `false` if choice card countdown expired. *** ### `userCancel` ```typescript { type: TruexAdEventType.USER_CANCEL } ``` User backed out of the ad but did not exit the stream. **Properties**: * `url`: The URL to open in an external browser ## Helper Functions ### `isTerminalEvent` Determines if an event is a terminal event. ```typescript function isTerminalEvent(event: TruexAdEvent): boolean ``` **Parameters**: * `event` - The event to check **Returns**: `true` if the event is terminal, `false` otherwise **Example**: ```tsx import { isTerminalEvent } from '@truex/ad-renderer-vega'; const handleTruexAdEvent = (event: TruexAdEvent) => { if (isTerminalEvent(event)) { // Handle terminal event hideAd(); resumeVideo(); } }; ``` ## Checking for Terminal Events Use the helper function to determine if an event is terminal: ```tsx import { TruexAdEvent, isTerminalEvent } from '@truex/ad-renderer-vega'; const handleTruexAdEvent = (event: TruexAdEvent) => { console.log('Event:', event.type); if (isTerminalEvent(event)) { // This is a terminal event - resume app hideAd(); resumeVideo(); } }; ``` ## Best Practices ### Always Handle All Terminal Events ```tsx const handleTruexAdEvent = (event: TruexAdEvent) => { if (isTerminalEvent(event)) { cleanupAd(); resumeApp(); } }; ``` ### Track Ad Credits ```tsx case TruexAdEventType.AD_COMPLETED: // Skip remaining ads in this pod if `adFreePodEearnd` is true adFreePodEarned ? skipRemainingAds() : startNextAdInCurrentAdBreak() ; break; case TruexAdEventType.AD_FREE_POD: // Mark that user earned ad-free viewing // and call `skipRemainingAds` on `adCompleted` setAdFreePodEarned(true); break; ``` ### Use Callbacks Properly Wrap event handlers in `useCallback` to prevent unnecessary re-renders: ```tsx const handleTruexAdEvent = useCallback((event: TruexAdEvent) => { // Handler implementation }, [/* dependencies */]); ``` --- --- url: /infillion-ads-integration-docs/platforms/vega/getting-started.md --- # Getting Started This guide will help you add the TrueX Ad Renderer to your existing FireTV app's advertising setup. ## Installation Install the TrueX Ad Renderer for Vega and its required dependencies. :::steps 1. Install the Package Using npm: ```bash npm install --save @truex/ad-renderer-vega ``` 2. Peer Dependencies The TrueX Ad Renderer requires specific peer dependencies. Install all required packages: ```bash npm install \ @amazon-devices/react-native-device-info@~2.0.0 \ @amazon-devices/webview@~3.3.0 ``` 3. Verify Installation After installation, verify that the package is correctly installed: ```bash npm list @truex/ad-renderer-vega ``` You should see output similar to: ``` your-app@1.0.0 └── @truex/ad-renderer-vega@x.x.x ``` ::: ## Basic Usage Learn how to integrate the TrueX Ad Renderer component into your React Native application. ### Import the Component In your React Native component, import the TrueX Ad component: ```typescript import { TruexAd } from '@truex/ad-renderer-vega'; ``` ### Import Types For TypeScript projects, import the type definitions: ```typescript import { TruexAd, TruexAdEvent, TruexAdEventType, TruexAdRendererOptions, TruexAdProps } from '@truex/ad-renderer-vega'; ``` ### Minimal Example Here's the simplest way to render a TrueX ad: ```tsx import React, { useCallback } from 'react'; import { TruexAd, TruexAdEventType, TruexAdEventHandler } from '@truex/ad-renderer-vega'; function TruexAdContainer({ truexAdInfo, onTruexAdFinished, onTruexAdFreePod}) { const handleTruexAdEvent = useCallback( event: TruexAdEvent) => { switch (event.type) { case TruexAdEventType.AD_COMPLETED: case TruexAdEventType.AD_ERROR: case TruexAdEventType.NO_ADS_AVAILABLE: case TruexAdEventType.USER_CANCEL_STREAM: // Ad finished, resume content onTruexAdFinished(); break; case TruexAdEventType.AD_FREE_POD: // User earned ad credit onTruexAdFreePod() break; } }, [ onTruexAdFinished, onTruexAdFreePod ] ); // Parse the ad parameters from the VAST node const adParameters = JSON.parse(truexAdInfo.adParameters); return ( ); } export default TruexAdContainer; ``` ### Component Props The `TruexAd` component accepts the following props: #### Required Props * **`adParameters`**: An object containing the ad configuration. This object is obtained by parsing the JSON content of the `` node from the VAST/VMAP response. * **`onAdEvent`**: A callback function to handle ad lifecycle events. ```tsx // Parse the JSON string from the node in your VAST response const adParams = JSON.parse(adParametersStringFromVast); ``` #### Optional Props * **`options`**: Configuration options for the renderer. ```tsx import { TruexAdRendererOptions } from '@truex/ad-renderer-vega'; const options: TruexAdRendererOptions = { supportsUserCancelStream: true, appId: 'my-firetv-app', enableWebViewDebugging: __DEV__ }; ``` ### Configuration Options The `options` prop accepts a `TruexAdRendererOptions` object: ```typescript type TruexAdRendererOptions = { supportsUserCancelStream?: boolean, appId?: string, enableWebViewDebugging?: boolean, }; ``` *** #### `supportsUserCancelStream` * **Type**: `boolean` * **Default**: `false` * **Description**: Enables the `USER_CANCEL_STREAM` terminal event. When enabled, users can exit the entire stream from within the ad experience. ```tsx ``` *** #### `appId` * **Type**: `string` * **Default**: `undefined` * **Description**: Your application identifier for reporting and analytics. ```tsx ``` *** #### `enableWebViewDebugging` * **Type**: `boolean` * **Default**: `false` * **Description**: Enables WebView debugging tools. Should only be enabled in development builds. ```tsx ``` ## Runtime Version Information Access the TrueX Ad Renderer version at runtime: ```tsx import { buildInfo } from '@truex/ad-renderer-vega'; console.log(`Package: ${buildInfo.name}`); // Package: @truex/ad-renderer-vega console.log(`Version: ${buildInfo.version}`); // Version: 0.7.1 console.log(`Date: ${buildInfo.date}`); // Date: 2025-12-04T16:06:55.046Z ``` ## Understanding the Integration Flow Before diving into code, it's helpful to understand the integration workflow: 1. **Video Playback** - Your app plays video content 2. **Ad Break Detected** - Video player encounters ad break (pre-roll/mid-roll) 3. **Pause Video & Show TrueX Ad** - Pause playback, render TrueX component, hide controls 4. **User Interaction** - User engages with interactive ad experience 5. **Terminal Event Received** - Ad completion, error, or cancellation 6. **Resume Video Playback** - Hide ad, resume video, skip remaining ads if credit earned ## Key Integration Points Your integration will involve: 1. **Ad Break Detection**: Identifying when to show TrueX ads 2. **Component Rendering**: Displaying the `` component 3. **Event Handling**: Responding to ad lifecycle events 4. **Video Control**: Managing video playback state 5. **Ad Credit Tracking**: Honoring earned ad-free viewing ### What if I'm using a different video player? The TrueX Ad Renderer is video-player agnostic. You'll need to integrate it with your specific player's API for pausing/resuming playback. ### Is this only for FireTV? The `@truex/ad-renderer-vega` package is specifically designed for Amazon Vega (FireTV). Other platforms have their own integration packages: * [Web/HTML Integration](/platforms/web/) * [Roku Integration](/platforms/roku/) * [Android TV & Mobile Integration](/platforms/android/) * [tvOS Integration](/platforms/tvos/) --- --- url: /infillion-ads-integration-docs/platforms/ios.md --- # Mobile Integration TrueX Ad Renderer for mobile provides native iOS and Android integration for smartphones and tablets. ## Overview TrueX mobile integrations support both iOS and Android platforms with native SDKs. ## Supported Platforms ### iOS * iPhone (iOS 13.0+) * iPad (iOS 13.0+) ### Android * Android smartphones (Android 5.0+) * Android tablets (Android 5.0+) ## Documentation For complete integration documentation, please refer to: ### iOS * [iOS Integration Guide](https://github.com/socialvibe/truex-mobile-integrations/blob/master/iOS-DOCS.md) ### Android * [Android Integration Guide](https://github.com/socialvibe/truex-android-integrations/blob/develop/DOCS.md) ## Quick Start ### iOS ```ruby # Podfile pod 'TruexAdRenderer-iOS' ``` ```swift let truexAdRenderer = TruexAdRenderer() truexAdRenderer.initialize(vastConfigUrl: vastUrl) { event in // Handle events } ``` ### Android ```gradle dependencies { implementation 'com.truex:TruexAdRenderer-Android:x.x.x' } ``` ```kotlin val truexAdRenderer = TruexAdRenderer(context) truexAdRenderer.init(vastConfigUrl) { event -> // Handle events } ``` ## Repositories Access the official mobile integration repositories: * [TrueX Mobile Integrations](https://github.com/socialvibe/truex-mobile-integrations) * [TrueX Android Integrations](https://github.com/socialvibe/truex-android-integrations) ## Migration Notice Full mobile integration documentation will be migrated to this site in a future update. For now, please refer to the GitHub repositories linked above. --- --- url: /infillion-ads-integration-docs/platforms.md --- # Supported Platforms Infillion Ads (TrueX/IDVx) can be integrated across multiple platforms. Choose your platform below to view specific integration documentation. ## TV Platforms * **[Vega (FireTV)](./vega/)** * React Native integration for Amazon Vega (Kepler) OS * Full TypeScript support * **[Roku](./roku/)** * Native BrightScript integration * Optimized for Roku streaming devices * **[Android TV](./android/)** * Native Android integration * Supports both Android TV and Fire TV (Android-based) * **[tvOS](./tvos/)** * Native Swift/Objective-C integration * For Apple TV devices ## Mobile & Web * **[iOS](./ios/)** * Native Swift/Objective-C integration * For iPhone and iPad * **[Web/HTML](./web/)** * Browser-based integration * Uses TAR HTML and VPAID standards --- --- url: /infillion-ads-integration-docs/overview/getting-started-interactive-video.md --- ### How Interactive Video Works **Interactive Video** delivers **interactive video ads that start automatically** without requiring user opt-in. These ads maintain interactivity throughout their duration (typically 30 seconds) and **play inline with other ads** in the break sequence. After an Interactive Video ad completes, playback continues to the next ad in the pod. **Key features:** * **Automatic start** - Begins playing without opt-in * **Interactive throughout** - Users can interact with ad content during playback * **Plays inline** - Completes and continues to the next ad in sequence --- --- url: /infillion-ads-integration-docs/overview/getting-started-truex.md --- ### Product Flow **TrueX** presents users with an **interactive choice card** where they choose between engaging with branded content or watching standard video ads. When users opt in and complete the interactive experience, they earn an **ad credit that skips all remaining ads** in the pod, creating a win-win: viewers get ad-free content, and advertisers get highly engaged audiences. **Key features:** * **Opt-in via choice card** - Users actively choose to engage * **Engagement requirements** - Users must spend 30 seconds and interact at least once to earn credit * **Skips entire ad break** - Successful engagement bypasses all remaining ads in the pod Upon completion, the renderer signals a `adFreePod` event, indicating that remaining linear ads should be skipped. There are two distinct product flows supported by `TruexAdRenderer`: Sponsored Stream (full-stream ad-replacement) and Sponsored Ad Break (mid-roll ad-replacement). In a Sponsored Ad Break flow, once the user hits a mid-roll break with a **TrueX** tag flighted, they will be shown a "choice-card" offering them the choice between watching a normal set of video ads or a fully interactive **TrueX** ad: ![choice card](/assets/images/choice_card.png) ***Fig. A** example **TrueX** mid-roll choice card* If the user opts for a normal ad break, or if the user does not make a selection before the countdown timer expires, the **TrueX** UI will close and playback of normal video ads can continue as usual. If the user opts to interact with **TrueX**, an interactive ad unit will be shown to the user: ![ad](/assets/images/ad.png) ***Fig. B** example **TrueX** interactive ad unit* The requirement for the user to "complete" this ad is for them to spend at least the allotted time on the unit and for at least one interaction (e.g. navigating anywhere through the ad). ![true attention timer example](/assets/images/true-attention-timer-example.png) ***Fig. C** example **TrueX** attention timer* Once the user fulfills both requirements, a "Watch Your Show" button will appear in the bottom right, which the user can select to exit the **TrueX** ad. Having completed a **TrueX** ad, the user will be returned directly to content, skipping the remaining ads in the current ad pod. The Sponsored Stream flow is quite similar. In this scenario, a user will be shown a choice-card in the pre-roll: ![choice card](/assets/images/choice_card.png) ***Fig. D** example **TrueX** pre-roll choice card (full-stream replacement)* Similarly, if the user opts-in and completes the **TrueX** ad, they will be skipped over the remainder of the pre-roll ad break. However, every subsequent mid-roll break in the current stream will also be skipped over. In this case instead of the regular pod of video ads, the user will be shown a "hero card" (also known as a "skip card"): ![skip card](/assets/images/skip_card.png) ***Fig. E** example **TrueX** mid-roll skip card* This messaging will be displayed to the user for several seconds, after which they will be returned directly to content. ## High-level Integration Process The Infillion Integration is composed of three high level steps - flighting our tag to your Ad server, enabling the rendering of Infillion interactive Ads in your video player, and crediting users for viewing a Infillion Ad (Ad skipping logic). :::steps 1. Tag flighting VAST tags are flighted at the top of every midroll Ad pod. This enables both the fetching of Infillion interactive Ads, and skipping of Ad pods in the event a viewer has already completed a Infillion Ad. Our tag does not represent a single campaign or advertiser, but instead is an always-on tag that changes based on demand for a particular user. Tag type differs based on the selected integration type. VPAID (for desktop) & VAST companion tags are the most common Flighting Instructions 2. Start TruexAdRenderer. As a part of our partnership with Innovid - Infillion choice card & interactive ad rendering support are provided through the Innovid SDK and don’t require any special development effort from the publisher. 3. Credit users with free Ad pods when they complete a Infillion Ad. * When users complete a Infillion Ad, we need to deliver their reward (skipped Ad breaks). This is typically handled by the publisher. * When a user completes a Infillion Ad, our SDK fires …. at which point the publisher is responsible for resuming playback of the main content stream. A more in depth guide on Ad skipping logic can be found in the technical documentation. ::: ## Flighting Instructions: Once your team is ready to start testing Infillion Ads, our team will provide a test tag to flight to your Ad server. This test tag allows us to deliver test traffic to your Ad placement either in your staging environment, or a public placement with very low test demand allocation. This allows a limited number of users, including our QA team, to test your integration before it goes into production with real campaigns. Exact flighting instructions vary based on the specific Ad server & version your company uses. Below are general guidelines for flighting Infillion tags on a wide variety of Ad servers. Notes on tag flighting: > \[!IMPORTANT] > The Infillion TrueX tag should only be flighted to the first position in a given Ad pod. It will not function otherwise. > \[!NOTE] > In order to ensure that TrueX choice cards don’t reduce ad slots in the case the viewer decides not to interact with a Infillion Ad, increase the max number of Ads in pods which include a Infillion Ad by 1. For instance, if your normal commercial break pattern for a pod has a maximum of 3, 30 second Ads (90 seconds total), increase to a maximum of 4, 30 second Ads (120 seconds total). If a user spends 30 seconds in the Infillion choice card, a 120 second pod limit means they’ll still see the intended 3x 30 second Ads rather than being cut off. [truex_product]: https://infillion.com/products/infillion-truex/ [interactive_video_product]: https://infillion.com/products/infillion-interactive-video/ --- --- url: /infillion-ads-integration-docs/overview/vast-tags.md --- ## VAST Tag Types Infillion uses two types of VAST tags for both TrueX and Interactive Video products. The tags differ in how the `adParameters` JSON payload is embedded in the VAST XML. ### "Generic" Tag The `adParameters` are embedded directly as a JSON string within the `` node: **TrueX "Generic" Tag:** ``` https://get.truex.com/{placement_hash}/vast/generic?{ad_request_parameters} ``` **Interactive Video "Generic" Tag:** ``` https://get.truex.com/{placement_hash}/vast/idvx/generic?{ad_request_parameters} ``` **VAST Structure:** ```xml trueX 00:00:30 ``` ### "Companion" Tag The `adParameters` are embedded in a companion ad's `` node as base64-encoded json string: **TrueX "Companion" Tag:** ``` https://get.truex.com/{placement_hash}/vast/companion?{ad_request_parameters} ``` **IDVx "Companion" Tag:** ``` https://get.truex.com/{placement_hash}/vast/idvx/companion?{ad_request_parameters} ``` **VAST Structure:** ```xml trueX 00:00:30 ``` ### Differentiating TrueX and IDVx The `` node value identifies the ad type: * **TrueX ads**: `trueX` * **IDVx ads**: `IDVx` Both tag types (Generic and Companion) work with both TrueX and IDVx products. --- --- url: /infillion-ads-integration-docs/platforms/roku.md --- > \[!TIP] Reference App > For a complete working example, check out the **[TrueX Roku Reference App](https://github.com/socialvibe/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](#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`](#init) followed by [`start`](#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](#truexadrenderer-output-events----main-flow) and [`TruexAdRenderer` Output Events -- Informative](#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** ad * `userCancelStream`: the user intends to exit the current stream entirely * `noAdsAvailable`: there were no **TrueX** ads available to the user * `adError`: 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 ``` 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 : "", slotType : "", supportsUserCancelStream : , logLevel : , channelWidth : , channelHeight : } ``` 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 to `response.ads.breaks[0].ads[0].adParameters`. * `slotType`: the type of the current ad pod, `PREROLL` or `MIDROLL` * `supportsUserCancelStream`: optional -- set to `true` to enable the [userCancelStream](#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 ##### 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: ![trueX ad parameters example](http://ctv.truex.com/docs/truexadrenderer_adparameters_example.png) 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](#terminal-events) before taking any more action, while keeping track of whether or not the [`adFreePod`](#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`](#adstarted) event. `adFreePod` and other events may fire after this point, depending on the user's choices, followed by one of the [terminal events](#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 : ' } ``` 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 : ' } ``` This is a [terminal event](#terminal-events). 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 : ' } ``` This is a [terminal event](#terminal-events). 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](#terminal-events). 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](#terminal-events), 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](#terminal-events), and is only enabled when the `supportsUserCancelStream` property is set to `true` when triggering the [`init`](#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`](#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 : ' } ``` 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 to `true` if this was actively selected by the user, `false` if 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](#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 : "", ' videoName : "", ' url : "" ' } ``` 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 started * `firstQuartile`: A video has reached its first quartile * `secondQuartile`: A video has reached its second quartile * `thirdQuartile`: A video has reached its third quartile * `completed`: A video has reached completion The parameters for this event are: * `subType`: The subType of the emitted video event * `videoName`: The name of the video that emitted the event, if available * `url`: The source URL of the video that emitted the event, if available --- --- url: /infillion-ads-integration-docs/platforms/tvos.md --- ## Overview In order to support interactive ads on tvOS, true\[X] has created a renderer library that can renderer true\[X] ads natively, which interfaces with a hosting app, as well as its existing ad server and content delivery mechanism (e.g. SSAI). With this library, the host player app can defer to the TruexAdRenderer when it is required to display a true\[X] ad. For simplicity, publisher implemented code will be referred to as "app code" while true\[X] implemented code will be referred to as "renderer code". true\[X] will provide an Objective-C `TruexAdRenderer` library that can be loaded into the app. This library will offer a class, `TruexAdRenderer`, that will need to be instantiated, initialized and given certain commands (described below in [TruexAdRenderer Methods](#truexadrenderer-methods)) by the app code. It will also contain a singleton of shared constants, `TruexConstants`. At this point, the renderer code will take on the responsibility of requesting ads from true\[X] server, creating the native UI for the true\[X] choice card and interactive ad unit, as well as communicating events to the app code when action is required. The app code will still need to parse out the SSAI ad response, detect when a true\[X] ad is supposed to display, pause the stream, instantiate `TruexAdRenderer` and handle any events emitted by the renderer code. It will also need to call pause, resume and stop methods on the `TruexAdRenderer` when certain external events happen, like if the app is backgrounded or if the user has requested to exit the requested stream via back buttons. It will also need to handle skipping ads in the current ad pod, if it is notified to do so. ### When to show true\[X] Upon receiving an ad schedule from your SSAI service, you should be able to detect whether or not true\[X] is returned in any of the pods. true\[X] ads should have `apiFramework` set to `VPAID` or `truex`. SSAI 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 true\[X] payload will be encapsulated as part of a companion payload on the returned VAST ad. Please work with your true\[X] point of contact if you have difficulty identifying the right approach to detecting the true\[X] placeholder, which will be the trigger point for the ad experience. Once the player reaches a true\[X] placeholder, it should pause, instantiate the `TruexAdRenderer` and immediately call [`init`](#initwithurl) followed by [`start`](#start). Alternatively, you can instantiate and `init` the `TruexAdRenderer` in preparation for an upcoming placeholder. This will give the `TruexAdRenderer` more time to complete its initial ad request, and will help streamline true\[X] 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, in the form of calling delegate methods (see [`TruexAdRendererDelegate` Methods -- Main Flow](#truexadrendererdelegate-methods----main-flow) and [`TruexAdRendererDelegate` Methods -- Informative](#truexadrendererdelegate-methods----informative)) One of the first events you will receive is [`onAdStarted`](#onadstarted). This notifies the app that the renderer has received an ad for the user and has started to show the unit to the user. The app does not need to do anything in response, however it can use this event to facilitate a timeout. If an `onAdStarted` event has not fired within a certain amount of time after calling `start`, the app can call `stop` on the renderer and proceed to normal video ads. At this point, the app must listen for the renderer's [terminal events](#terminal-events), while paying special attention to the [`onAdFreePod`](#onadfreepod) event. A *terminal event* signifies that the renderer is done with its activities and the app may now resume playback of its stream. The `onAdFreePod` event signifies that the user has earned a credit with true\[X] and all linear video ads remaining in the current pod should be skipped. If the `onAdFreePod` event did not fire before a terminal event is emitted, the app should resume playback without skipping any ads, so the user receives a normal video ad payload. #### Terminal Events The delegate methods representing *terminal events* are: * [`onAdCompleted`](#onadcompleted): the user has exited the true\[X] ad * [`onUserCancelStream`](#onusercancelstream): the user intends to exit the current stream entirely * [`onNoAdsAvailable`](#onnoadsavailable): there were no true\[X] ads available to the user * [`onAdError`](#onaderror): the renderer encountered an unrecoverable error It's important to note that the player should not immediately resume playback once receiving the `onAdFreePod` 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 app code. The SSAI API should provide enough information for the app to determine where the current pod end-point is, and the app, when appropriate, should fast-forward directly to this point when resuming playback. ## TruexAdRenderer tvOS API This is an outline of public `TruexAdRenderer` methods and `TruexAdRendererDelegate` methods (referred to as events). ### Adding `TruexAdRenderer` to Your Project The easiest way to add `TruexAdRenderer` is via CocoaPods. The renderer will be maintained and distributed on Github. 1. Add the following Podspec repositories to your Podfile: ```ruby source 'https://github.com/CocoaPods/Specs.git' source 'https://github.com/socialvibe/cocoapod-specs.git' source 'https://github.com/Innovid/cocoapods-spec.git' source 'https://github.com/YOU-i-Labs/YouiTVAdRenderer-CocoaPod.git' ``` **Note:** Two of `TruexAdRenderer`'s dependencies, from `Innovid` and `YOU-i-Labs`, are not available in the public specs repo. 2. Add the TruexAdRenderer pod to your target: ```ruby target 'MyApp' do use_frameworks! pod 'TruexAdRenderer', '~> 3.6' # [...] end ``` **Note:** `TruexAdRenderer` and some of its dependencies are delivered as frameworks -- not as static libraries. As such, please include the `use_frameworks!` line in your target definition. ### TruexAdRenderer Methods #### `initWithUrl` ```objective-c - (_Nullable id)initWithUrl:(NSString* _Nullable)creativeUrl adParameters:(NSDictionary* _Nonnull)adParameters slotType:(NSString* _Nonnull)slotType; ``` This method should be called by the app code in order to initialize the `TruexAdRenderer`. The renderer will parse out the `creativeURL`, `adParameters` and `slotType` passed to it and make a request to the true\[X] 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 [`onFetchAdComplete`](#onfetchadcomplete) 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: * `creativeURL`: true\[X] asset url returned by SSAI. In the example of Uplynk, this would correspond to `response.ads.breaks[0].ads[0].creative` * `adParameters`: AdParameters as returned by SSAI. In the example of Uplynk, this would correspond to `response.ads.breaks[0].ads[0].adParameters` * `slotType`: the type of the current ad pod, `PREROLL` or `MIDROLL` #### `start` ```objective-c - (void)start:(UIViewController* _Null_unspecified)baseViewController; ``` This method should be called by the app code when the app is ready to display the true\[X] unit to the user. This can be called anytime after the unit is initialized. The app should have as much extraneous UI hidden as possible, including player controls, status bars and soft buttons/keyboards. After calling `start`, the app code should wait for a [terminal event](#terminal-events) before taking any more action, while keeping track of whether or not the [`onAdFreePod`](#onadfreepod) 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 true\[X] unit to the user in a new `ViewController` presented on the `baseViewController` and then fire the [`onAdStarted`](#onadstarted) event. `onAdFreePod` and other events may fire after this point, depending on the user's choices, followed by one of the [terminal events](#terminal-events). The parameters for this method call are: * `baseViewController`: The `viewController` that `TruexAdRenderer` should present its `ViewController` to. The `baseViewController` should cover the entire screen. #### `stop` ```objective-c - (void)stop; ``` The `stop` method is only called when the app needs the renderer to immediately stop and destroy all related resources. Examples include: * the user backs out of the video stream to return to the normal app UI * there was an unrelated error that requires immediate halt of the current ad unit * the app code has reached a custom timeout waiting for either the [`onFetchAdComplete`](#onfetchadcomplete) or [`onAdStarted`](#onadstarted) events The `TruexAdRenderer` instance should not be used again after calling `stop` -- please remove all references to it afterwards. In contrast to `pause`, there is no way to resume the ad after `stop` is called. #### `pause` ```objective-c - (void)pause; ``` `pause` is required whenever the app needs to pause the true\[X] unit (including all video, audio, and timers). #### `resume` ```objective-c - (void)resume; ``` `resume` should be called when the app is ready for a previously paused true\[X] unit to resume. ### `TruexAdRendererDelegate` Methods -- Main Flow The following `TruexAdRendererDelegate` methods signal the main flow of the `TruexAdRenderer` and may require action by the host app. The `TruexAdRendererDelegate` protocol can be found in `TruexShared.h`. #### `onFetchAdComplete` ```objective-c - (void)onFetchAdComplete; ``` This method is marked as **`@optional`** in the `TruexAdRendererDelegate` protocol. This method is called in response to the `init` method when the true\[X] ad request has successfully completed and the ad is ready to be presented. The host app 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 app code shows a loading indicator while waiting for `onFetchAdComplete`. Then, either the event is received (and the app can call `start`) or a specific timeout is reached (and the app can call `stop` 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 `onFetchAdComplete` is received before the mid-roll slot is encountered, then the app can call `start` to immediately present the true\[X] ad. If not, the app can wait for a specific timeout (if not already reached, in case the user has seeked to activate the mid-roll) before calling `stop` on the renderer and resuming playback with normal video ads. #### `onAdStarted` ```objective-c - (void)onAdStarted:(NSString*)campaignName; ``` This event will fire in response to the `start` method when the true\[X] UI is ready and has been added to the view hierarchy. The parameters for this method call are: * `campaignName`: The name of the ad campaign available to the user (e.g. "*Storebought Coffee - Sample Video Ad #1 - Q1 2017*") #### `onAdCompleted` ```objective-c - (void)onAdCompleted:(NSInteger)timeSpent; ``` This is a [terminal event](#terminal-events). This event will fire when the true\[X] unit is finished with its activities -- at this point, the app should resume playback and remove all references to the `TruexAdRenderer` instance. Here are some examples where `onAdCompleted` will fire: * The user opts for normal video ads (not true\[X]) * The choice card countdown runs out * The user completes the true\[X] ad unit * After a "skip card" has been shown to a user for its duration The parameters for this method call are: * `timeSpent`: The amount of time (in seconds) the user spent on the true\[X] unit #### `onAdError` ```objective-c - (void)onAdError:(NSString*)errorMessage; ``` This is a [terminal event](#terminal-events). This event will fire when the true\[X] unit has encountered an unrecoverable error. The app code should handle this the same way as an `onAdCompleted` event -- resume playback and remove all references to the `TruexAdRenderer` instance. #### `onNoAdsAvailable` ```objective-c - (void)onNoAdsAvailable; ``` This is a [terminal event](#terminal-events). This event will fire when the true\[X] unit has determined it has no ads available to show the current user. The app code should handle this the same way as an `onAdCompleted` event -- resume playback and remove all references to the `TruexAdRenderer` instance. #### `onAdFreePod` ```objective-c - (void)onAdFreePod; ``` This event will fire when the user has earned a credit with true\[X]. The app code should notate that this event has fired, but should not take any further action. Upon receiving a [terminal event](#terminal-events), if `onAdFreePod` was fired, the app should skip all remaining ads in the current slot. If it was not fired, the app should resume playback without skipping any ads, so the user receives a normal video ad payload. #### `onUserCancelStream` ```objective-c - (void)onUserCancelStream; ``` This is a [terminal event](#terminal-events), and is marked as **`@optional`** in the `TruexAdRendererDelegate` protocol. Implementing this delegate method will enable the renderer to fire this event when the user intends to exit the stream entirely. The app, 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 the app code does not implement this delegate method, then the renderer will emit an [`onAdCompleted`](#onadcompleted) event instead. ### `TruexAdRendererDelegate` Methods -- Informative All following delegate methods are marked as **`@optional`** in the `TruexAdRendererDelegate` protocol, and are used mostly for tracking purposes -- no action is generally required. #### `onOptIn` ```objective-c - (void)onOptIn:(NSString*)campaignName adId:(NSInteger)adId; ``` This method is marked as **`@optional`** in the `TruexAdRendererDelegate` protocol. This event will fire if the user selects to interact with the true\[X] interactive ad. Note that this event may be fired multiple times if a user opts in to the true\[X] interactive ad and subsequently backs out. The parameters for this event are: * `campaignName`: The name of the ad campaign. * `adID`: The ad ID. #### `onOptOut` ```objective-c - (void)onOptOut:(BOOL)userInitiated; ``` This method is marked as **`@optional`** in the `TruexAdRendererDelegate` protocol. 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 to `true` if this was actively selected by the user, `false` if the user simply allowed the choice card countdown to expire. #### `onSkipCardShown` ```objective-c - (void)onSkipCardShown; ``` This method is marked as **`@optional`** in the `TruexAdRendererDelegate` protocol. This event will fire anytime a "skip card" is shown to a user as a result of completing a true\[X] Sponsored Stream interactive ad in an earlier pre-roll. #### `onUserCancel` ```objective-c - (void)onUserCancel; ``` This method is marked as **`@optional`** in the `TruexAdRendererDelegate` protocol. This event will fire when a user backs out of the true\[X] 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 true\[X] interactive ad. The user will be subsequently taken back to the Choice Card (with the countdown timer reset to full). Note that after a `onUserCancel`, the user can opt-in and engage with an interactive ad again, so more `onOptIn` or `onOptOut` events may then be fired. --- --- url: /infillion-ads-integration-docs/platforms/web.md --- ## Overview In order to support interactive ads on on mobile and desktop web sites, as well as web-enabled smart TVs and game consoles, Infillion has created the npm package `@truex/ad-renderer` to add to host web sites and web apps that can renderer TrueX interactive ads and leverage your app's existing ad server and content delivery mechanism (e.g. SSAI). For simplicity, publisher implemented code will be referred to as "host app code" while TrueX implemented code will be referred to as "renderer code" or TAR. The intended audience for this document is the host application developer who has to integrate to the TrueX renderer. The npm library provides a class, `TruexAdRenderer`, that will need to be instantiated, initialized, and displayed by the host app code, as described below in [TruexAdRenderer API](#truexadrenderer-api). 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 host app code when action is required. The host app code will still need to parse out the 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. ## How to use TruexAdRenderer ### Setup The TrueX ad renderer is available as an `npm` module via the `@truex/ad-renderer` package. For the typical web based development around a `package.json` project file, you add the TrueX dependency as follows: ```sh npm add @truex/ad-renderer ``` this will add an entry in the `"dependencies"` section in the `package.json` file, something like: ```json "dependencies": { "@truex/ad-renderer": "1.12.5", ``` You then build and run their web app like usual, e.g. invoking `npm start` for webpack-based projects. Alternatively, if you prefer you can refer to the TAR library directly in a script tag, e.g.: ```html ``` or if you want to always refer to the latest version: ```html ``` ### When to show a TrueX Ad Upon receiving an ad break from your ad provider, you should be able to detect whether or not TrueX is returned in any of the pods. In a typical [VAST-based](https://www.iab.com/guidelines/vast) ad integration (for example Google Ad Manager or FreeWheel), the `` element within the ad's VAST tag should have the value of `trueX`. A standard VAST ad response from TrueX contains a JSON blob in the `` field and a placeholder video in the `` field. Work with your TrueX contact if you have questions about interpreting our ad payloads. Ad provider 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 / IMA, the TrueX payload will be encapsulated as part of a companion payload on the returned VAST ad. Please work with your Infillion 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 a `TruexAdRenderer` instance and invoke the [`init`](#init) and [`start`](#start) methods. Alternatively, you can call `init` on 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. ### Code Sample Once a TrueX ad is detected, the renderer needs to be created and displayed. The following code provides an example of the typical approach of integrating to TAR. For example, it shows how you can call the `init` and `start` methods to get the ad displayed, and to listen for the key ad events a client publisher needs to respond to, ultimately to control how to resume the main video. ```javascript import { TruexAdRendererCTV, TruexAdEventType } from '@truex/ad-renderer'; // or TruexAdRendererDesktop or TruexAdRendererMobile, as appropriate ... videoController.pause(); let adFreePod = false; const adParameters = JSON.parse(adParametersJsonString); const tar = new TruexAdRendererCTV(adParameters); // or TruexAdRendererDesktop or TruexAdRendererMobile, as appropriate tar.subscribe(handleTruexAdEvent); await tar.init(); await tar.start(); ... function handleTruexAdEvent(event) { switch (event.type) { case TruexAdEventType.AD_FREE_POD: adFreePod = true; // the user did sufficient interaction for an ad credit break; case TruexAdEventType.AD_ERROR: console.error('ad error: ' + event.errorMessage); resumePlayback(); break; case TruexAdEventType.NO_ADS_AVAILABLE: case TruexAdEventType.AD_COMPLETED: // Ad is not available, or has completed. Depending on the adFreePod flag, either the main // video or the ad fallback videos are resumed. resumePlayback(); break; } } function resumePlayback() { if (adFreePod) { // The user has the credit, resume the main video after the ad break. videoController.skipAdBreak(); videoController.resumeMainVideo(); } else { // Continue with playing the remaining fallback ad videos in the ad break. videoController.skipCurrentAd(); videoController.resumeAdBreak(); } } ``` ### Handling Ad Events Once the renderer has been initialized and started, it will begin to emit ad events (see [`TruexAdRenderer` Ad Events](#truexadrenderer-ad-events)). These ad events that can be monitored via the [`subscribe`](#subscribe) method as shown in the above code sample. One of the first events you will receive is `adStarted`. This notifies the host app that the renderer has received an ad for the user and has started to show the unit to the user. The app 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 app can proceed to normal video ads. At this point, the host app 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 app 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 ad break should be skipped. If the `adFreePod` event did not fire before a terminal event is emitted, the app 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 ad * `userCancelStream`: the user intends to exit the current stream entirely * `noAdsAvailable`: there were no TrueX ads available to the user * `adError`: 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 host app code. The ad provider SDKs like Google IMA should provide enough information for the host app to determine where the current pod end-point is, and the app, when appropriate, should fast-forward directly to this point when resuming playback. ## TruexAdRenderer API Here we describe the essential methods of the `TruexAdRenderer` class, as well as ad events that can be listened for. Note that there are actually 3 possible classes to use: ```javascript TruexAdRendererCTV TruexAdRendererDesktop TruexAdRendererMobile ``` You should use the appropriate one for your platform, so as to allow the correct ad tracking to be used. If you use the (now deprecated) `TruexAdRenderer` class, that maps to `TruexAdRendererCTV` ### TruexAdRenderer Methods #### `constructor` ```javascript /** * Derives a url for a query to download a vast config object. * * @param {*} params uses as a url if a string, or else an object with a vast_config_url field, or else as * aa vast config object directly. * * @param {Object} options for optional overrides * * @param {String} options.showLoadingSpinner if true (default), a loading indicator is shown while the * choice card display elements are loading, i.e. while waiting for image assets to load, etc. * * @param {String} options.userAdvertisingId The id used for user ad tracking. * If omitted, the existing network_user_id in the vast config url is used. * If that is missing, the fallbackAdvertisingId is used. * * @param {String} options.fallbackAdvertisingId The id used for user ad tracking when no explicit user ad id is * provided or available from the platform. By default it is a randomly generated UUID. Specifying allows one to * control if limited ad tracking is truly random per ad, or else shared across multiple TAR ad sessions. * * @param {String} options.supportsUserCancelStream if true, enables the userCancelStream event for back actions * from the choice card. Defaults to false, which means back actions cause optOut/adCompleted events instead. * * @param {String} options.choiceCardUrlOverride url to load the choice card script from. * * @param {String} options.containerUrlOverride url to load the container for the engagement ad. * * @param {String} options.optOutTrackingEnabled override value to set opt out tracking * * @param {String} options.appId set the application id/ package name for tracking * * @param {String} options.useWebMAF if true and running on the PS4, all ad videos are played via the WebMAF API, * so as to work around any WebMAF load failures due to the creation of HTML5 Video elements. * * @param {Object} options.keyMapOverrides provides a map keyed by input actions that describe the key codes * to use to map key events to input actions. This will override the platform's built in support, and is intended * to allow the use of the TruexAdRenderer on unsupported platforms where the key mapping has not been * implemented yet in TAR itself. E.g. * @example * { * select: [32, 13], // space or enter * back: [27, 8, 127], // esc or backspace or del * moveUp: 38, * moveDown: 40, * moveLeft: 37, * moveRight: 39 * } */ constructor(parameters, options) ``` The usual case is to construct the renderer with the adParameters json, e.g. `const tar = new TruexAdRendererCTV(adParameters)`. #### `init` ```javascript /** * Queries for the vast config result * * @returns {Promise} resolves to the resulting the vast config result object */ function init() ``` This should be called by the host app code in order to initialize the `TruexAdRenderer` instance. The renderer will use the VAST config url passed to it in the constructor 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`. #### `start` ```javascript /** * Starts the choice card and engagement flow * * @param {Object} [vastConfig] optional defaults to the value obtained via the init() call. * * @param {HTMLElement} [parentElement] parent DOM element to add the ad overlay/choice card to. * Defaults to document.documentElement. * * @return {Promise} promise that completes when the choice card loads, resolves to the div holding the ad overlay. */ function start(vastConfig, parentElement) ``` This should be called by the host app code when the app is ready to display the TrueX unit to the user. This can be called anytime after the renderer is initialized. The host app should have as much extraneous UI hidden as possible, including player controls, status bars and soft buttons/keyboards. On constrained devices, especially connected TV devices, it is preferrable to also unload the main video if possible, resuming it after the ad unit is completed. After calling `start`, the host app code should wait for a [terminal event](#terminal-events) before taking further actions, while keeping track of whether the [`adFreePod`](#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 ad unit to the user in a new component (added to the `TruexAdRenderer` parent component) and then fire the [`adStarted`](#adstarted) event. `adFreePod` and other events may fire after this point, depending on the user's choices, followed by one of the [terminal events](#terminal-events). #### `stop` ```javascript /** * Allow ads to be forcibly closed by the host app or test script. * (Needs to be possible if the app needs to reset, otherwise back actions can be permanently * blocked if the ad is not cleaned up.) */ function stop() ``` The `stop` method is only called when the host app needs the renderer to immediately stop and destroy all related resources. Examples include: * the user backs out of the video stream to return to the normal app UI * there was an unrelated error that requires immediate halt of the current ad unit * the app code has reached a custom timeout waiting for either the [`adFetchCompleted`](#adfetchcompleted) or [`adStarted`](#adstarted) events The renderer instance should not be used again after calling `stop` -- please remove all references to it afterwards. #### `pause` ```javascript /** * Pauses an ad if the hosting app needs to suspend/resume itself. * I.e. Any ad videos are paused and countdowns suspended. */ function pause() ``` #### `resume` ```javascript /** * Resumes a previously paused ad. I.e. any paused ad videos are resumed, as well as suspended countdowns. */ function resume() ``` #### `subscribe` ```javascript /** * Adds a callback subscription to receive ad events. * * An ad event object as a type field to describe which event has occurred (i.e. one of * the {@link adEvents} constants), along with other optional data fields depending on the event. * * @param type Indicates the type of event to subscribe to. If empty or if a single callback function, * then the function is invoked on all ad events. * @param callback Describes the callback when the first arg is the type string. */ function subscribe(type, callback) ``` Use `subscribe` to listen to ad events emitted from the renderer. The key ones the host app should listen to are: ```javascript adFreePod adCompleted noAdsAvailable adError ``` To listen to all ad events, just pass in a single callback as the argument, e.g. `tar.subscribe(handleAdEvent)`. To listen to a particular ad event, pass in the type to listen to and the callback, e.g. `tar.subscribe('adCompleted', handleAdCompleted)` The ad event names are available as constants via the renderer's `adEvents` field, e.g. `tar.adEvents.adFreePod` #### `unsubscribe` ```javascript /** * Removes the callback subscription. * * @param type Indicates the type of event to unsubscribe from. If empty or if a single callback function, * then the callback is unsubscribed subscribed for all ad events. * @param callback Describes the callback when the first arg is the type string. */ function unsubscribe(type, callback) ``` ### `TruexAdRenderer` Ad Events #### Main Ad Events The following events signal the main flow of the `TruexAdRenderer` and may require action by the host app: #### `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 app 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 host app code shows a loading indicator while waiting for `adFetchCompleted`. Then, either the event is received (and the app can call `start`) or a specific timeout is reached (and the app can discard the `TruexAdRenderer` instance 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 app can call `start` to immediately present the TrueX ad. If not, the app 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` instance and resuming playback with normal video ads. #### `adStarted` This event fires after the `start` call, when the TrueX UI is being constructed and connected to the web page. #### `adDisplayed` This event fires once the TrueX UI is loaded and visible, i.e. all image assets are loaded, etc. This is useful if the host app is implementing its own loading indiciator UX (i.e. its own loading spinner), and needs to know when the ad UI is actually ready to be disabled without delays. #### `adCompleted` This is a [terminal event](#terminal-events). This event will fire when the TrueX unit is finished with its activities \-- at this point, the app should resume playback and remove the TrueX ad renderer from its UI Here are some examples where `adCompleted` will fire: * The user opts for normal video ads (not TrueX) * The choice card timeout runs out * The user completes the TrueX ad unit * After a "skip card" has been shown to a user for its duration The event data field for this event is: * `timeSpent`: The amount of time (in seconds) the user spent on the TrueX unit #### `adError` This is a [terminal event](#terminal-events). This event will fire when the TrueX unit has encountered an unrecoverable error. The host app code should handle this the same way as an `adCompleted` event -- resume playback and remove the TrueX ad renderer from its UI. The event data field for this event is: * `errorMessage`: A description of the cause of the error. #### `noAdsAvailable` This is a [terminal event](#terminal-events). This event will fire when the TrueX unit has determined it has no ads available to show the current user. The host app code should handle this the same way as an `adCompleted` event - resume playback and remove the TrueX ad renderer from its UI. #### `adFreePod` This event will fire when the user has earned a credit with TrueX. The host app code should notate that this event has fired, but should not take any further action. Upon receiving a [terminal event](#terminal-events), if `adFreePod` was fired, the app should skip all remaining ads in the current slot. If it was not fired, the app should resume playback without skipping any ads, so the user receives a normal video ad payload. #### `userCancelStream` This is a [terminal event](#terminal-events), and is only enabled when the `supportsUserCancelStream` property is set to `true` when triggering the [`init`](#init) action. When enabled, the renderer will fire this event when the user intends to exit the stream entirely. The app, 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, the renderer will emit an [`adCompleted`](#adcompleted) event instead. #### Informative Ad Events All following events are used mostly for tracking purposes -- no action is generally required. #### `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` This event will fire if the user opts for a normal video ad experience. The event data field for this event is: * `userInitiated`: This will be set to `true` if this was actively selected by the user, `false` if the user simply allowed the choice card countdown to expire. #### `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` 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. #### `popupWebsite` On mobile platforms, ad units with links to external web sites fire this event when the user clicks on the web site link, e.g. typically via a "Learn More" link. On mobile platforms, navigating to an external web site means leaving the current application. As such this ad event is used to communicate the user's intention, and the host app needs to open the external web page as appropriate for the platform. E.g. for Android, an intent is raised to open the web page in the phone's browser. The event data field for this event is: * `url`: Indicates the web page to navigate to. #### `xtendedViewStarted` This event fires for TrueX ad creatives that their own fallback extended videos built in. From the host app's perspective, nothing more is needed to be done, and the regular ad event flow processing will occur, just with the extended ad content instead. --- --- url: /infillion-ads-integration-docs/platforms/vega.md --- # Vega (FireTV) Integration TrueX Ad Renderer for Amazon Vega (Kepler) OS provides a React Native component library for rendering interactive TrueX ads on FireTV devices. > \[!TIP] Reference App > For a complete working example, check out the **[TrueX Vega Reference App](https://github.com/socialvibe/truex-vega-reference-app)**. > \[!INFO] info AI Assistance > Integrating with an AI coding assistant? Use our machine-readable documentation context: > > * **[llms.txt](/llms.txt)**: Documentation index and summary. > * **[llms-full.txt](/llms-full.txt)**: Full documentation content. ## Overview The `@truex/ad-renderer-vega` package is a React Native component designed specifically for Amazon's Vega (Kepler) operating system, which powers FireTV devices. It enables publishers to deliver engaging interactive ad experiences that give viewers choice in their ad consumption. ## Key Features * **React Native Component**: Seamless integration with React Native applications * **TypeScript Support**: Full type definitions for type-safe development * **Event-Driven Architecture**: Comprehensive event system for ad lifecycle management * **WebView-Based Delivery**: Leverages Amazon's WebView capabilities for rich interactive content * **Production Ready**: Battle-tested in production environments ## Platform Requirements * **Target Platform**: Amazon Vega (Kepler) OS (FireTV devices) * **Framework**: React Native 0.72.0 * **Language**: TypeScript/JavaScript * **React Version**: 18.2.0 ## What You'll Need Before integrating TrueX ads into your Vega application, ensure you have: 1. A React Native application running on Amazon Vega OS 2. Access to Amazon Device SDKs (@amazon-devices/\* packages) - see [Amazon Vega SDK Documentation](https://developer.amazon.com/docs/fire-tv/vega-sdk.html) 3. A VAST configuration URL or VAST XML from your ad server 4. Basic understanding of React hooks and event handling ## Quick Example Here's a minimal example of integrating TrueX ads: ```tsx import React, { useCallback } from 'react'; import { TruexAd, TruexAdEvent, TruexAdEventType, TruexAdEventHandler } from '@truex/ad-renderer-vega'; // truexAdInfo contains the ad data from your VAST response function TruexAdContainer({ truexAdInfo, onTruexAdFinished, onTruexAdFreePod }) { const handleTruexAdEvent = useCallback( event: TruexAdEvent) => { switch (event.type) { case TruexAdEventType.AD_COMPLETED: case TruexAdEventType.AD_ERROR: case TruexAdEventType.NO_ADS_AVAILABLE: case TruexAdEventType.USER_CANCEL_STREAM: // Ad finished, resume content onTruexAdFinished(); break; case TruexAdEventType.AD_FREE_POD: // User earned ad credit onTruexAdFreePod() break; } }, [ onTruexAdFinished, onTruexAdFreePod ] ); // Parse the ad parameters from the VAST node const adParameters = JSON.parse(truexAdInfo.adParameters); return ( ); } ``` --- --- url: /infillion-ads-integration-docs/overview/what-are-infillion-ads.md --- # What are Infillion Ads? Infillion is a leading advertising technology company that offers innovative ad solutions including [TrueX][truex_product] and [Interactive Video][interactive_video_product] (Interactive Digital Video Experience). ## TrueX - Opt-in Engagement Advertising [TrueX][truex_product] is Infillion’s flagship ad product. Fully interactive and always opt-in, TrueX allows consumers to choose to skip the Publisher’s regular ad break by interacting for 30 seconds with a TrueX engagement ad. Infillion pays the Publisher the same price or more for that skipped ad pod. Infillion works with a diverse range of video streaming Publishers on many different environments, devices and platforms, while driving best in class results for advertisers. TrueX provides a better experience for the viewer, reduces ad load for Publishers, and produces 5x the brand impact for Advertisers over standard video spots. ## **Interactive Video** [Interactive Video][interactive_video_product] from Infillion delivers a new industry standard in video engagement across all devices and platforms. The Infillion IDVx product goes beyond hovers and inadvertent clicks, to deliver real interaction, by real humans, in premium environments. Built on the same core interactive foundation as TrueX, IDVx removes the opt-in, interaction, and time spent requirements, in order to capitalize on the scale of a Publisher’s inventory with beautiful, engaging, and highly IDVx ads. Infillion pays Publishers a set CPM for the IDVx ads the Publisher renders in their ad pods. [truex_product]: https://infillion.com/products/infillion-truex/ [interactive_video_product]: https://infillion.com/products/infillion-interactive-video/