Client-side Implementation
How to configure a player application to support non-linear ad insertion
Client-side Components
The following functional client-side components are involved in the flow sequence:
- App: The application / page that controls user interactions and the interactions between the main other client-side components
- Video Player: the component in the app that streams and renders the video
- Smartlib: the client-side Broadpeak SDK that manages interaction with the BkYou/broadpeak.io platform to receive metadata on inserted linear ads and non-linear ads to to be inserted
- Smartlib Session: the object that manages individual playback sessions (specific to the stream and user)
- SIMID Creative: the SIMID non-linear ad. It's an HTML document that contains the visual part of the ad and implements part of the SIMID protocol.
- SIMID Controller: the component or object in the app that manages the display of SIMID creatives, typically through the management of a WebController object. The SIMID controller implements part of the SIMID protocol.
For clarity about client-side responsibilities in this document, we introduce this component separate from the App itself. Naturally, application developers have the choice of how they model this distinction within the app. - Web Controller: the element in charge of loading and displaying the SIMID creative (HTML). This object depends on the device type: WebView (Android), WKWebView (iOS) or iframe (Web)
SIMID Controller
Broadpeak provides an open-source reference implementation of a SIMID controller that can be integrated in a web or Android app and be bootstrapped from.
Role
The role of the SIMID controller is best understood from its relationship to the other component:
- The app receives programmatic events from the SmartLib. The events carry information that indicates whether non-linear ads were returned by the ad server.
- The app instructs the SIMID controller on how to display the non-linear ad.
These instructions are represented in the diagram below with the terms "init", "load url", "show" and "destroy". These names are purely informative, and the choice of implementation of these interactions between the App and the SIMID controller are in the hands of the application developer
- The SIMID controller listens to the events that the Creative (loaded in the Web Controller) sends - see βSIMID Implementationβ below
- The SIMID controller propagates the information captured from those to the SmartLib, enabling it to react accordingly. - see βEvent listenerβ below
This functionality is necessary to ensure that the Smartlib can have access to certain information that passes between the SIMID Controller and the SIMID Creative, on all devices, particularly those on which events cannot be listened to by all components (e.g. Android and iOS). This is critical in particular for the purpose of ensuring that insertions are tracked correctly. see βEvent listenerβ below
SIMID Implementation
The controller implements the SIMID specification, and must at minimum support the following methods and messages:
- Section 8 - Protocol
- Section 4.3 - "Messages from the player" - sent by the SIMID controller to the Creative
- Section 4.4 - "Messages from the Creative to the Player" - sent by the SIMID Creative to the SIMID controller
Other SIMID messages
The SIMID spec contains other messages. Those are not currently deemed to be necessary for non-linear ads (whether static of interactive).
Event listener
The SIMID controller propagates SIMID messages in such a way that the SmartLib can listen to them. This is critical in particular for the purpose of ensuring that insertions are tracked correctly in the Broadpeak analytics system which provides a combined view of linear and non-linear ad insertions.
To do so, the controller extends a GenericSimidControllerApi
(abstract class bundled with SmartLib). The app must then pass an instance of the controller to SmartLib with session.attachSimidController()
.
Whenever the SIMID controller receives a SIMID message from the creative, it fires the method onMessageReceived()
from your instance of GenericSimidControllerApi
with the associated SIMID message payload encoded as a JSON string, which contains the following:
property | type | example |
---|---|---|
sessionId | string | β173378a4-b2e1-11e9-a2a3-2a2ae2dbcce4β |
messageId | int | 0 |
timestamp | long | 1564501643047 |
type | string | βcreateSessionβ |
args | map<string, any> | (object created from the JSON payload) |
Conversely, when the SIMID controller sends a SIMID message to the creative, it fires the method onMessageSent()
from your instance of GenericSimidControllerApi
, with the message sent encoded as a JSON string.
Not all messages need to be propagated to SmartLib. In the current version, only createSession
and SIMID:Player:startCreative
are necessary.
Ad Tracking
The SIMID controller, since it is in charge of the display of the web controller, also needs to inform the SmartLib when it is time to send ad trackers, in particular the creativeView
tracking URL. SmartLib offers a sendTracker()
method for that purpose - See βTrackingβ section below for details
Overall flow
The solution has been architected to ensure minimal changes in the Smartlib compared to standard SSAI linear ads flows (documented at https://delivery-platform.broadpeak.tv/smartlib/public/ad-insertion/integration). Familiarity with those flows is assumed in the remainder of this document.
A βnewβ icon π is used below to highlight areas specific to flows with non-linear ads which require specific and additional handling by the app or player developer.
This section focuses on an Android integration. There are likely to be small differences in implementation between different platforms (web, Android, iOS). Where relevant they are highlighted below.

-
When the app launches, SmartLib is initialised
-
For each video load (i.e., each channel change), a SmartLib session is created
- The app calls
SmartLib.getInstance().createStreamingSession()
and stores thesession
object. - The app attaches the video player instance to Smartlib with
session.attachPlayer(playerInstance)
. - π The app extends a
GenericSimidControllerApi
and create an instance ofbpkSimidController
. Some of the SIMID messages received from that point on must be forwarded usingbpkSimidController.onMessageReceived(messageStr)
for received messages andbpkSimidController.onMessageSent(messageStr)
for sent messages. Your SIMID controller might need to keep track of this instance. - π The app attaches the SIMID controller instance with
session.attachSimidController(bpkSimidController)
. This allows the SIMID controller to pass events to SmartLib. - The app calls
session.setAdEventsListener(β¦)
so that the app can receive ad events. - The app calls
session.getURL(contentURL)
to start the streaming session.
- The app calls
-
When SmartLib detects an ad break
-
π
onPrepareAdBreak(adBreakData)
is triggered a few seconds before the start of the ad break, in all cases (whether the ad break contains linear non-linear ads)adBreakData
contains information about the ad break.- This event can be used by the app to (re-)initialize the SIMID controller
-
π
onPrepareAd(adBreakData, adData)
is triggered a few seconds before the start of an ad-
π The app determines if the ad has non-linear ads attached
-
on Web, this is done by looking up the field
adData.adType
, which will contain one of the following values:linear The ad only contains a linear creative nonlinear The ad only contains a non-linear creative linear_and_nonlinear The ad contains both linear and non-linear creatives -
on Android, this is done by calling
adData.getType()
, which returns an enum valueAD_LINEAR The ad only contains a linear creative AD_NON_LINEAR The ad only contains a non-linear creative AD_LINEAR_AND_NON_LINEAR The ad contains both linear and non-linear creatives
-
-
π If a non-linear creative is present, the app retrieves the metadata for the SIMID resource:
- On Web, by looking up
adData.nonLinearIframeResources
- On Android, by calling
adData.getNonLinearIframeResources()
Both return an array of objects with the following properties:
property type description url string URL of the SIMID resource parameters string Contains information that needs to be passed to the SIMID Creative through the Player:init. It contains a JSON string but it is the creativeβs responsibility to parse and interpret it. - On Web, by looking up
-
πΒ The app instructs the SIMID controller to load the SIMID creative from that URL. The SIMID controller creates a WebController in the way appropriate to each device.
-
The SIMID Creative exchanges a few messages with the SIMID controller to ensure everything is working properly:
createSession
,Player:init
,resolve
- see section 6.2 βWorkflow Initializationβ of the SIMID specification. -
The SIMID Controller propagates those messages to SmartLib with
bpkSimidController.onMessageReceived(messageStr)
andbpkSimidController.onMessageSent(messageStr)
.
-
-
onAdBreakBegin(adBreakData)
is triggered when the ad break starts. -
onAdBegin(adBreakData, adData)
is triggered when an ad starts.- πΒ The app instructs the SIMID controller to display the SIMID Creative (if one was successfully prepared in
onPrepareAd()
) - π The SIMID Creative exchanges a few messages with the controller:
Player:startCreative
,resolve
- see section 6.3 βTypical Start Creative Workflowβ of the SIMID specification: - π The SIMID Controller ensures that the WebController is displayed to the end-user.
- π The SIMID Controller instructs SmartLib to trigger the creativeView tracking URL, with
session.sendTracker(AdTracking.CREATIVE_VIEW)
. This triggers the impression call to the ad server. - πΒ The SIMID Creative sends a
Creative:requestResize
message to instruct the app to resize the player. The app resizes the video player component accordingly - see βPlayer Resizingβ below for more information. - The SIMID Controller propagates those messages to SmartLib with
bpkSimidController.onMessageReceived(messageStr)
andbpkSimidController.onMessageSent(messageStr)
.
- πΒ The app instructs the SIMID controller to display the SIMID Creative (if one was successfully prepared in
-
onAdEnd(adBreakData, adData)
is triggered when the ad ends- πΒ The app instructs the SIMID Controller to hide the SIMID Creative
- πΒ The app resets the size of the video player
-
onAdBreakEnd(adBreakData)
is triggered when the ad break ends- πΒ The app can use this event to free the memory of the SIMID controller (if appropriate)
-
Sample Code
Please refer to SIMID controller repository for reference implementation:
- Web: SIMID Controller and demo app
- Android: SIMID Controller and demo app
Player resizing
To enable the display of non-linear ads around the video content and avoid obscuring part of the content, the SIMID creative will send a SIMID:Creative:requestResize
command to the SIMID controller, with the calculated coordinates and dimensions (in pixels) of the area of the creative within which the video needs to be displayed.
The dimensions returned take into account the dimensions of the player component and of the creative.
The SIMID controller passes those dimensions to the app, which must resize the video component accordingly. If transitions are warranted for a better user experience (such as a gradual squeeze back), it is the responsibility of the application to apply them.
Deviation from SIMID spec
The SIMID spec (latest v1.2) indicates that:
SIMID does not support L-shaped ads that resize the video player without an overlay covering the video
and that, instead
The video asset will need to be cropped or resized to allow the interactive creative to be put into the correct place
This constraint is not workable, in particular in a SSAI solution supporting non-linear ads (such as L-Banners), especially when they donβt accompany a corresponding linear creative and are therefore to be displayed alongside the main content.
Our solution therefore requires a small βdeviationβ from the standard specification, to allow a creative to inform a player/app of the need to resize the video component and make it smaller than the (full-frame) creative. This is possible without any change to the SIMID message syntax.
Example
For simplicity, we use a 4-tuple to represent a Dimensions object: (x, y, width, height)
This example assumes that
- the display has a natural 4K (3840x2160) resolution
- This is sent by the SIMID controller to the creative in the
SIMID:Player:init
message
- This is sent by the SIMID controller to the creative in the
- the source image (returned by the ad server) has a resolution of 1920x1080, with a media area declared as (200, 0, 1720, 968)
- This information is passed by the Smartlib to the Creative through the
SIMID:Player:init
message, in particular theCreativeData.adParameters
- This information is passed by the Smartlib to the Creative through the

non-linear ad creative, with dimensions
On that basis, the creative will calculate and send a SIMID:Creative:requestResize
message with the following payload
- creativeDimensions: (0, 0, 3840, 2160)
- mediaDimensions: (400, 0, 3440, 1935)
The application performs the resize of the video player accordingly:

Application, with resized video player (hashed area)
It is critical that the player not send a SIMID:Player:resize after receiving and resolving a SIMID:Creative:requestResize
Ad Tracking
Impressions
The impression (or impressions) are valid for the whole ad, whether or not they contain linear and/or non-linear components. They are automatically being fired by the SmartLib
Tracking beacons
The only tracker used for non-interactive non-linear ads is creativeView
.
It is the responsibility of the SIMID Controller to instruct SmartLib to send the tracker, after it has ensured that the ad is successfully displayed. This is described in the flow above
Updated 13 days ago