BSDK Step By Step

From Engineering Client Portal

Engineering Portal / Digital / BSDK Step By Step


Provided below are step-by-step quick start guides for implementing Nielsen Browser SDK for DCR Static, DCR Video, and DTVR products. Click each section to get started.

→ BSDK DCR Static

Show/hide DCR Static

BSDK DCR Static Introduction

Show/hide Intro

The Digital Content Ratings (DCR) Static product provides content consumption measurement on client webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points. This tutorial provides the steps to implement the DCR Static product on a standard HTML webpage. It includes:

  • Static Queue Snippet: allows for SDK API calls while SDK and configuration file is loading onto page
  • SDK Initialization Call: initializes the SDK and static configuration file
  • DCR Static Metadata: information about the page(s) being tracked
  • staticStart Event: event that starts SDK measurement


By the end of this guide you'll have a webpage that is running Nielsen's Browser SDK in the background:
BSDK DCR Static Ex.png

BSDK DCR Static Step 1 - Obtain AppID

Show/hide step 1

To begin using the Browser SDK (BSDK) you will need to obtain an Application ID (AppId)

Item Description Source
App ID (appid) Unique ID assigned to the player/site and configured by product Contact your Nielsen TAM

The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the BSDK on the webpage.
Example: PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX

BSDK DCR Static Step 2 - Add Static Queue Snippet

Show/hide step 2

Create HTML page in your preferred editor. In order for SDK to begin tracking, the following code snippet up must be added in a <script> tag to be inserted in <head> tag of the HTML page.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DCR Static Sample Page</title>
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
  <style>
  body,h1,h2,h3,h4,h5 {font-family: "Raleway", sans-serif}
  </style>
  <script>
    // Static Queue Snippet
    !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");
  </script>
</head>
<body>
</body>
</html>

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.

BSDK DCR Static Step 3 - Make SDK Initialization Call

Show/hide step 3

Create a variable named nSdkInstance and initialize SDK by passing in your App ID into the NOLBUNDLE.nslq() method. Add the following code after the static queue snippet code:

// SDK Initialization call
var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX", "staticPage", {
  nol_sdkDebug: 'debug' // ONLY FOR TESTING! REMOVE BEFORE MOVING TO PRODUCTION
});

When the initialization call is made, a unique static config file, PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX.js, will be loaded on to the page based on the appid and cached by the client-side browser(s). Once the static config file is loaded onto the page, the SDK (nlsSDK600.bundle.min.js) will be fully downloaded and initialized. The initialization call has three parameters:

Parameter Description Values
App ID (appid) Unique ID assigned to player/site PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
instanceName Name of SDK instance Any string value
options Options to be added during initialization nol_sdkDebug, optout

NOTE: REMOVE <nol_sdkDebug> OPTION BEFORE GOING INTO PRODUCTION RELEASE

BSDK DCR Static Step 4 - Create DCR Static Metadata Object

Show/hide step 4

Create metadata object which contains information about the static webpage. Add the following code after SDK initialization code:

// DCR Static Metadata Object
var nielsenMetadata = {
  type: 'static', // type of content [required]
  assetid: 'HHF887465-9486', // unique ID for each article [required]
  section: 'HOME', //  section of site [required]
  segA: '', // custom segment [optional]
  segB: '', // custom segment [optional]
  segC: ''  // custom segment [optional]
};

Metadata Object Properties

Key Description Fixed/Dynamic Value Required?
type asset type fixed 'static' Yes
assetid Unique ID for each article dynamic custom (no Special Characters) Yes
section section of each site (e.g. section value should be first level in page URL: website.com/section). Limit to 25 unique values dynamic custom (no Special Characters) 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

Metadata can be passed through key-values using the Nielsen reserved keys. The tracking code includes the Nielsen reserved keys and placeholder values. Pass dynamic metadata for the keys with the value (e.g. section:)


BSDK DCR Static Step 5 - Call ggPM staticStart event

Show/hide step 5

Static Start Event

Make BSDK API call ggPM() passing in the event staticstart as the first parameter and metadata variable as the second parameter. Add the following code after creating your DCR Static metadata object:


nSdkInstance.ggPM('staticstart', staticMetadata);


The content metadata object is passed as a parameter when calling staticstart event.

Static End Event

Call the Browser SDK ggPM() API by passing in the event staticend as the first parameter and metadata variable as the second parameter. In case metadata for another site section has been previously loaded, the staticend API call for that section should be made prior to loading in new metadata (different assetid/section) using a new staticstart API call.

nSdkInstance.ggPM('staticend', staticMetadata);

The content metadata object is passed as a parameter when calling staticend event.

The API call for staticend is not a requirement for all DCR Static integrations, however if client integration is a Single Page Application (SPA) it is imperative that staticend is called prior to the loading of new metadata. This allows the Browser SDK to properly credit the previous section/content being viewed before measuring the new one.

Do not place this call inside beforeunload browser event, because Browser SDK needs some time and resources to deliver data to the cloud.

NOTE: The information on staticend is provided here for reference. The demo site code does not make use of staticend.

BSDK DCR Static Step 6 - Update Page Content

Show/hide step 6

As mentioned in the Create Metadata Object section, the section metadata property correlates to the section of the website the user is currently on. Examples include the home, about, contact, etc. sections often found on webpages. To properly credit the section of the page the user is currently viewing, you must make sure that the section metadata property correctly corresponds with the section or page of the site that the user is currently on. If a user navigates to the contact section of our website (www.example.com/contact) we would have the following in our metadata object:


// DCR Static Metadata Object
var nielsenMetadata = {
  type: 'static', // type of content [required]
  assetid: 'HHF887465-9486', // unique ID for each article [required]
  section: 'CONTACT', //  section of site [required]
  segA: '', // custom segment [optional]
  segB: '', // custom segment [optional]
  segC: ''  // custom segment [optional]
};

Note: DCR Static is not currently supported in iframe windows.

Keep Going

Show/hide

Congratulations, you've successfully integrated the Browser SDK on your web page!

BSDK DCR Static Ex1.png

Final code output:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DCR Static Test Page</title>
  <script>
    // Static Queue Snippet
    !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");

    // SDK Initialization [update with your App Id]
    var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX", "staticPage", {
      nol_sdkDebug: "debug"
    });

// DCR Static Metadata Object
var nielsenMetadata = {
  type: 'static', // type of content [required]
  assetid: 'HHF887465-9486', // unique ID for each article [required]
  section: 'HOME', //  section of site [required]
  segA: '', // custom segment [optional]
  segB: '', // custom segment [optional]
  segC: ''  // custom segment [optional]
};

    // Call staticStart Event
    nSdkInstance.ggPM("staticstart", nielsenMetadata);
  </script>
</head>
<body class="w3-light-grey">
  <div class="w3-content" style="max-width:1400px">
    <header class="w3-container w3-center w3-padding-32"> 
    <h1><b>DCR Static Sample Web Page</b></h1>
    <p>Sample page with Nielsen's DCR Static Browser SDK integration</p>
  </header>
  <div class="w3-row">
  <div class="w3-col l8 s12">
    <div class="w3-card-4 w3-margin w3-white">
      <img src="/images/n-logo-aud.avif" alt="Nielsen" style="width: 60%;">
      <div class="w3-container">
        <h3><b>DCR Static</b></h3>
        <h5>Sample Page</h5>
      </div>
  
      <div class="w3-container">
        <p>Mauris neque quam, fermentum ut nisl vitae, convallis maximus nisl. Sed mattis nunc id lorem euismod placerat. Vivamus porttitor magna enim, ac accumsan tortor cursus at. Phasellus sed ultricies mi non congue ullam corper. Praesent tincidunt sed
          tellus ut rutrum. Sed vitae justo condimentum, porta lectus vitae, ultricies congue gravida diam non fringilla.</p>
        <div class="w3-row">
          <div class="w3-col m8 s12">
            <p><button class="w3-button w3-padding-large w3-white w3-border"><b>READ MORE »</b></button></p>
          </div>
          <div class="w3-col m4 w3-hide-small">
            <p><span class="w3-padding-large w3-right"><b>Comments  </b> <span class="w3-tag">0</span></span></p>
          </div>
        </div>
      </div>
    </div>
    <hr>
  </div>
  <div class="w3-col l4">
    <div class="w3-card w3-margin w3-margin-top">
    <img src="/images/arrows.jpeg" style="width: 100%; height: 300px;">
      <div class="w3-container w3-white">
        <h4><b>DCR Static</b></h4>
        <p>The Digital Content Ratings (DCR) Static product provides content consumption measurement on client webpages. This measurement includes insight into the total time a user spent on a webpage, how they navigated through the page via links, and many other data points.</p>
      </div>
    </div><hr>
    <hr> 
    <div class="w3-card w3-margin">
      <div class="w3-container w3-padding">
        <h4>Tags</h4>
      </div>
      <div class="w3-container w3-white">
      <p><span class="w3-tag w3-black w3-margin-bottom">DCR</span> <span class="w3-tag w3-light-grey w3-small w3-margin-bottom">Static</span> <span class="w3-tag w3-light-grey w3-small w3-margin-bottom">BSDK</span>
        <span class="w3-tag w3-light-grey w3-small w3-margin-bottom">Measurement</span> <span class="w3-tag w3-light-grey w3-small w3-margin-bottom">DCR</span>
      </p>
      </div>
    </div>
  </div>
  </div><br>
  </div>
  <footer class="w3-container w3-dark-grey w3-padding-32 w3-margin-top">
    <button class="w3-button w3-black w3-disabled w3-padding-large w3-margin-bottom">Previous</button>
    <button class="w3-button w3-black w3-padding-large w3-margin-bottom">Next »</button>
    <p>Powered by <a href="https://www.w3schools.com/w3css/default.asp" target="_blank">w3.css</a></p>
  </footer>  
</body>
</html>


Next Steps

Show/hide

Now that you've integrated DCR Static for the BSDK, what's next?

How to debug BSDK integration?

In your browser's dev tools menu (Chrome and Edge - press F12) you can inspect the various elements and sources. Here you can see pings being sent by the SDK and various JavaScript sources. Debug-level console logs will be shown if BSDK is debug mode (which you configured during this tutorial). BSDK DCR Static Ex1.png

Going Live

In addition to the basic steps above, before going live developers need to make certain privacy disclosures and allow users to opt out of Nielsen measurement. More details can be found here, along with a more comprehensive reference for implementing DCR Static measurement with BSDK.

Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, developers need to make a couple of updates to the initialization call to ensure that the site is being measured properly.

  1. App ID: Ensure that correct is used during initialization PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  2. Debug Logging: Disable logging by deleting {nol_sdkDebug: 'debug'} from initialization call.


PRODUCTION Initialization Call - Refer to the production initialization call below:


var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "staticPage");



→ BSDK DCR Video

Show/hide DCR Video


BSDK DCR Video Introduction

Show/hide Intro

The Digital Content Ratings (DCR) Video product provides content consumption measurement on client webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more. This example provides the steps to implement the DCR Video product using the HTML Video Embed Element. It includes:

  • Static Queue Snippet: allows for SDK API calls while SDK and configuration file is loading onto page
  • SDK Initialization Call: initializes the SDK and static configuration file
  • DCR Video Metadata: information about the player being tracked
  • Playhead Event Sequence: event(s) that starts and tracks player measurement

By the end of this guide you'll have a webpage that is running Nielsen's Browser SDK during video playback:
BSDK DCR Video EX.png

BSDK DCR Video Step 1 - Obtain AppID

Show/hide step 1

To begin using the Browser SDK (BSDK) you will need to obtain an Application ID (AppId)

Item Description Source
App ID (appid) Unique ID assigned to the player/site and configured by product Contact your Nielsen TAM

The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the BSDK on the webpage.
Example: PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX

BSDK DCR Video Step 2 - Add Static Queue Snippet

Show/hide step 2

Create HTML page in your preferred editor. In order for SDK to begin tracking, the following code snippet up must be added in a <script> tag to be inserted in <head> tag of the HTML page.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DCR Static Sample Page</title>
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
  <style>
  body,h1,h2,h3,h4,h5 {font-family: "Raleway", sans-serif}
  </style>
  <script>
    // Static Queue Snippet
    !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");
  </script>
</head>
<body>
</body>
</html>

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.

BSDK DCR Video Step 3 - Make SDK Initialization Call

Show/hide step 3

Create a variable named nSdkInstance and initialize SDK by passing in your App ID into the NOLBUNDLE.nslq() method. Add the following code after the static queue snippet code:

// SDK Initialization call
    var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "sdk-video-instance", {
      nol_sdkDebug: "debug" // ONLY FOR TESTING! REMOVE BEFORE MOVING TO PRODUCTION
    });

When the initialization call is made, a unique static config file, PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX.js, will be loaded on to the page based on the appid and cached by the client-side browser(s). Once the static config file is loaded onto the page, the SDK (nlsSDK600.bundle.min.js) will be fully downloaded and initialized. The initialization call has three parameters:

Parameter Description Values
App ID (appid) Unique ID assigned to player/site PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
instanceName Name of SDK instance Any string value
options Options to be added during initialization nol_sdkDebug, optout, enableFpid

NOTE: REMOVE <nol_sdkDebug> OPTION BEFORE GOING INTO PRODUCTION RELEASE

BSDK DCR Video Step 4 - Create DCR Video Content Metadata Object

Show/hide step 4

Create metadata object(s) which contains information about the video. There are two types of asset metadata:

  • content: identify video
  • ad: identify each ad
// DCR Video Metadata Object
var contentMetadataObject = {
  type: 'content', // type of content [required]
  assetid: 'VID-123456', // unique ID for each asset [required]
  program: 'program name', // name of program [required]
  title: 'episode title with season and episode number', // ex: S1E3 [required]
  length: 'length in seconds', // length of content [required]
  airdate: '20210321 09:00:00', // airdate of broadcast [required]
  isfullepisode: 'y', // long form content [required]
  adloadtype: '2', // type of ad load (linear/dynamic) [required]
  segB: 'custom segment B', // [optional]
  segC: 'custom segment C', // [optional]
  crossId1: 'Standard Episode ID', // [optional]
  crossId2: 'Content Originator' // [optional]
};

For this example, we are only going to create content metadata. For information on Ad integration click Digital Measurement Metadata and see "Ad Metadata" section.

Content Metadata Object Properties

Key Description Values Required? Provider
type asset type content Yes Nielsen
assetid Unique ID assigned to asset
Note: Refrain from using the following special characters Special Characters
Examples:
BBT345a234
CBSs5e234F2021
Yes Client
program Complete program or movie title (no abbreviations or shorthand)
Note: 25 character limit
Examples:
The Big Bang Theory
TheBigBangTheory
The Dark Knight
TheDarkKnight
Yes Client
title Episode title with season and episode number (40 character limit)
(Formats accepted: S01E03, S1E3, S1 E3)
Examples:
The Pants Alternative S03E18
The Pants Alternative S3E18
The Pants Alternative S3 E18
Can also accept:S3E18
Not Valid: 318 or 0318
Yes Client
crossId1 Gracenote TMS ID (If available) should be passed for all telecasted content for clients using the Gracenote solution for proper matching purposes
Note: The TMS ID will be a 14 character string. Normally leading with 2 alpha characters ('EP', 'MV', 'SH' or 'SP'), followed by 12 numbers
The TMS ID will be a 14 character string. Normally with 'EV,' 'EP', 'SH', 'SP', or 'MV' followed by 12 numbers after the initial two letter prefix.
Examples:
The Giant Morning Show:SH009311820022
The Pants Alternative Episode:EP009311820061
No Nielsen
crossId2 Populated by content distributor to contribute viewing from that distributor to the given content originator Custom
For a full list of acceptable values, please contact your Nielsen representative.
Yes, for distributors Nielsen
length Length of content in seconds
Note: Integers and decimals are acceptable values are acceptable for the length parameter
Examples:
For standard VOD content - 300 to represent 5 minutes, 1320to represent 22 minutes, etc.
If DAI live stream of a discrete program (Live Event/Sporting Event), pass length of content. See example for standard VOD content above.If unknown DAI live steam, pass a value of 0
Yes Client
airdate Original broadcast or release date for the program:
- For USA, date should be EST
- Outside USA, date should be local time
If not applicable or available, original broadcast or release date for the Program
Acceptable Formats:
YYYY-MM-DDTHH:MI:SS
YYYY-MM-DDHH:MI:SS
YYYY-MM-DDTHH:MI:SS+xx:xx
YYYY-MM-DDTHH:MI:SS-xx:xx
YYYYMMDDHH:MI:SS
YYYYMMDD HH:MI:SS
MM-DD-YYYY
MM/DD/YYYY
YYYYMMDD
Yes Client
isfullepisode Full episode flag to identify differences between long form content y - full episode
n - non full episode(clip,teaser,promo,etc.)
Also accept:
lf or yes - longform
sf or no - shortform
Yes Nielsen
adloadtype Type of ad load:
1 Linear - matches TV ad load
2 Dyanmic - Dynamic Ad Insertion (DAI)
DCR only uses '2' - DAI Yes Nielsen
segB One of two custom segments for clients' granular reporting within a brand Examples:
Genre- horror, comedy, etc.
Timeslot - primetime, daytime, etc.
News type - breakingnews, weather, etc.
No Client
segC One of two custom segments for clients' granular reporting within a brand Examples:
Genre- horror, comedy, etc.
Timeslot - primetime, daytime, etc.
News type - breakingnews, weather, etc.
No Client

Segment Information Custom segments (segB and segC) can be used to aggregate video and/or static content within a single Brand to receive more granular reports within a brand Examples regarding usage of segments within SDK:

  • All comedy clips and stories for a Brand rolled into a "Comedy" segment
  • Genre grouping content by Comedy vs. Drama
  • Group related Text + Video content, i.e. for a show that has a lot of - static pages associated with it
  • Packaging based on how clients sell inventory
  • Grouping related types of content either by genre, category or platform.


BSDK DCR Video Step 5 - Add Video Player

Show/hide step 5

Add the the video player element to the <body> of your HTML page:

<video controls src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4"
  poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217" width="620">

  Sorry, your browser doesn't support embedded videos,
  but don't worry, you can <a href="https://archive.org/details/BigBuckBunny_124">download it</a>
  and watch it with your favorite video player!
</video>

If you already have the video the element on the page then proceed to the next step to setup video event listeners.


BSDK DCR Video Step 6 - Set Up Event Listeners

Show/hide step 6

Setup Video Event Listeners In order for the SDK to process player events, you must attach the Browser SDK events to the corresponding player events, e.g. play, pause, and loadmetadata.

SDK Events

Event Parameter Description
loadMetadata content/ad metadata object Needs to be called at the beginning of each asset
setPlayheadPosition Playhead position as integer
For VOD: current position in seconds
For live content: current Unix timestamp (seconds since Jan-1-1970 UTC)
Note: setPlayheadPosition has to be called every second
Pass playhead position every second during playback
stop playhead position in seconds Call when content or ads complete playing and pass playhead position
end playhead position in seconds Call when the current video asset completes playback and pass the playhead position.
Example(s): At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.

Query video element
First we are going to create a video.js file and setup our event listeners for the video player:

// Setup Event Listeners w/ SDK Events

// Select the video element
const video = document.querySelector('video');


loadMetadata Event
Before SDK can begin crediting, the loadMetadata event must be called at the beginning of each asset by passing the contentMetadata object that was created in the previous step.

// Load contentMetadata object
video.addEventListener('loadedmetadata', (event) => {
  // Call SDK loadmetadata event
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject);
});


setPlayheadPosition Event
In order to accurately measure the time spent viewing you must pass in the playhead position of the video via the setPlayheadPosition event.

// Send playhead positions
let playheadPosition = 0;
video.addEventListener('timeupdate', (event) => {
  // Perform floor on currentTime property to get current position in seconds
  let currTime = Math.floor(video.currentTime);

  // Safety check to make sure current time is greater than 0
  if(0 < currTime) {
    playheadPosition = currTime;
    // Call SDK setplayheadposition event passing in the current playhead
    nSdkInstance.ggPM("setPlayheadPosition", playheadPosition);
  }
});


stop Event
If the player is paused at any time, need to call SDK's stop event and pass the current playhead position

// Handle Stop
video.addEventListener('pause', (event) => {
  nSdkInstance.ggPM("stop", playheadPosition);
});


end Event
Once the stream has completed playback, call the end event and pass the ending playhead position.

// Handle End
video.addEventListener('ended', (event) => {
  nSdkInstance.ggPM("end", playheadPosition);
});


Complete video.js file
Once complete the video.js file should look like this:

// Setup Event Listeners w/ SDK Events

// Select the video element
const video = document.querySelector('video');

// Load contentMetadata object
video.addEventListener('loadedmetadata', (event) => {
  // Call SDK loadmetadata event
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject);
});

// Send playhead positions
let playheadPosition = 0;
video.addEventListener('timeupdate', (event) => {
  // Perform floor on currentTime property to get current position in seconds
  let currTime = Math.floor(video.currentTime);

  // Safety check to make sure current time is greater than 0
  if(playheadPosition < currTime) {
    playheadPosition = currTime;
    // Call SDK setplayheadposition event passing in the current playhead
    nSdkInstance.ggPM("setPlayheadPosition", playheadPosition);
  }
});

// Handle Stop
video.addEventListener('pause', (event) => {
  nSdkInstance.ggPM("stop", playheadPosition);
});

// Handle End
video.addEventListener('ended', (event) => {
  nSdkInstance.ggPM("end", playheadPosition);
});


Be sure to add <script src="video.js"></script> right before the closing </body> tag in your HTML file!


Keep Going

Show/hide

Congratulations, you've successfully integrated the Browser SDK on your web page!

devtoolsbsd1.png

Final code output:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DCR Video Test Page</title>
  <script>
    // Static Queue Snippet
    !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");

    // Created SDK Instance
    var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "sdk-video-instance", {
      nol_sdkDebug: "debug"
    });

    var contentMetadataObject = {
      type: 'content', // type of content [required]
      assetid: 'VID-123456', // unique ID for each asset [required]
      program: 'program name', // name of program [required]
      title: 'episode title with season and episode number', // ex: S1E3 [required]
      length: 'length in seconds', // length of content [required]
      airdate: '20210321 09:00:00', // airdate of broadcast [required]
      isfullepisode: 'y', // long form content [required]
      adloadtype: '2', // type of ad load (linear/dynamic) [required]
      segB: 'custom segment B', // [optional]
      segC: 'custom segment C', // [optional]
      crossId1: 'Standard Episode ID', // [optional]
      crossId2: 'Content Originator' // [optional]
    };
  </script>
</head>

<body>
  <main>
    <h1>DCR Video Sample Page</h1>
    <div>
      <video controls src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4"
        poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217" width="620">

        Sorry, your browser doesn't support embedded videos,
        but don't worry, you can <a href="https://archive.org/details/BigBuckBunny_124">download it</a>
        and watch it with your favorite video player!
      </video>
    </div>
  </main>
  <script src="video.js"></script>r
</body>
</html>



video.js

// Setup Event Listeners w/ SDK Events

// Select the video element
const video = document.querySelector('video');

// Load contentMetadata object
video.addEventListener('loadedmetadata', (event) => {
  // Call SDK loadmetadata event
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject);
});

// Send playhead positions
let playheadPosition = 0;
video.addEventListener('timeupdate', (event) => {
  // Perform floor on currentTime property to get current position in seconds
  let currTime = Math.floor(video.currentTime);

  // Safety check to make sure current time is greater than 0
  if(playheadPosition < currTime) {
    playheadPosition = currTime;
    // Call SDK setplayheadposition event passing in the current playhead
    nSdkInstance.ggPM("setPlayheadPosition", playheadPosition);
  }
});

// Handle Stop
video.addEventListener('pause', (event) => {
  nSdkInstance.ggPM("stop", playheadPosition);
});

// Handle End
video.addEventListener('ended', (event) => {
  nSdkInstance.ggPM("end", playheadPosition);
});



Next Steps

Show/hide

Now that you've integrated the BSDK, what's next?

How to debug BSDK integration? In your browser's dev tools menu (Chrome and Edge - press F12) you can inspect the various elements and sources. Here you can see pings being sent by the SDK and various JavaScript sources. Debug-level console logs will be shown if BSDK is debug mode (which you configured during this tutorial). devtoolsbsd1.png

Going Live
Once the DCR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, users need to make a few updates to the initialization call to ensure that the site is being measured properly.

  1. App ID: Ensure that correct is used during initialization
    'PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
  2. Debug Logging: Disable logging by deleting {nol_sdkDebug: 'debug'} from initialization call.


PRODUCTION Initialization Call - Refer to the production initialization call below:

var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "sdk-video-instance");


→ BSDK DTVR Video

Show/hide DTVR

BSDK DTVR Introduction

Show/hide Intro

Digital TV Ratings(DTVR) enables the crediting of viewing from mobile and PC devices to linear TV content that carried the same linear ad load. Digital screens can include both computers and mobile devices such as smartphones and tablets. This viewing is captured using a census-based methodology through the Nielsen SDK. This example provides the steps to implement the DTVR product in live video stream. It includes:

  • Static Queue Snippet: allows for SDK API calls while SDK and configuration file is loading onto page
  • SDK Initialization Call: initializes the SDK and static configuration file
  • DTVR Metadata: information about the player being tracked
  • DTVR Event Sequence: event(s) that start and track DTVR measurement

By the end of this guide you'll have a webpage that is running Nielsen's Browser SDK during video playback:

BSDK DTVR Step 1 - Obtain AppID

Show/hide step 1

To begin using the Browser SDK (BSDK) you will need to obtain an Application ID (AppId)

Item Description Source
App ID (appid) Unique ID assigned to the player/site and configured by product Contact your Nielsen TAM

The appid is a 37 character unique ID assigned to the player/site and configured by product and is required when creating a new instance of the BSDK on the webpage.
Example: PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX

BSDK DTVR Step 2 - Add Static Queue Snippet

Show/hide step 2

Create HTML page in your preferred editor. In order for SDK to begin tracking DTVR content the following code snippet must be added in a <script> tag to be inserted in <head> tag of the HTML page.

The static queue snippet allows the SDK APIs to be called while the SDK and configuration file(s) are being downloaded. Once the files are downloaded and the SDK is initialized on the page, the SDK will begin to empty the queue. It will process the API calls/events from the queue first and then process subsequent ggPM calls.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DTVR Sample Page</title>
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
  <style>
  body,h1,h2,h3,h4,h5 {font-family: "Raleway", sans-serif}
  </style>
  <script>
    // Static Queue Snippet
    !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");
  </script>
</head>
<body>
</body>
</html>

BSDK DTVR Step 3 - Make SDK Initialization Call

Show/hide step 3

Create a variable named nSdkInstance and initialize SDK by passing in your App ID into the NOLBUNDLE.nslq() method. Add the following code after the static queue snippet code from the previous step:

// SDK Initialization call
    var nSdkInstance = NOLBUNDLE.nlsQ("PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "sdk-video-instance", {
      nol_sdkDebug: "debug" // ONLY FOR TESTING! REMOVE BEFORE MOVING TO PRODUCTION
    });

When the initialization call is made, a unique static config file, PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX.js, will be loaded on to the page based on the appid and cached by the client-side browser(s). Once the static config file is loaded onto the page, the SDK (nlsSDK600.bundle.min.js) will be fully downloaded and initialized.

The initialization call has three parameters:

Parameter Description Values
App ID (appid) Unique ID assigned to player/site PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
instanceName Name of SDK instance Any string value
options Options to be added during initialization nol_sdkDebug, optout, enableFpid

NOTE: REMOVE <nol_sdkDebug> OPTION BEFORE GOING INTO PRODUCTION RELEASE

BSDK DTVR Step 4 - Create DTVR Metadata Object

Show/hide step 4

The metadata received for each asset is used for classification and reporting. Metadata can be passed through key-values using the Nielsen reserved keys. User will need to set up content object with the required Nielsen keys as shown in the sample code below.

Content Metadata Object

Create a metadata object which contains ad related information present in the episode/live stream. Add the following code after SDK initialization code:

// DTVR Metadata Object
var contentMetadataObject = {
  type: 'content', // [required]
  adModel: '1' // [required]
};


  • Content metadata should remain constant throughout the completion of an episode or live stream.
Content Metadata Object Properties
Key Description Values Required?
type type of asset "content" yes
adModel linear vs dynamic ad model 1) - Linear – matches TV ad load
2) Dynamic – Dynamic Ad Insertion (DAI)
yes

BSDK DTVR Step 5 - SDK DTVR Event Sequence

Show/hide step 5

The sample event lifecycle can be used as a reference for identifying the order for calling events. Make BSDK API call ggPM() for metadata with first param as loadmetadata and second param as metadata, while for sending ID3 tag pass sendID3 as first param and ID3 payload as second param. Add the following code after creating your DTVR metadata object(s) from the previous step:

nSdkInstance.ggPM("loadMetadata", contentMetadataObject); 
nSdkInstance.ggPM("sendID3", ID3_Payload); // call sendID3 every 10 seconds and stop calling during any playback interruptions
SDK Event Parameters

The events listed below are available for integration of the DTVR.

Event Parameter Description
"loadMetadata" content/Ad metadata object Needs to be called at the beginning of each asset to pass type and adModel
"sendID3" Used to send the ID3 tag payload retrieved from the stream Needs to be called at the beginning of playback
"setVolume" Used to pass in the player volume levels in % Needs to be called when the player volume changes. This is applicable only for Audibility feature.
ID3 Tags

ID3_Payload is the container to pass the retrieved ID3 tag from the stream. The player should look for 'PRIV' ID3 tags and send 'owner' field (which typically starts from "www.nielsen.com") through this API. Refer to DTVR Event Listeners section below for more information.

Sample ID3 Tags

www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_<wbr />JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00

www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGhe<wbr />Fi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8<wbr />QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00

BSDK DTVR Step 6 - DTVR Event Listeners

Show/hide step 6

Event Listeners

In the prior section, we went over the SDK event sequence required for DTVR measurement. If the stream contains ads then you must use the loadMetadata API call to indicate the type of ads (linear or dynamic) at the beginning of the stream/when the player starts to play. The method for ID3 extraction is going to be dependent on the video player that it used. It must have methods that allow for ID3 extraction so the client can supply them to the Browser SDK based on the HLS standard. When reading the payload metadata from the stream you'll want to look for "www.nielsen.com" which will indicate the start of the ID3 tag.

Refer to retrieve id3 tag for more information

BSDK DTVR Step 7 - Keep Going

Show/hide step 7

Keep Going

Congratulations, your video player should have Browser SDK integration with DTVR measurement.

Next Steps
Now that you've integrated the BSDK, what's next?

Going Live
Once the DTVR Tracking Code is added, Nielsen will validate the implementation. Following Nielsen testing, users need to make a couple of updates to the initialization call to ensure that the site is being measured properly.


App ID: Ensure that correct is used during initialization 'PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'


Debug Logging: Disable logging by deleting {nol_sdkDebug: 'debug'} from initialization call.

PRODUCTION Initialization Call - Refer to the production initialization call below:

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