Browser Simplified API Static Metadata: Difference between revisions

From Engineering Client Portal

No edit summary
No edit summary
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR & DTVR}}  {{CurrentBreadcrumb}}
<!--{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR & DTVR}}  {{CurrentBreadcrumb}}
[[Category:Digital]]
[[Category:Digital]]
 
-->
__NOTOC__
<!--
== Prerequisites ==
== Prerequisites ==
-->
= Using the Simplified SDK for Static Measurement for Browser =
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.
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.
<syntaxhighlight lang="javascript">'PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</syntaxhighlight>
<syntaxhighlight lang="javascript">'PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'</syntaxhighlight>
Line 97: Line 101:
var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", {
var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", {
   nol_sdkDebug: "debug",
   nol_sdkDebug: "debug",
   outout: "false"
   optout: "false"
});
});
</script></syntaxhighlight>
</script></syntaxhighlight>
Line 205: Line 209:
</syntaxhighlight>
</syntaxhighlight>
=== Json Examples ===
=== Json Examples ===
[https://engineeringportal.nielsen.com/docs/Digital_Measurement_Simplified_SDK_Supplements Addtional JSON input object examples.]
[https://engineeringportal.nielsen.com/docs/Digital_Measurement_Simplified_API_Supplements Additional JSON input object examples.]
{{Template:Browser_Privacy_and_Opt-Out}}
{{Template:Browser_Privacy_and_Opt-Out}}


Line 214: Line 218:


<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", { outout: "false"});
var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", { optout: "false"});
</syntaxhighlight>
</syntaxhighlight>


== Sample Code ==
== Sample Code ==
This code is for example purposes only to demonstrate a very simple video implementation, with a single preroll and single content block.
This code is for example purposes only to demonstrate the code required for static measurement.
<syntaxhighlight lang=javascript>
<syntaxhighlight lang=javascript>
<script >
<script >
  // Setup videojs sample player
    /***************** Static Queue Snippet *********************/
  var nielsenid = document.getElementById("my-sdkplayer");
    ! function(t, n) {
var coolPlayer = videojs('my-sdkplayer', {
        t[n] = t[n] || {
  controls: true,
            nlsQ: function(e, c, o, r, s, i) {
  autoplay: true,
                return s = t.document,
  preload: 'auto',
                    r = s.createElement("script"),
});
                    r.async = 1,
var prevPos = null;
                    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>
</head>


coolPlayer.preroll({
<body >
  src: {
    <script >
     src: "assets/CleaningCrew.mp4",
     /**
     type: "video/mp4"
    * SDK Initialization to engtestsite.com domain
  },
    */
  href: "http://videojs.com",
     // Initialize instance
  adsOptions: {
    var nSdkInstance = NOLBUNDLE.nlsQ('P00BEB680-1F1A-47BB-922D-1BXXXXXXXXXX', 'dcrVideoInstance', {
     debug: true
        containerID: "my-sdkplayer",
  }
        nol_sdkDebug: "debug"
});
     });


videojs('my-sdkplayer').ready(function() {
var pathArray = window.location.pathname.split('/');
  // EXAMPLE: Start playing the video.
NURL = pathArray[2];


  coolPlayer.play();
var obj = {
  var obj = {
     event: 'playhead', // playhead,pause,complete,adstop
     event: 'playhead', // playhead,pause,complete,adstop
     type: 'content',
     type: 'static',
     playheadPosition: '0',
     playheadPosition: '',
     metadata: {
     "metadata": {
      content: {
        "content": {},
        type: 'content',
         "ad": {},
         assetid: 'VID98-2B88',
         "static": {
         program: 'Put a programname here ',
            type: 'static',
        title: 'S01E02',
            section: NURL,
        length: '180',
            assetid: 'AID885-9984',
        airdate: '20190101 10:01:00',
            segA: 'NielsenEnt',
        isfullepisode: 'y',
            segB: 'CustomSegB',
        crossId1: 'Standard Episode ID',
            segC: 'CustomSegC',
        crossID2: 'Content Originator',
            crossId1: "crossReference11",
        adloadtype: '2'
            reportSuite: "123"
      },
         }
      ad: {},
      static: {}
    }
  };
 
    coolPlayer.on('timeupdate', function() {
        var getcurrentTime = coolPlayer.currentTime();
        var intPlayedTime = parseInt(getcurrentTime, 10);
         if (intPlayedTime > 0 && intPlayedTime !== prevPos && !coolPlayer.scrubbing()) {
            // check for playhead change so it's only called once per second
            console.log('PLAYHEAD EVENT **************************************************************');
            console.log(Math.round(getcurrentTime));
            obj.event = 'playhead';
            obj.type = 'content';
            obj.metadata.ad = {};
            prevPos = intPlayedTime;
            obj.playheadPosition = Math.round(getcurrentTime);
            nSdkInstance.trackEvent(obj);
     }
     }
  });
};
 
  this.on('adstart', function() {
    console.log('ADSTART EVENT **************************************************************');
    obj.type = 'ad';
    obj.metadata.ad = {
      type: 'preroll',
      assetid: 'AD9455',
      adldx: '1',
      program: 'Cant Skip Campaign',
      title: 'Cleaning Crew',
      length: '36',
    };
    nSdkInstance.trackEvent(obj);
  });
 
  this.on('contentresumed', function() {
    console.log('CONTENT RESUMED EVENT **************************************************************');
    obj.type = 'content';
    obj.event = 'playhead';
    obj.metadata.ad = {};
    nSdkInstance.trackEvent(obj);
  });
 
  this.on('pause', function() {
    console.log('PAUSE EVENT **************************************************************');
    obj.event = 'pause';
    obj.playheadPosition = Math.round(coolPlayer.currentTime());
    nSdkInstance.trackEvent(obj);
  });


  this.on('adtimeupdate', function() {
nSdkInstance.trackEvent(obj);
    var getcurrentTime = coolPlayer.currentTime();
    var intPlayedTime = parseInt(getcurrentTime, 10);
    if (intPlayedTime > 0 && intPlayedTime !== prevPos) {
      // check for playhead change so it's only called once per second
      console.log('AD PLAYHEAD EVENT **************************************************************');
      console.log(Math.round(getcurrentTime));
      prevPos = intPlayedTime;
      obj.playheadPosition = Math.round(getcurrentTime);
      nSdkInstance.trackEvent(obj);
    };
  });


  this.on('adend', function() {
    console.log('AD STOP EVENT **************************************************************');
    obj.event = 'adstop';
    nSdkInstance.trackEvent(obj);
  });
  this.on('ended', function() {
    console.log('COMPLETE EVENT **************************************************************');
    obj.event = 'complete';
    nSdkInstance.trackEvent(obj);
  });
});
</script>
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 00:56, 8 May 2019


Using the Simplified SDK for Static Measurement for Browser

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.

'PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'

Configure SDK

There are two steps required for configuring the SDK:

  • Add Static Queue Snippet
  • Create SDK Instance

Add Static Queue Snippet

Add the following script tag to 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.

Create SDK Instance

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

Initialization API Call

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


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"})"
optout OptOut global parameter (Optional Parameter) 1/0 or true/false

Example SDK Initialization

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

More information on OptOut Parameter under Privacy and Opt-Out.

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",
  optout: "false"
});
</script>

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})

Handling 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 | UNIX timestamp (seconds since Jan-1-1970 UTC) >,
 "id3Data": <id3 payload>,
}


Event Types

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 or id3 payload, 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.

NOTE: Since only recording static data, playheadposition = ""

Static Metadata

The values passed through the Nielsen keys will determine the breakouts that are seen in reporting. The custom segments (A, B & C) will roll into the sub-brand. To not use custom segments A, B and C, do not pass any value in these keys.

Key Description Data Type Value Required?
assetid Unique ID for each article dynamic custom
(no Special Characters)
Yes
section Section of each site which is limited to 25 unique values
(e.g. section value should be first level in page URL: website.com/section).
dynamic custom Yes
segA custom segment for reporting: Limit to 25 unique values across custom segments
(segA + segB + segC)
dynamic custom No
segB custom segment for reporting: Limit to 25 unique values across custom segments
(segA + segB + segC)
dynamic custom No
segC custom segment for reporting: Limit to 25 unique values across custom segments
(segA + segB + segC)
dynamic custom No

Aggregation Limits There are limits on the number of unique values that can be aggregated on in reporting. The specific limitations by key are:

Key Aggregation Limit
section maximum of 25 unique values (section <= 25)
segA Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)
segB Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)
segC Maximum number of unique values allowed across segA, segB, and segC is 25 (segA + segB + segC<= 25)

Static Metadata Sample

// Sample input Object for static metadata
// Since only recording static data, playheadposition = ""
{ 
   "metadata": { 
      "content": {},
      "ad": {},
      "static": { 
         "type":"static",
         "assetid":"Static1",
         "section":"Page",
         "segA":"S07E04:NBC",
         "segB":"teams",
         "segC":"Atlanta",
         "crossId1":"Reference"
      }
   },
   "event": "playhead",
   "type": "static",
   "playheadPosition": "",
}

Json Examples

Additional JSON input object examples.

Privacy and Opt-Out

There are two primary methods for implementing user Opt-out preferences:

  1. User Opt Out - Provide a link to the Nielsen Privacy Policy page when a User can make their selection
  2. Initialization Opt Out - Global OptOut Parameter

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 User Opt-Out option, include the following two items in your privacy policy.

  • A notice that the player (or page in relation to static measurement) 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 at https://www.nielsen.com/digitalprivacy

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 via this link, their browser cookies will contain the value TOTAL_OPTOUT. This will prevent a redirect to our data provider from occurring
  • Users can opt back in via this link. When a user selects that link, their opt-out cookie will be deleted and they will be able to be measured moving forward.


The following paragraph is a template for a Privacy Statement.

The properties may feature Nielsen proprietary measurement software, which will allow users to contribute to market research, such as Nielsen TV Ratings. To learn more about the information that Nielsen software may collect and your choices with regard to it, please see the Nielsen Digital Measurement Privacy Policy at https://www.nielsen.com/digitalprivacy

User Opt Back In

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.

Initialization Opt Out

The BSDK600 now supports the ability to optout on initialization of the SDK by allowing an optout global parameter to be passed. This optout will be maintained through the session of the SDK instance. Specifications and limitations are specified below.

Type Supported Values Notes Optout
optout True, Yes, or 1 Case is insensitive and can be string or bool

Example: nlsQ("XXXXXXXX-BH45-JKY6-BKH7-67GJKY68GJK7", "myInstance", { optout: true});

Ping parameter will set uoo=true.
optout False, No, or 0 Case is insensitive and can be string or bool

Example: nlsQ("XXXXXXXX-BH45-JKY6-BKH7-67GJKY68GJK7", "myInstance", { optout: false});

Ping parameter will set uoo to blank.

Example of using OptOut

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

Opt Out Overview

Browser Cookie uoo value in session ping Final Optout Status
Default Value no uoo value or uoo=0 Not Opted Out
Default Value uoo=1 Opted Out
TOTAL_OPTOUT uoo=0 Opted Out
TOTAL_OPTOUT uoo=1 Opted Out

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. Example Production Initialization Call

var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", { optout: "false"});

Sample Code

This code is for example purposes only to demonstrate the code required for static measurement.

<script >
    /***************** 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>
</head>

<body >
    <script >
    /**
     * SDK Initialization to engtestsite.com domain
     */
    // Initialize instance 
    var nSdkInstance = NOLBUNDLE.nlsQ('P00BEB680-1F1A-47BB-922D-1BXXXXXXXXXX', 'dcrVideoInstance', {
        containerID: "my-sdkplayer",
        nol_sdkDebug: "debug"
    });

var pathArray = window.location.pathname.split('/');
NURL = pathArray[2];

var obj = {
    event: 'playhead', // playhead,pause,complete,adstop
    type: 'static',
    playheadPosition: '',
    "metadata": {
        "content": {},
        "ad": {},
        "static": {
            type: 'static',
            section: NURL,
            assetid: 'AID885-9984',
            segA: 'NielsenEnt',
            segB: 'CustomSegB',
            segC: 'CustomSegC',
            crossId1: "crossReference11",
            reportSuite: "123"
        }
    }
};

nSdkInstance.trackEvent(obj);