Czech Digital Measurement iOS Simplified SDK

From Engineering Client Portal

Revision as of 18:44, 28 March 2019 by Admin3 (talk | contribs)

Engineering Portal breadcrumbArrow.png Digital breadcrumbArrow.png International breadcrumbArrow.png Czech Digital Measurement iOS Simplified SDK

Overview

The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc. The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings (DCR & DTVR), Digital Ad Ratings (DAR), Digital Audio. Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:

  • Application launch events and how long app was running
  • Time of viewing a sub section / page in the application.

Prerequisites

To start using the Simplified SDK for Browser, you will need an Appid. This is a Unique ID assigned to the player/site and configured by product. If you do not have any of these prerequisites or if you have any questions, please see Contact list for Czech Republic.

Simplified SDK API

As part of making the SDK more user friendly and reduce the number of app integration touch points, Nielsen has designed a simple interface to pass metadata to the sdk while reducing the number of API calls. The new trackevent() API has been implemented as a wrapper for the existing SDK and will be responsible for handling new API calls, performing validation, and translation of new API calls to the existing Nielsen App SDK API methods. Applications which are already integrated with the existing SDK API, are unaffected by this new API. SimplifiedAPI vs StandardAPI New.jpg Click here to zoom in on image

Manages the order of metadata (ad vs content and playheads)

Existing API has a number of methods used for reporting player and application state changes to the SDK. Order of calls is important for the SDK in the existing API. In the new enhanced API all these calls will be replaced with one API call that will get one dictionary object with many key-value pairs, where any value could be another complex dictionary object. All the data provided in the existing API in separate calls will be provided in one single call. SDK will analyse the data received in the dictionary object, compare it with the data received previously and generate a sequence of calls for the existing API.

Implementation

This guide covers implementation steps in JavaScript.

Step 1 : Configure SDK

Add the following script tag (to Static Queue Snippet) the website:

<script type = "text/javascript" >
  /***************** Static Queue Snippet *********************/
  ! function(t, n) {
    t[n] = t[n] || {
      nlsQ: function(e, c, o, r, s, i) {
        return s = t.document,
          r = s.createElement("script"),
          r.async = 1,
          r.src = ("http:" === t.location.protocol ? "http:" : "https:") + "//cdn-gl.imrworldwide.com/conf/" + e + ".js#name=" + c + "&ns=" + n, i = s.getElementsByTagName("script")[0], i.parentNode.insertBefore(r, i),
          t[n][c] = t[n][c] || {
            g: o || {},
            ggPM: function(e, o, r, s, i) {
              (t[n][c].q = t[n][c].q || []).push([e, o, r, s, i])
            },
            trackEvent: function(e) {
              (t[n][c].te = t[n][c].te || []).push(e)
            }
          }, t[n][c]
      }
    }
  }(window, "NOLBUNDLE"); 
</script>

The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration file are still being downloaded. As the queue can capture all API calls before the download completes, there is no wait time. Once the SDK is available, the API calls will transition from directing to the queue to the SDK seamlessly.

Step 2 : Create SDK Instance

To initialize the SDK, create an SDK instance by making the initialization call:

NOLBUNDLE.nlsQ("<apid>", "<instanceName>",{nol_sdkDebug: "debug"})


When creating an instance, pass the following values: (nol_sdkDebug and optout are optional)

Parameter Description Values
apid Unique ID assigned to player/site 'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
instanceName Name of SDK instance "any string value"
nol_sdkDebug Enables Nielsen console logging. Only required for testing "{nol_sdkDebug: "debug"}"

When the initialization call is made, a unique static configuration file, <apid>.js, will be downloaded based on the apid and will be cached on the user’s browser.

Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.bundle.min.js”.


Example SDK Configuration

The configuration should include the Static Queue Snippet and an SDK Instance for an unique App ID as shown in the example:

<script type = "text/javascript" >
  /***************** Static Queue Snippet *********************/
  ! function(t, n) {
    t[n] = t[n] || {
      nlsQ: function(e, c, o, r, s, i) {
        return s = t.document,
          r = s.createElement("script"),
          r.async = 1,
          r.src = ("http:" === t.location.protocol ? "http:" : "https:") + "//cdn-gl.imrworldwide.com/conf/" + e + ".js#name=" + c + "&ns=" + n, i = s.getElementsByTagName("script")[0], i.parentNode.insertBefore(r, i),
          t[n][c] = t[n][c] || {
            g: o || {},
            ggPM: function(e, o, r, s, i) {
              (t[n][c].q = t[n][c].q || []).push([e, o, r, s, i])
            },
            trackEvent: function(e) {
              (t[n][c].te = t[n][c].te || []).push(e)
            }
          }, t[n][c]
      }
    }
  }(window, "NOLBUNDLE"); 

  // Created SDK Instance
var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", {nol_sdkDebug: "debug"});
</script>

Step 3 : Simplified API Syntax

The existing API has a number of methods used for reporting player and application state changes to the SDK. The order of calls is important for the SDK in the existing API. In the new simplified API, all these calls will be replaced with one API call that will get one dictionary object with many key-value pairs, where any value could be another complex dictionary object. All the data provided in the older API in separate calls will be provided in one single call.

Main API call for the new NielsenEventTracker API:

 nSdkInstance.trackEvent({metadata})

TrackEvent JSON Metadata

Parameter “data” is a JSON object with many key-value pairs that holds all information required by SDK.

Format of input object is the following:

{ 
 "event": <event identifier>,
 "type": <type of metadata>,
 "metadata":{ 
   "content": <content metadata object>,
   "ad": <ad metadata object>,
   "static": <static metadata object>
 },
 "playheadPosition":<playhead value>
 }


Passed parametres

Parameter Description Supported values Example
event Event identifier

String: playhead,pause,complete, adStop

"event":"playhead"
type Determines the metadata object that should be used for crediting.

String:
content, ad, static

"type":"content"
metadata Object that holds metadata values of specific types Object
"metadata":{ 
   "content": <content_metadataObject>,
   "ad": <ad_metadataObject>,
   "static": <static_metadataObject>
 },
playheadPosition Playhead value String

For live stream : Position value is Unix timestamp: "playheadPosition":"1543437655"

For VOD : Position value is playhead: "playheadPosition":"10"

For static : pass only 1st position: "playheadPosition":"1"

Event identifiers

The New API method supports the following event types:

Key Description
playhead

It is used to pass content, ad or static metadata, the current playhead value, Unix timestamp, ott information to the SDK.

pause

This event should be used when content playback is paused.
(Pause is detected by SDK automatically when the time gap between commands is more than 30 minutes.)

complete

It is called when session is completed or ends.

adStop

Should be called at the end of each ad. This event type is required to handle the case when advertisements could not be distinguished, as its assetId is the same.


Content Metadata

For detailed information of metadata and custom variables see specitication of Content Metadata for Czech Republic.
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play. Send content metadata for every playheadposition update.
When content is playing, pass only metadata for content - like

var metadata = { 
   "content": <content_metadataObject>,
   "ad": "",
   "static": ""
 };

Ad Metadata

For detailed information of metadata and custom variables see specitication of Content Metadata for Czech Republic.
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins. When ad is playing, pass metadata for ad and its content as well - like

var metadata = { 
   "content": <content_metadataObject>,
   "ad": <ad_metadataObject>,
   "static": ""
 };

Static Metadata

For detailed information of metadata and custom variables see specitication of Content Metadata for Czech Republic.
As static measurement is indepentent from video measurement, keep content and ad metadata empty and pass only static metadata.

var metadata = { 
  "content": "",
   "ad": "",
   "static": <static_metadataObject>
 };

Putting it all together - example for video (ad)

// content
var content_metadataObject = {
	"assetid" : "assetid_example",
	"type" : "content",
	"program" : "ProgramName",
	"title" : "Bunny in woods",
	"length" : "579",
	"mediaUrl" : "", // empty
	"airdate" : "20190313 20:00:00",
	"isfullepisode" : "y",
	"crossId1" : "IDEC",
	"nol_c1" : "p1,", // empty for VOD
	"nol_c2" : "p2,TV ident",
	"segB" : "Program type",
	"segC" : "", // empty
	"adloadtype" : "1",
	"hasAds" : "1"
}

// ad
var ad_metadataObject = {
	"assetid" : "assetid_example_preroll",
	"type" : "preroll",  // or midroll, postroll
	"length" : "30",
	"title" : "Nielsen preroll",
	"nol_c4" : "p4,ASMEAcode", // empty for VOD
	"nol_c5" : "p5,AtributForAd",
	"nol_c6" : "p6,preroll"
}

var trackObject = {
	"event": 'playhead',
	"type": 'ad',
	"playheadPosition": '1',
	"metadata": {
                "content": content_metadataObject,
                "ad": ad_metadataObject,
                "static": ""
          				}
	   		  };

// fire TrackEvent
nSdkInstance.trackEvent(trackObject)

Putting it all together - example for static

// static
var static_metadataObject = {
	"type" : "static",  
	"section" : "static_section1",  
	"segA" : "segA example",  
	"segB" : "segB example",  
	"segC" : "segC example",  
}

var trackObject = {
	"event": 'playhead',
	"type": 'static',
	"playheadPosition": '1',
	"metadata": {
                "content": "",
                "ad": "",
                "static": static_metadataObject
          				}
	   		  };

// fire TrackEvent
nSdkInstance.trackEvent(trackObject)

Step 4 : API Call sequence

Use Case 1: Video - Content has no Advertisements

Playlist : single content, no ads.
A Sample API sequence follow this flow:

Playlist API call TrackEvent Description
1. Video start event playhead, type : content, metadata : content_metaDataObject, playheadPosition : 1 1st call playhead
2. Video playing .. event playhead, type : content, metadata : content_metaDataObject, playheadPosition : 2,3,4.. etc playhead every second
3. Video ends event complete, type : content, metadata : content_metaDataObject, playheadPosition : lastPlayheadValue call complete

Use Case 2: Video - Content has Advertisements

Playlist : ad preroll - content - ad midroll - content continues - ad postroll.
A Sample API sequence follow this flow:

Playlist API call TrackEvent Description
1. Ad Preroll start event playhead, type : ad, metadata : ad_preroll_metaDataObject + content_metaDataObject, playheadPosition : 1 1st call playhead
2. Ad Preroll playing .. event playhead, type : ad, metadata : ad_preroll_metaDataObject + content_metaDataObject, playheadPosition : 2,3,4.. etc playhead every second
3. Ad Preroll ends event adStop, type : ad, metadata : ad_preroll_metaDataObject + content_metaDataObject, playheadPosition : lastPosition call adStop at the end of add
4. Content start event playhead, type : content, metadata : content_metaDataObject, playheadPosition : 1 1st call playhead
5. Content playing .. event playhead, type : content, metadata : content_metaDataObject, playheadPosition : 2,3,4.. etc playhead every second
6. Content interupted by midroll event playhead, type : content, metadata : content_metaDataObject, playheadPosition : lastPlayheadValue last playhead
7. Ad Midroll start event playhead, type : ad, metadata : ad_midroll_metaDataObject + content_metaDataObject, playheadPosition : 1 1st call playhead
8. Ad Midroll playing .. event playhead, type : ad, metadata : ad_midroll_metaDataObject + content_metaDataObject, playheadPosition : 2,3,4.. etc playhead every second
9. Ad Midroll ends event adStop, type : ad, metadata : ad_midroll_metaDataObject + content_metaDataObject, playheadPosition : lastPosition call adStop at the end of add
10. Content continues after midroll event playhead, type : content, metadata : content_metaDataObject, playheadPosition : 1 1st call playhead
11. Content playing .. event playhead, type : content, metadata : content_metaDataObject, playheadPosition : 2,3,4.. etc playhead every second
12. Content ends event complete, type : content, metadata : content_metaDataObject, playheadPosition : lastPlayheadValue call complete for content
13. Ad Postroll start event playhead, type : ad, metadata : ad_postroll_metaDataObject + content_metaDataObject, playheadPosition : 1 1st call playhead
14. Ad Postroll playing .. event playhead, type : ad, metadata : ad_postroll_metaDataObject + content_metaDataObject, playheadPosition : 2,3,4.. etc playhead every second
15. Ad Postroll ends event adStop, type : ad, metadata : ad_postroll_metaDataObject + content_metaDataObject, playheadPosition : lastPosition call adStop at the end of add

Use Case 3: Video - more ads in each ad pool

Playlist : ad preroll1 - preroll 2 - content - ad midroll 1 - ad midroll 2 - content continues - ad postroll 1 - ad postroll 2.
Use adldx parametr to assign position of ad in ad pool (starting from 0)

Ad in pool MetaData Example

var ad_pool_metadataObject = {
	"assetid" : "assetid_example_preroll",
	"type" : "preroll",  // or midroll, postroll
	"length" : "30",
	"title" : "Nielsen preroll",
	"nol_c4" : "p4,ASMEAcode", // empty for VOD
	"nol_c5" : "p5,AtributForAd",
	"nol_c6" : "p6,preroll",
	"adldx" : "0" // position in ad pool - 0,1,2..
}


Reset the playhead position to 0 for each ad.
Call the adStop event at the end of each ad or increment the adldx
The Simplified SDK will can automatically detect the change from ad to content, or even ad to ad if the assetID changes; however, there could be situations where the same ad is played back to back. You can either increment/change the adldx value, and/or call adStop at the end of each Ad.

Use Case 4: Static

A Sample API sequence follow this flow:

Playlist API call TrackEvent Description
1. User enters page (or HbbTV section) event playhead, type : static, metadata : static_metaDataObject, playheadPosition : 1 1st call playhead
2. User stays within section .. n/a no call needed, SDK counts seconds 2,3,4,..
3. User leaves section n/a no call needed, SDK automatically ends measurement

Step 5 : Privacy and Opt-Out

User Opt-Out

The site must provide a means for the user to opt-out of, or opt back into Nielsen Measurement. A user can opt-out if they would prefer not to participate in any Nielsen online measurement research. To implement the opt-out option, include the following two items in your privacy policy.

  • A notice that the player includes proprietary measurement software that allows users to contribute to market research (such as Nielsen TV Ratings).
  • A link to the Nielsen Digital Measurement Privacy Policy

On the Nielsen Digital Measurement Privacy Policy page, users can click Choices to read more detailed information about the measurement software, learn about their options with regard to Nielsen measurement, and, if they do not want to participate in Nielsen online measurement, click a link to receive an opt-out cookie. Once users have opted-out, they can choose to opt back into Nielsen Measurement at anytime by selecting the opt back in link on the Nielsen Digital Privacy Policy page. When a user selects the link, their opt-out cookie will be deleted and they will be able to be measured.

The following paragraph is a template for an opt-out statement (in Czech).

Tato aplikace obsahuje proprietární měřicí software společnosti Nielsen, který uživatelům umožní přispívat k průzkumu trhu. Chcete-li se dozvědět více o informacích, které může software Nielsen shromažďovat a o Vaší možnosti měření deaktivovat, přečtěte si zásady ochrany osobních údajů Nielsen Digital Measurement na Nielsen Digital Measurement Privacy Policy.

Initialization Opt-Out

To configure Opt-Out during SDK initialization. Add parametr outout into SDK init syntax - see step2.
Use value "true" or "Yes" or "1" to OptOut, or value "false", "No" or "0" to not OptOut.

var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", {
  nol_sdkDebug: "debug",
  outout: "true"
});


Opt-out status

Optional : to retrieve Opt-Out status call getOptOutStatus() , result is boolean value true (OptOuted = not measuring) or false (not OptOuted = measuring).

nSdkInstance.getOptOutStatus();

Step 6 : Test your player by yourself

see how to test player at https://www.youtube.com/watch?v=t9eUsf9yh8w&feature=youtu.be

Test SKD API calls

to verify SDK API calls use Chrome and install add-on called "Nielsen SDK Inspector" (https://chrome.google.com/webstore/search/%20Nielsen%20SDK%20Inspector)

Test outgoing pings

to verify outgoing pings use Charles Proxy or any other proxy sw capable to sniff your network traffic. Filter URLs to "imrworld". Example of such ping :

http://secure-eu-cert.imrworldwide.com/cgi-bin/gn?prd=dcr&ci=de-205177
&ch=de-205177_c01_static-123_P&asn=static-123&prv=1&c6=vc,c01&ca=NA
&c13=asid,T74896328-A13B-4985-8798-0AEBFA228D3E&c32=segA,segA%20example&c33=segB,segB%20example
&c34=segC,segC%20example&c15=apn,&sup=1&segment2=&segment1=&forward=0&ad=0&cr=V&c9=devid,
&enc=true&c1=nuid,88b7cd07-f83d-45b1-8db1-20b4e2caae55
&at=view&rt=text&c16=sdkv,bj.6.0.0&c27=cln,0&crs=&lat=&lon=&c29=plid,14966485169569829
&c30=bldv,6.0.0.1&st=dcr&c7=osgrp,&c8=devgrp,&c10=plt,&c40=adbid,&c14=osver,NA
&c26=dmap,1&dd=&hrd=&wkd=&c35=adrsid,&c36=cref1,&c37=cref2,&c11=agg,1&c12=apv,&c51=adl,0
&c52=noad,0&devtypid=&pc=NA&c53=fef,n&c54=oad,&c55=cref3,&c57=adldf,2&ai=static-123&c3=st,c&c64=starttm,1496648518
&adid=static-123&c58=isLive,false&c59=sesid,&c61=createtm,1496648517
&c63=pipMode,&c68=bndlid,&c73=phtype,&c74=dvcnm,&c76=adbsnid,&df=0&sessionId=14966485169569829
&c44=progen,&davty=0&si=http%3A%2F%2Fsdkdemo.admosphere.cz%2FBrowserSdk6static%2Fdemo1cz%2F
&c66=mediaurl,&c62=sendTime,1496648517&rnd=496564

Step 7 : Provide your app for certification

Once ready please send your application to Nielsen local staff for verification - see Contact list for Czech Republic.


Step 8 : Going Live

After the integration has been certified, users will need to make a couple of updates to the initialization call to ensure that player will be measured properly. Disable debug logging by deleting {nol_sdkDebug: 'DEBUG'} from initialization call - see step 2.