Skip to main content
Skip table of contents

Using the OtvAa Wrapper API

The wrapper-app and bmwrapper-app source code demonstrate the basic functionality described below. Their design are very similar to the agent-app as described in Using the OtvAa Agent API.

An addition to the wrapper app UI comparing to the agent app is the inclusion of a thumbnail-sized Player view and some basic playback buttons in the Submit Activity tab. There is no significance to the player content so it is made very small to reserve screen area for other controls.

The wrapper application communicates with OtvAnalyticsAgentWrapper which in turn:

  • instantiates, configures and communicates with an OtvAnalyticsAgent instance

  • configures the legacy Insight Agent (if required)

  • attaches listeners to the provided Player (Connect Player/Bitmovin Player), extracts events and metrics and reports them to the Analytics Server (via OtvAnalyticsAgent).

As the use of OtvAnalyticsAgent and OtvAnalyticsAgentWrapper are mutually exclusive by a single app, the wrapper application only handles OtvAnalyticsAgentWrapper. However, the API is very similar, and any submitActivity() call on OtvAnalyticsAgentWrapper is consequently passed on to the OtvAnalyticsAgent instance.

Initialising the wrapper

Similar to OtvAnalyticsAgent, the setting up of the OtvAnalyticsAgentWrapper is done in two steps. First, we instantiate the agent with the application context:

CODE
OtvAnalyticsAgentWrapper wrapper = new OtvAnalyticsAgentWrapper(getApplicationContext());

The second step is initialising the newly-created instance. The OtvAnalyticsAgentWrapper.initialise() takes three parameters, and returns an OtvAaError value, which, if successful, returns the OK value.

The first parameter of the initialisation is the wrapper and Insight configuration as a JSON object. If the Insight agent is not required, the only value required is samplePeriod. If Insight is required, then the Insight configuration parameters are added all in an insightConfig section:

JSON
{
  "samplePeriod":30,
  "insightConfig": {
    "collectorURL":"https://url-to-insight-collector",
    "reportingInterval": 30, // seconds (default 60)
    "samplingInterval": 15, // seconds (15-reportingInterval, default 30)
    "appName":"OtvAa Wrapper Sample App",
    "appVersion":"5.x",
    "deviceType":"handheld",
    "deviceId": "my-device-id"
    "operatorId":"my-op-id"}
  }
}

The other two parameters in the initialisation method are similar to the two parameters in agent-app: configuration for the agent and an instance of an OtvAaReportListener implementation. See Initialising the agent in the previous page.

With the above three parameters we can now initialise the wrapper (and the downstream agent):

CODE
OtvAaError result = wrapper.initialise(wrapperConfigJson,agentConfigJson,reportListener);

Note that you can check if initialisation is successful in two ways: either by checking that

result == OtvAaError.OK

or by checking

boolean success == Agent.isInitialised()

Updating the Configuration

The configuration of the wrapper and agent may need to be changed. With the same caveats described in Updating the Configuration in the previous page, you can update configuration as follows:

JAVA
OtvAaError result = wrapper.updateConfig(wrapperConfigJson, agentConfigJson);

Setting the Player

Set the player so that the wrapper can automatically detect some activities from the player, and automatically populate some of the metadata for other activities. The player should be set before the playbackStart() function is called so that the initial playback events are already reported.

The player parameter is a reference to the player object created by the application.

Set Connect player object:

CODE
OTVVideoView mVideoView;
......
OtvAaError result = wrapper.setPlayer(mVideoView, OtvAnalyticsAgentWrapper.PLAYER_TYPE_CONNECT);

Set Bitmovin player object:

CODE
Player mBitmovinPlayer;
......
OtvAaError result = wrapper.setPlayer(mBitmovinPlayer, OtvAnalyticsAgentWrapper.PLAYER_TYPE_BITMOVIN);

If the player is set (changed) during a playback session, then no further actions will be detected for that playback session.

Starting a Playback Session

playbackStart() must be called by the client application to provide stream information which is not available from the player. If possible, the playback session should be started immediately before setting stream URL on the player to request playback. If this is not possible then it should be started as soon as possible after the playback is requested on the player.

The parameters of playbackStart() are:

  • metadata

  • insightContent

  • insightUserInfo

If insight is not enabled, then the two insight parameters may be omitted.

If insight is enabled, insightUserInfo may be omitted if insight is required to run in anonymous mode.

playbackStart Metadata:

JSON
{
  // The following are important as they're used to
  // identify the playback session in subsequent activities
  "playbackSessionId": "<UUID/GUID>",
  "editorialID:"" "editorialChannelId",
  "contentSource": "<IPTV/OTT/Blend>",
  "ContentType": "live-event",
  
  "railId": "...",
  "Depth": "...",
  "hdepth": "...",
  "vdepth": "...",
  "templateId": "...",
  "technicalId": "...",
  "programmeId": "...",
  "seriesId": "...",
  "deepLinkId2: "..."
}

Insight Content Info

JAVA
ContentInfoHolder contentInfoHolder = new ContentInfoHolder();

// Set stream metadata for Insight
contentInfoHolder.setDuration(player.getDuration());
contentInfoHolder.setContentId("ContentId");
contentInfoHolder.setContentName("ContentName");
contentInfoHolder.setAudioLanguage("AudioLang"); // May be changed over the course of a session
contentInfoHolder.setSubtitleLanguage("SubsLang"); // May be changed over the course of a session
contentInfoHolder.setUri(uri);
contentInfoHolder.setType("VOD"); // Available options : VOD and LIVE

if (isLive) {
  contentInfoHolder.setChannelId("123456");
  contentInfoHolder.setChannelName("BBC1");
  contentInfoHolder.setEventId("abcdef");      // optional
  contentInfoHolder.setEventName("live tv");   // optional
  contentInfoHolder.setType("LIVE")
}

List<String> genres = new ArrayList<>();
genres.add("Drama");
genres.add("Thriller");
contentInfoHolder.setGenreList(genres);

Insight User Info

JAVA
UserInfoHolder userInfoHolder = new UserInfoHolder();
userInfoHolder.setUserId("User001");
userInfoHolder.setAccountId("account001");
userInfoHolder.setGender("male");
userInfoHolder.setAge(37);
userInfoHolder.setAgeRange("AlwaysTheSame");
userInfoHolder.setCategory("D'oh");
userInfoHolder.setFullName("Homer J Simpson");
userInfoHolder.setStreet("Evergreen Terrace");
userInfoHolder.setCity("Springfield");
userInfoHolder.setState("Idono");
userInfoHolder.setPostcode("1DK");
userInfoHolder.setCountry("US");
userInfoHolder.setCorp("Corp");
userInfoHolder.setNode("Node")

playbackStart()

JAVA
OtvAaError result = wrapper.playbackStart(metadata, insightContent, insightUserInfo);

Submitting Non-Playback Actions

Non-playback actions will not be automatically detected by the wrapper, so must be submitted by the client application, for example:

JAVA
// adDeliveredMetadata:
// {
//   // No need for appSessionId as it is auto populated
//   // No need for playbackSessionId as it is auto populated
//   "adID": "my-ad-id",
//   "trackingAssetId": "my-tracking-asset-id",
//   "adSupplier": "my-ad-supplier"
// }

OtvAaError result = wrapper.submitActivity(OtvActivity.AdDelivered, adDeliveredMetadata);

see https://docs.nagra.com/otv-analytics-agent/latest/otv-analytics-activities to find which activities are automatically generated by the wrapper as well as which metadata is automatically populated.

Stop Playing and Clean-up

A playbackStop activity is optional, but recommended if possible, when stopping one playback and starting another. The next playbackStart activity will be used to find when the previous session stopped.

Sometimes it is not possible to guarantee clean up at the end of a playback or application session (e.g., if the user navigates away from the application or the application is sent to the background), however the client application should endeavour to clean up using the following sequence to ensure no loss of data:

JAVA
JSONObject stopMetadata = // Create a metadata object with at least the Position field

OtvAaError result = wrapper.submitActivity(OtvActivity.PlaybackStop, stopMetadata);
:
result = wrapper.submitActivity(OtvActivity.AppEnd);
:
wrapper = null;

Error Handling

Synchronous errors are the OtvAaError return values from method calls to the wrapper.

Other asynchronous errors, mostly the results of network operations and calls to the server, would be sent to the OtvAnalyticsAgent.tvAaReportListener.onError(OtvAaError xErrorCode, int xExtra) callback, either from the OtvAnalyticsAgenttWrapper instance or the OtvAnalyticsAgent instance it controls.

See the API documentation at OpenTV Analytics Agent for Android APIs .

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.