DCR Czech Video Browser SDK: Difference between revisions

From Engineering Client Portal

(Created page with "{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International}} {{CurrentBreadcrumb}} Category:Digital == Prerequisites == To get started, an App ID is needed. The A...")
 
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International}}  {{CurrentBreadcrumb}}
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}
[[Category:Digital]]
[[Category:Digital]]


Line 13: Line 13:
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
<script>
<script>
!function(t,n)
!function(e,n){
{
  function t(e){
   t[n]=t[n]||
    return"object"==typeof e?JSON.parse(JSON.stringify(e)):e
   }
  e[n]=e[n]||
   {
   {
     nlsQ:function(e,o,c,r,s,i)
     nlsQ:function(o,r,c){
    {
      var s=e.document,
    return s=t.document,
      a=s.createElement("script");
    r=s.createElement("script"),
      a.async=1,
    r.async=1,
      a.src=("http:"===e.location.protocol?"http:":"https:")+"//cdn-gl.imrworldwide.com/conf/"+o+".js#name="+r+"&ns="+n;
    r.src=("http:"===t.location.protocol?"http:":"https:")+"//cdn-gl.imrworldwide.com/conf/"+e+".js#name="+o+"&ns="+n,
      var i=s.getElementsByTagName("script")[0];
    i=s.getElementsByTagName("script")[0],
      return i.parentNode.insertBefore(a,i),
    i.parentNode.insertBefore(r,i),
      e[n][r]=e[n][r]||{g:c||{},
    t[n][o]=t[n][o]||{g:c||{},
      ggPM:function(o,c,s,a,i){e[n][r].q=e[n][r].q||[];try{var l=t([o,c,s,a,i]);e[n][r].q.push(l)}
    ggPM:function(e,c,r,s,i){(t[n][o].q=t[n][o].q||[]).push([e,c,r,s,i])}},t[n][o]
catch(e){console&&console.log&&console.log("Error: Cannot register event in Nielsen SDK queue.")}},
      trackEvent:function(o){e[n][r].te=e[n][r].te||[];try{var c=t(o);e[n][r].te.push(c)}
catch(e){console&&console.log&&console.log("Error: Cannot register event in Nielsen SDK queue.")}}},
      e[n][r]
     }
     }
   }
   }
}
}(window,"NOLBUNDLE");
 
(window,"NOLBUNDLE");


var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "nlsnInstance");
var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "nlsnInstance");
Line 105: Line 108:
| loadMetadata || content or ad metadata JSON || Needs to be called at the beginning of each asset|| nSdkInstance.ggPM("loadMetadata", metadataObjectContent)
| loadMetadata || content or ad metadata JSON || Needs to be called at the beginning of each asset|| nSdkInstance.ggPM("loadMetadata", metadataObjectContent)
|-
|-
| setPlayheadPosition|| playhead position in seconds as integer || Pass playhead position every second during playback. for VOD: pass current position in seconds.  for Live: current UTC timestamp - if possible to seek back in Live content than pass related UTC time (not current)|| nSdkInstance.ggPM("setPlayheadPosition", currentPosition);
| setPlayheadPosition|| playhead position in seconds as integer || Pass playhead position every second during playback. for VOD: pass current position in seconds.  for Live: current Unix timestamp (seconds since Jan-1-1970 UTC) - if it's possible to seek back in Live content, then pass related Unix timestamp (not current)|| nSdkInstance.ggPM("setPlayheadPosition", currentPosition);
|-
|-
| stop || playhead position in seconds as integer || Call when content or ads complete playing and pass playhead position, call stop when pausing playback|| nSdkInstance.ggPM("stop", parseInt(playerPosition));
| stop || playhead position in seconds as integer || Call when content or ads complete playing and pass playhead position, call stop when pausing playback|| nSdkInstance.ggPM("stop", parseInt(playerPosition));

Latest revision as of 09:36, 25 September 2023

Engineering Portal / Digital / International DCR / DCR Czech Video Browser SDK

Prerequisites

To get started, an App ID is needed. The App ID is a unique ID assigned to the player/site/app. This will be provided upon starting the integration. If not, please contact Nielsen local staff - See Czech Contacts.

apid: "PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

Step 1: Configure SDK

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

<script>
!function(e,n){
  function t(e){
    return"object"==typeof e?JSON.parse(JSON.stringify(e)):e
  }
  e[n]=e[n]||
  {
    nlsQ:function(o,r,c){
      var s=e.document,
      a=s.createElement("script");
      a.async=1,
      a.src=("http:"===e.location.protocol?"http:":"https:")+"//cdn-gl.imrworldwide.com/conf/"+o+".js#name="+r+"&ns="+n;
      var i=s.getElementsByTagName("script")[0];
      return i.parentNode.insertBefore(a,i),
      e[n][r]=e[n][r]||{g:c||{},
      ggPM:function(o,c,s,a,i){e[n][r].q=e[n][r].q||[];try{var l=t([o,c,s,a,i]);e[n][r].q.push(l)}
catch(e){console&&console.log&&console.log("Error: Cannot register event in Nielsen SDK queue.")}},
      trackEvent:function(o){e[n][r].te=e[n][r].te||[];try{var c=t(o);e[n][r].te.push(c)}
catch(e){console&&console.log&&console.log("Error: Cannot register event in Nielsen SDK queue.")}}},
      e[n][r]
    }
  }
}(window,"NOLBUNDLE");

var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "nlsnInstance");

</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 (already added in above code):

var nSdkInstance = NOLBUNDLE.nlsQ("appid", "instanceName", {debugMode"});


When creating an instance, pass the following values:

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

Example SDK Initialization

For development phase - including DEBUG mode

var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "myPlayerName", {nol_sdkDebug: "debug"});


For production phase (after approval)

var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX","myPlayerName");


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”.

Step 3: Create Metadata Objects

The metadata received for each asset is used for classification and reporting.

There are two types of asset metadata:

  • content: identify video
  • ad: identify each ad

Content Metadata

Content metadata should remain constant throughout the completion of an episode / clip including the ads play.
See Czech SDK Metadata.

Ad Metadata

The ad metadata should be passed for each individual ad.
See Czech SDK Metadata.

Step 4 : Call Nielsen APIs

The method for calling SDK API events is ggPM().

nSdkInstance.ggPM('eventName', parameter);

Type of SDK Events

Event Parameter Description Example
loadMetadata content or ad metadata JSON Needs to be called at the beginning of each asset nSdkInstance.ggPM("loadMetadata", metadataObjectContent)
setPlayheadPosition playhead position in seconds as integer Pass playhead position every second during playback. for VOD: pass current position in seconds. for Live: current Unix timestamp (seconds since Jan-1-1970 UTC) - if it's possible to seek back in Live content, then pass related Unix timestamp (not current) nSdkInstance.ggPM("setPlayheadPosition", currentPosition);
stop playhead position in seconds as integer Call when content or ads complete playing and pass playhead position, call stop when pausing playback nSdkInstance.ggPM("stop", parseInt(playerPosition));
end playhead position in seconds as integer Call when the current video asset completes playback and pass the playhead position. nSdkInstance.ggPM("end", parseInt(playerPosition));
  • 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.
  • If 1st video in playlist is content - call 'loadMetadata' for content. If 1st video in playlist is ad (not content), call 'loadMetadata' for content and than 'loadMetadata' for add - see below SDK Event Lifecycle.
  • For Ad Pods, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.
  • When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.
  • If last video in playlist is content (not ad) - call 'end' at the end of playlist. If last video in playlist in ad (not content), than call 'end' at the end of content video and stop at the end of ad - see bellow SDK Event Sequence. Summary: call 'end' at the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.

SDK Event Sequence

The sample event life-cycle can be used as a reference for identifying the order for calling events.

Playlist for this sample is : preRoll → content → midRoll → content resumed → postRoll


// START OF STREAM
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);

// PREROLL
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
//
//   pass playhead every second
//
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
nSdkInstance.ggPM('stop', playheadPosition);

// CONTENT
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
//
//   pass playhead every second
//
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);

// MIDROLL
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
//
//   pass playhead every second
//
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
nSdkInstance.ggPM('stop', playheadPosition);

// CONTENT
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
//
//   pass playhead every second
//
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
nSdkInstance.ggPM('end', playheadPosition);

// POSTROLL
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
//
//   pass playhead every second
//
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);
nSdkInstance.ggPM('stop', playheadPosition);


Step 5 : Interrupt Scenarios

Even when user or system interrupts playback you have to make sure that such interrupt will be handles as follows:

Pause Event

To indicate pause, stop passing the playhead position to the SDK and call STOP event. Once the content resumes, begin sending the playhead again with the correct playhead value.

Other Interrupt Scenarios

The following possible browser interruption scenarios must be handled:

  • Browser/Tab close
  • Leaving the page to another destination
  • Pressing the stop button

There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. ad vs. content).

window.addEventListener('beforeunload', function(event)
{
  // indicate <stop> inside ad
  nSdkInstance.ggPM('stop', playheadPosition);

  // indicate <end> and <stop> for the content
  nSdkInstance.ggPM('end', playheadPosition);
  nSdkInstance.ggPM('stop', playheadPosition);
});

Note: User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer).

Step 6 : Nielsen 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 <a href=http://cdn-gl.imrworldwide.com/priv/browser/cz/cs/optout.html>Nielsen Digital Measurement Privacy Policy</a>

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 7 : Test your player by yourself

See how to test the player at https://www.youtube.com/watch?v=t9eUsf9yh8w

Test SDK API calls

Use the Chrome and install add-on to verify SDK API calls: "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 8 : Provide your app for certification

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

Step 9 : Going Live

After the integration has been certified (but not prior that), users will need to disable debug logging by deleting {nol_sdkDebug: 'DEBUG'} from initialization call - see Step 2.

Demos

See live demos with sample implementation available at http://sdkdemo.admosphere.cz/