Browser SDK API Reference: Difference between revisions

From Engineering Client Portal

No edit summary
(Use anchor)
 
(42 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}
{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}
[[Category:Digital]]
[[Category:Digital]]
== Setting up Development Environment ==
=== Step 1: Configure Content Management System (CMS) ===
Configure CMS to send the required values (see table below). Any internal CMS_variable names can be used for passing the data.
Ensure to capture these CMS_variable names in the SDK Configuration Form.
For more information on setting variable names, see the SDK Configuration Form included within the SDK package.
{| class="wikitable"
|-
! Required Data !! Description !! Value
|-
| dataSrc || Used when both CMS metadata and ID3 data are present in the player. Setting this field tells the SDK whether to use the CMS metadata or the ID3 payload to derive the pings || cms
|-
| type || Type of asset: ad or content || preroll, midroll, postroll, or content
|-
| assetid || unique ID assigned to asset || custom <br>(no [[Special Characters]])
|-
| OCR Tag || OCR tag provided by Nielsen for implementation on the ad unit || Complete OCR URL
|-
| program || Name of program (25 character limit) || custom
|-
| title || Episode title (40 character limit) || custom
|-
| length || Length of content in seconds || Length in seconds, 0 for live stream
|-
| adloadtype || Type of ad load || "1" - Linear "2" - Dynamic(default)
|-
| hasAds || Identify if content includes Ads ||  "0" - no ads "1" - includes ads "2" - unknown(default)
|-
| isfullepisode || Full episode flag || "y" - full episode "n" - non full episode
|-
| segA || Segment A (this is not available for video reporting as the episode title is reported) || custom value
|-
| segB || Custom segment B || custom value
|-
| segC || Custom segment C || custom value
|-
| crossId1 || Standard episode ID || custom value
|-
| crossId2 || Content originator (required only for distributors) || custom value
|-
| airdate || Original air date and time in Eastern Time. For non-US countries, it should be local time. || YYYYMMDD HH24:MI:SS
|-
| containerId || HTML DOM element of the Player container (for Viewability&Audibility feature only) || custom value
|}
=== Step 2: Complete the Nielsen SDK Configuration Form ===
The SDK is designed to map the <code>CMS_variable names</code>. To support the custom mapping, the developer is required to complete the SDK Configuration Form. The form will be provided during onboarding along with this guide.
== Initialization ==
=== Obtain the Nielsen Application ID (apid) and Browser SDK URLs ===
The Nielsen <code>apid</code> is required to enable SDK functionality. Technical Account Manager will provide an apid for each player configuration. 
Browser SDK can support URLs that use any of the protocols – HTTPS and HTTP. 
=== Configure Browser SDK ===
There are two steps required for configuring the SDK:
'''Add Static Queue Snippet'''
*Add Static Queue Snippet
*Create SDK Instance
Add the following script tag to the website:
<syntaxhighlight lang="javascript">
<script type="text/javascript">
    // 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>
</syntaxhighlight>
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'''
<syntaxhighlight lang="javascript">
NOLBUNDLE.nlsQ("<apid>", "<instanceName>",{nol_sdkDebug: "debug"})
</syntaxhighlight>
When creating an instance, pass the following three values:
=== SDK Initialization – Global Parameters <span class="anchor" id="SDK Initialization Global Parameters"></span> ===
{| class="wikitable"
|-
! Parameters !! Description !! Value
|-
| apid || UniqueID assigned to player/site. || 'XXXXXXXX-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"})"
|-
| containerId || HTML DOM element id of the player container. Only for Viewability & Audibility feature. || {containerId: "playerId1"}
|-
| hem_sha256 || SHA256-hashed email address (client-supplied unique 32-character hexadecimal string) || "tMmiiTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ="
|-
| hem_sha1 || SHA1-hashed email address (client-supplied unique 32-character hexadecimal string) || "XvBniTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ="
|-
| hem_md5 || MD5-hashed email address (client-supplied unique 32-character hexadecimal string) || "JnIbdTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ="
|-
| uid2 || An identifier based on a user’s verifiable PII (e.g. hashed email). UID2.0 was initially created by The Trade Desk (TTD) and is now managed by Prebid. || "MTKVpUAzwYAPnHrtfE0wlINOMzhU7UUEjjVdCdRu63k="
|-
| uid2_token || Encrypted Unified ID 2.0 || "AgAAAAPFR0zA5ogv/yaAPiUsAdZPsfqS8Ql
DSGxAB+rr8yekFs3AjLYVk5qqqiyV2XHbSuwzHmxSlLeQeK
QI1mp015jsNnpX5/xGgXldcgVz+gFnyh3T8/3agMwRmyrhC
xG4oH2C7fc48AQk2eotE7FW0ZDEYM8fD9ZxDaxFUC/OV3OuZA&"
|-
|luid
|Living Unit ID - Experian Household ID
'''Note: This parameter is applicable only for CTV and First Party Livestream data'''
|"B0EOFEDgD"
|}
{{example_bsdk_init}}
'''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:
<syntaxhighlight lang="javascript">
<script type="text/javascript">
!function(t,n)
{
  t[n]=t[n]||
  {
    nlsQ:function(e,o,c,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="+o+"&ns="+n,
    i=s.getElementsByTagName("script")[0],
    i.parentNode.insertBefore(r,i),
    t[n][o]=t[n][o]||{g:c||{},
    ggPM:function(e,c,r,s,i){(t[n][o].q=t[n][o].q||[]).push([e,c,r,s,i])}},t[n][o]
    }
  }
}
(window,"NOLBUNDLE");
  // Created SDK Instance
  var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX","nlsnInstance", {nol_sdkDebug: "debug"});
</script>
</syntaxhighlight>
=== Multiple SDK Instances ===
The Browser SDK allows instantiating multiple instances of the object, which can be used simultaneously without any problems, however they must be instantiated with their own unique instance names. There is no maximum number of instances that is enforced in the browser.
The below examples will make use of the same AppId, however using different AppIds will work as well. The principles below follow the same initialization rules stated above for a single instance and simply require a unique instance name and variable name with which the returned instance is assigned.
For more information around the possible parameters that can be passed as well as deeper descriptions for the API calls, please refer to the section on [[#SDK Initialization Global Parameters|'''SDK Initialization - Global Parameters''']].
'''Example of 2 instances on the same page'''
<syntaxhighlight lang="javascript">
//Add Static Queue Snippet
<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");
    //Create SDK Instance(s)
    // Notice the unique instance name given to each instance below and the unique variable name for each instance
    var nSdkInstanceLive = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "instanceLive", {
        nol_sdkDebug: 'debug',
        optout: 'false'
    });
    var nSdkInstanceVod = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "instanceVod", {
        nol_sdkDebug: 'debug',
        optout: 'false'
    });
</script>
</syntaxhighlight>
'''Example of 2 instances using a parent page and iFrame'''
<big>Parent Page (index.html)</big>
<syntaxhighlight lang="javascript">
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>DCR Static/DCR Video</title>
  <script>
    /* NLSQUEUE build v*/
    !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
    var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "staticPage", {
      nol_sdkDebug: 'debug',
    });
    // Static Metadata
    var staticMetadata = {
      assetid: 'staticTestPage',
      type: 'static'
    };
    // Event 'staticstart' call
    nSdkInstance.ggPM(14, staticMetadata);
  </script>
</head>
<body>
  <h1>DCR Static on Parent/DCR Video in iFrame</h1>
  <p>Static measurement is current on parent page when window is in focus</p>
  <iframe src="./dcr-video.html" frameborder="0" width="650" height="500" style="background-color: rgb(42, 217, 248);" id="video-iframe"></iframe>
</body>
</html>
</syntaxhighlight>
<big>Nested iFrame Referenced on Parent Page (dcr-video.html)</big>
<syntaxhighlight lang="javascript">
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>iFrame Same Source</title>
    <script>
    /* NLSQUEUE build v*/
    !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
    var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "videoPlayer", {
      nol_sdkDebug: 'debug',
    });
    var contentMetadata = {
        type: "content",
        length: "300",
        title: "Skydiving Across Europe",
        program: "latacg",
        censuscategory: "Enlisted",
        assetid: "204558915992",
        section: "ProgramAsset8",
        tv: "true",
        adModel: "0",
        dataSrc: "cms",
        segA: "S07E04:NBC",
        segB: "teams",
        segC:"AtlanataFalcons",
      }
  </script>
  </head>
  <body>
    <p>I'm iframe SDK DCR Video measurement, DCR static measurement should continue when clicking "play" on video</p>
    <main>
      <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>
    </main>
    <script src="../player.js"></script>
  </body>
</html>
</syntaxhighlight>
=== SDK Initialization to measure the Viewability & Audibility ===
To support viewability metrics in the web page the integrator has to provide a tag value of the player view to let Nielsen SDK know that there is a player that needs to be tracked. It’s called the ‘containerId’ and it should be passed in the as string while initializing the Nielsen browser SDK.
NOLBUNDLE.nlsQ("<apid>", "<instanceName>",{containerId: <playerElementID>, nol_sdkDebug: "debug"})
'''Example SDK Initialization for Viewability'''
Your configuration should include the Static Queue Snippet and an SDK Instance for your unique App ID as shown in the example:
<syntaxhighlight lang="javascript">
//Add Static Queue Snippet
<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");
//Create SDK Instance
var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", {containerId: “player1”, nol_sdkDebug: "debug"});
</script>
</syntaxhighlight>
== Browser SDK API Methods & Properties ==
== Browser SDK API Methods & Properties ==
{| class="wikitable sortable"
{| class="wikitable sortable"
|-
|-
! Method / Property !! Event # !! DTVR !! DAR !! Digital Audio !! DCR !! International (Germany) !! Description
! Method / Property !! Event # !! DTVR !! DAR !! DCR !! Description
|-
|-
| [[loadMetadata (Browser)]] || 3 || ✔ || ✔ || ✔ || ✔ || ✔ || Used when there is a preroll ad that needs to be associated with content metadata. The loadMetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.
| [[loadMetadata (Browser)|loadMetadata]] || 15 || ✔ || ✔ || ✔ || Used when there is a preroll ad that needs to be associated with content metadata. The loadMetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.
|-
|-
| [[play (Browser)]] || 5 || ✔ || ✘ || ✘ || ✔ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. When the client passes in the channelName, they can change the CMS data stored by passing new values. If this event is not called then the “channel name” value populated will be the default value of “defaultChannelName”.
| [[play (Browser)|play]] || 5 || ✔ || ✘ || ✔ || Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. When the client passes in the channelName, they can change the CMS data stored by passing new values. If this event is not called then the “channel name” value populated will be the default value of “defaultChannelName”.
|-
| [[sendID3 (Browser)|sendID3]] || 55 || ✔ || ✘ || ✘ || Used to send the ID3 metadata.
|-
| [[setPlayheadPosition (Browser)|setPlayheadPosition]] || 49 || ✘ || ✘ || ✔ || Used to send the playhead position.
|-
| [[stop (Browser)|stop]] || 7 || ✘ || ✘ || ✔ || Used when switching between ad and content or content and ad.
|-
| [[end (Browser)|end]] || 57 || ✔ || ✘ || ✔ || This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content 3) when the browser is refreshed or closed
|-
| [[staticstart (Browser)|staticstart]] || 14 || ✘ || ✘ || ✔ || Used to send the metadata for the static page.
|-
| [[StaticEnd (Browser)|staticend]] || 56 || ✘ || ✘ || ✔ || In 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.
|-
| [[updateOTT (Browser)|updateOTT]] || - || ✘ || ✘ || ✔ || Used to notify Browser SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).
|-
| [[ onPaginate (Browser)|onPaginate]] || 30 || ✘ || ✘ || ✔ || Used to create a new instance of the SDK object
|-
| [[updateMetadata (Browser)|updateMetadata]] || 35 || ✔ || ✔ || ✔ || This event is used for updating metadata parameters for the content or ad that is being played.
|-
| [[setVolume_(Browser)|setVolume]] || 61 || ✔ || ✘ || ✔ || Used to pass in the player volume levels in %. Default value is -1.
|}
 
== Retrieving ID3 Tags ==
The video player must have the ability to extract ID3 tags and supply them to the Browser SDK, based on the HLS standard.
*An ID3 tag spans two PES packets.
**In the first PES packet, look for www.nielsen.com, this is the start of the ID3 tag. Continue to parse the first PES packet until the undefined char "\ufffd" is found. This forms the first half of the ID3 tag
**In the second PES packet, identify the end pattern – a regEx of /(\/\d+){3}/ and look to remove the lowest index of either "\x00" and/or "\ufffd". Now the second packet has been appended and the demarcation of the Nielsen-specific data has been defined.
 


'''VA Beacon:''' Called when content or ads start playing. The playhead position must be passed.
Follow the procedure below, to extract Nielsen ID3 tags from an MPEG-2 transport stream (including HLS streams).
#Parse the Program Map Table (PMT) to find the PID of the metadata stream. Confirm the presence of the metadata descriptor described in section 2.3.3 of Apple’s “HTTP Live Streaming Metadata Spec.pdf”. Only private streams with metadata descriptor present should be considered as ID3-tag metadata streams.
#Parse the HLS/Transport stream for any '''PES header''' with the PID found in step 1.
#Follow standard MPEG-2 parsing procedures to locate the start of the payload of the PES packet.
#Copy the PES payload into a buffer.
#The ID3 tag spans 2 PES packets. Parse the stream for the next packet whose PID is set to the PID found in step 1. Typically the ID3 Tag is of 249 bytes. The steps below guide towards extraction of the ID3 tag
##In the first PES packet, look for "www.nielsen.com" , this is the start of the ID3 tag. Keep on parsing the first PES packet until the undefined char "\ufffd" is found. This forms the first half of the ID3 tag
##In the second PES packet, identify the end pattern, a regEx of /(\/\d+){3}/ and look to remove the lowest index of either “\x00” and/or “\ufffd”. Now the second packet has been appended and the demarcation of the Nielsen specific data has been defined. This segment can be simply substringed.
##Concatenate this substringed segment with the payload derived from the first packet get the ID3 payload.
#Check the length of the contents in the buffer to make sure that it is equal to the size of a Nielsen ID3 tag.
#Ensure that the ID3 byte array is converted into the string and escape it, so that the SDK can consume it.
Repeat steps 2 through 7 for all ID3 tags in the stream.
 
'''References'''
*[http://www.iso.org/iso/catalogue_detail?csnumber=44169. ISO/IEC 13818-1:2007] Information technology – Generic coding of moving pictures and associated audio information: Systems
*https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/HTTP_Live_Streaming_Metadata_Spec/
 
=== Sample ID3 tags ===
* <code>www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_<wbr />JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00</code>
* <code>www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGhe<wbr />Fi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8<wbr />QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00</code>
<blockquote>'''Note''': ID3 tags are not applicable for International (Germany)</blockquote>
 
== Browser Opt-Out Implementation ==
The site in which video content is being measure via Nielsen methodology must provide the means for the user to opt-out of, or opt back into Nielsen Measurement.
 
For Browser-based applications, opt-out setting is stored via Nielsen cookie. Therefore, it is only necessary that users be made aware of measurement opt-out by incorporating the template below in the user interface.
 
=== Sample Opt Out Template ===
Our properties may feature Nielsen’s proprietary measurement software which will allow to contribute to market research, like Nielsen’s TV Ratings. To learn more about this information, see https://www.nielsen.com/digitalprivacy. Nielsen’s software may collect your choices with regards to it.
 
== Nielsen Privacy Requirements ==
Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.
*Disclosure of viewership data collection in EULA / Privacy Policy
*A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used
*Method for users to opt-out of Nielsen measurement, any time while using the application
 
=== Ratings Data Flow ===
Every view of creditable and watermarked content is measured by Nielsen.
[[File:RatingsDataFlow.png]]
 
'''Information NOT Shared'''
* '''With Nielsen'''
** User's Identity
* '''With Data Provider'''
** Content information
** Whether user is viewing an ad or video content
** Player used to play the streaming (audio / video, etc.)
** Values being de-duped / aggregating for
 
Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.
 
=== Data Collected ===
{| class="wikitable"
|-
! Type of Information !! Parameter !! Transmitted to Nielsen? !! Sent to Provider?
|-
| rowspan="8" | Nielsen ID3 Watermark
|-
| FinalDistributor Timestamp || Yes || No
|-
| Program Content Timestamp || Yes || No
|-
| Mobile Breakout Code || Yes || No
|-
| Commercial Credit Code – Linear or Dynamic || Yes || No
|-
| Time ShiftedViewing Code || Yes || No
|-
| Segment Number || Yes || No
|-
| Segment View Pattern || Yes || No
|-
|-
| [[sendID3 (Browser)]] || 55 || ✔ || ✘ || ✘ || ✘ || ✘ || Used to send the ID3 metadata.
| rowspan="7" | Device/App Info
|-
|-
| [[setPlayheadPosition (Browser)]] || 49 || ✘ || ✘ || ✔ || ✔ || ✔ || Used to send the playhead position.
| Device OSVersion || Yes || Yes
|-
|-
| [[stop (Browser)]] || 7 || ✘ || ✘ || ✘ || ✔ || ✔ || Used when switching between ad and content or content and ad.
| Device Model || Yes || No
|-
|-
| [[end (Browser)]] || 57 || ✔ || ✘ || ✔ || ✔ || ✔ || This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content 3) when the browser is refreshed or closed
| Cache Buster || Yes || Yes
|-
|-
| [[staticstart (Browser)]] || 14 || ✘ || ✘ || ✘ || ✔ || ✔ || Used to send the metadata for the static page.
| SDKDisabled Flag || Yes || No
|-
|-
| [[getOptOutStatus (Browser)]] || 4 || ✘ || ✘ || ✘ || ✘ || ✔ || '''VA Beacon Only:''' Sent only after calling stop. The current position must be passed. Not needed for new International (Germany) implementations.
| ServerCode || Yes || No
|-
|-
| [[updateOTT (Browser)]] || - || ✘ || ✘ || ✘ || ✘ || ✔ || Used to notify Browser SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).
| Channel or URL || Yes || No
|-
|-
| [[ onPaginate (Browser)]] || 30 || ✘ || ✘ || ✘ || ✔ || ✔ || Used to create a new instance of the SDK object
| rowspan="9" | Nielsen Identifiers
|-
|-
| [[updateMetadata (Browser)]] || 35 || || || || || || This event is used for updating metadata parameters for the content or ad that is being played.
| Client ID || Yes || No
|-
| Campaign ID || Yes || Yes
|-
| Nielsen Unique Device ID || Yes || No
|-
| Application ID || Yes || No
|-
| DeviceGroup (ex. Tablet, Smartphone, Desktop) || Yes || Yes
|-
| OS Group (ex. Android, iOS, Windows) || Yes || Yes
|-
| SDKVersion || Yes || No
|-
| IP Address for DMA, Country Code || Yes || Yes
|}
|}
<blockquote>'''Note''': Data is hashed, and encrypted using AES 128 before transmission to data provider.</blockquote>
{{Viewability_Data_Collected}}
==== Example ping sent to provider ====
* <code><nowiki>https://provider.com/cgi-bin/brandlift.php</nowiki>?campaign_id=ff12725d724fac7934cf6003f096b4cd<wbr />&placement_id=a4164b8fba9ee7c873a9c72c7091bb58<wbr />&creative_id=25280139b61a947e127a52f56c8a2fdd<wbr />&segment1=9000<wbr />&segment2=41<wbr />&segment3=iOS<wbr />&OSVer=iOS6.1<wbr />&c9=<wbr />&devgrp=tablet<wbr />&h=f5f243fe6d<wbr />&rnd=1376971827360</code>
This ping passes the following parameters to the provider:
* Campaign ID – (campaign, placement, creative)
* Country Code
* DMA
* OS Group (ex. iOS, Android)
* DeviceOS Version
* Device Advertiser ID
* DeviceGroup (ex. Tablet, Smartphone, Desktop)
* Cache Buster
{{Template:Browser_Privacy_and_Opt-Out}}
=== Opt-Out Implementation ===
The site must provide the means for the user to opt-out of, or opt back into Nielsen Measurement.
'''Sample Opt Out Template'''
Our properties may feature Nielsen’s proprietary measurement software which will allow to contribute to market research, like Nielsen’s TV Ratings. To learn more about this information, please [http://priv-policy.imrworldwide.com/priv/mobile/us/en/optout.html| click here]. Nielsen’s software may collect your choices with regards to it.
== Testing ==
See [[Digital Measurement Testing#Testing Browser Implementation|Digital Measurement Testing - Testing Browser Implementation]].

Latest revision as of 20:20, 11 December 2024

Engineering Portal / Digital / Browser SDK API Reference

Setting up Development Environment

Step 1: Configure Content Management System (CMS)

Configure CMS to send the required values (see table below). Any internal CMS_variable names can be used for passing the data.

Ensure to capture these CMS_variable names in the SDK Configuration Form.

For more information on setting variable names, see the SDK Configuration Form included within the SDK package.

Required Data Description Value
dataSrc Used when both CMS metadata and ID3 data are present in the player. Setting this field tells the SDK whether to use the CMS metadata or the ID3 payload to derive the pings cms
type Type of asset: ad or content preroll, midroll, postroll, or content
assetid unique ID assigned to asset custom
(no Special Characters)
OCR Tag OCR tag provided by Nielsen for implementation on the ad unit Complete OCR URL
program Name of program (25 character limit) custom
title Episode title (40 character limit) custom
length Length of content in seconds Length in seconds, 0 for live stream
adloadtype Type of ad load "1" - Linear "2" - Dynamic(default)
hasAds Identify if content includes Ads "0" - no ads "1" - includes ads "2" - unknown(default)
isfullepisode Full episode flag "y" - full episode "n" - non full episode
segA Segment A (this is not available for video reporting as the episode title is reported) custom value
segB Custom segment B custom value
segC Custom segment C custom value
crossId1 Standard episode ID custom value
crossId2 Content originator (required only for distributors) custom value
airdate Original air date and time in Eastern Time. For non-US countries, it should be local time. YYYYMMDD HH24:MI:SS
containerId HTML DOM element of the Player container (for Viewability&Audibility feature only) custom value

Step 2: Complete the Nielsen SDK Configuration Form

The SDK is designed to map the CMS_variable names. To support the custom mapping, the developer is required to complete the SDK Configuration Form. The form will be provided during onboarding along with this guide.

Initialization

Obtain the Nielsen Application ID (apid) and Browser SDK URLs

The Nielsen apid is required to enable SDK functionality. Technical Account Manager will provide an apid for each player configuration. Browser SDK can support URLs that use any of the protocols – HTTPS and HTTP.

Configure Browser SDK

There are two steps required for configuring the SDK:

Add Static Queue Snippet

  • Add Static Queue Snippet
  • Create SDK Instance

Add the following script tag to the website:

<script type="text/javascript">
    // 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>

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

When creating an instance, pass the following three values:

SDK Initialization – Global Parameters

Parameters Description Value
apid UniqueID assigned to player/site. 'XXXXXXXX-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"})"
containerId HTML DOM element id of the player container. Only for Viewability & Audibility feature. {containerId: "playerId1"}
hem_sha256 SHA256-hashed email address (client-supplied unique 32-character hexadecimal string) "tMmiiTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ="
hem_sha1 SHA1-hashed email address (client-supplied unique 32-character hexadecimal string) "XvBniTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ="
hem_md5 MD5-hashed email address (client-supplied unique 32-character hexadecimal string) "JnIbdTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ="
uid2 An identifier based on a user’s verifiable PII (e.g. hashed email). UID2.0 was initially created by The Trade Desk (TTD) and is now managed by Prebid. "MTKVpUAzwYAPnHrtfE0wlINOMzhU7UUEjjVdCdRu63k="
uid2_token Encrypted Unified ID 2.0 "AgAAAAPFR0zA5ogv/yaAPiUsAdZPsfqS8Ql

DSGxAB+rr8yekFs3AjLYVk5qqqiyV2XHbSuwzHmxSlLeQeK QI1mp015jsNnpX5/xGgXldcgVz+gFnyh3T8/3agMwRmyrhC xG4oH2C7fc48AQk2eotE7FW0ZDEYM8fD9ZxDaxFUC/OV3OuZA&"

luid Living Unit ID - Experian Household ID

Note: This parameter is applicable only for CTV and First Party Livestream data

"B0EOFEDgD"

Example SDK Initialization

var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "nlsnInstance", {nol_sdkDebug: "debug",
uid2:  "MTKVpUAzwYAPnHrtfE0wlINOMzhU7UUEjjVdCdRu63k=",
uid2_token: "AgAAAAPFR0zA5ogv/yaAPiUsAdZPsfqS8QlDSGxAB+rr8yekFs3AjLYVk5qqqiyV2XHbSuwzHmxSlLeQeKQI1mp015jsNnpX5/xGgXldcgVz+gFnyh3T8/3agMwRmyrhCxG4oH2C7fc48AQk2eotE7FW0ZDEYM8fD9ZxDaxFUC/OV3OuZA==",
hem_sha256: "e46f3f2c8c0e1d509aeb04d2fd78f0481c8520cb6769c258a50ddb98b073dabc",
hem_sha1: "",
hem_md5: ""
});

Note: The debug parameter, nol_sdkDebug, is only used for testing and should be removed before moving to production. The output is displayed in console debuggers when enabled..

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: “nlsSDK601.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">
!function(t,n)
{
  t[n]=t[n]||
  {
    nlsQ:function(e,o,c,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="+o+"&ns="+n,
     i=s.getElementsByTagName("script")[0],
     i.parentNode.insertBefore(r,i),
     t[n][o]=t[n][o]||{g:c||{},
     ggPM:function(e,c,r,s,i){(t[n][o].q=t[n][o].q||[]).push([e,c,r,s,i])}},t[n][o]
    }
  }
}
(window,"NOLBUNDLE");
  // Created SDK Instance
  var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX","nlsnInstance", {nol_sdkDebug: "debug"});
</script>

Multiple SDK Instances

The Browser SDK allows instantiating multiple instances of the object, which can be used simultaneously without any problems, however they must be instantiated with their own unique instance names. There is no maximum number of instances that is enforced in the browser.

The below examples will make use of the same AppId, however using different AppIds will work as well. The principles below follow the same initialization rules stated above for a single instance and simply require a unique instance name and variable name with which the returned instance is assigned.

For more information around the possible parameters that can be passed as well as deeper descriptions for the API calls, please refer to the section on SDK Initialization - Global Parameters.


Example of 2 instances on the same page


//Add Static Queue Snippet
<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");

    //Create SDK Instance(s)
    // Notice the unique instance name given to each instance below and the unique variable name for each instance
    var nSdkInstanceLive = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "instanceLive", {
        nol_sdkDebug: 'debug',
        optout: 'false'
    });

    var nSdkInstanceVod = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "instanceVod", {
        nol_sdkDebug: 'debug',
        optout: 'false'
    });

</script>

Example of 2 instances using a parent page and iFrame

Parent Page (index.html)


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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>DCR Static/DCR Video</title>
  <script>
    /* NLSQUEUE build v*/
    !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
    var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "staticPage", {
      nol_sdkDebug: 'debug',
    });

    // Static Metadata 
    var staticMetadata = {
      assetid: 'staticTestPage',
      type: 'static'
    };

    // Event 'staticstart' call
    nSdkInstance.ggPM(14, staticMetadata);
  </script>
</head>

<body>
  <h1>DCR Static on Parent/DCR Video in iFrame</h1>
  <p>Static measurement is current on parent page when window is in focus</p>
  <iframe src="./dcr-video.html" frameborder="0" width="650" height="500" style="background-color: rgb(42, 217, 248);" id="video-iframe"></iframe>
</body>

</html>


Nested iFrame Referenced on Parent Page (dcr-video.html)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>iFrame Same Source</title>
    <script>
    /* NLSQUEUE build v*/
    !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
    var nSdkInstance = NOLBUNDLE.nlsQ("XXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX", "videoPlayer", {
      nol_sdkDebug: 'debug',
    });

    var contentMetadata = {
        type: "content",
        length: "300",
        title: "Skydiving Across Europe",
        program: "latacg",
        censuscategory: "Enlisted",
        assetid: "204558915992",
        section: "ProgramAsset8",
        tv: "true",
        adModel: "0",
        dataSrc: "cms",
        segA: "S07E04:NBC",
        segB: "teams",
        segC:"AtlanataFalcons",
      }
  </script>
  </head>
  <body>
    <p>I'm iframe SDK DCR Video measurement, DCR static measurement should continue when clicking "play" on video</p>
    <main>
      <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>
    </main>
    <script src="../player.js"></script>
  </body>
</html>

SDK Initialization to measure the Viewability & Audibility

To support viewability metrics in the web page the integrator has to provide a tag value of the player view to let Nielsen SDK know that there is a player that needs to be tracked. It’s called the ‘containerId’ and it should be passed in the as string while initializing the Nielsen browser SDK.

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

Example SDK Initialization for Viewability

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

//Add Static Queue Snippet
<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");

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

Browser SDK API Methods & Properties

Method / Property Event # DTVR DAR DCR Description
loadMetadata 15 Used when there is a preroll ad that needs to be associated with content metadata. The loadMetadata will first be called to populate the content metadata values and then the loadMetadata for ad metadata will be called. This allows sending a content ping with the ad info, even if the user bails out during the preroll ad.
play 5 Used when there is an ID3 fed product such as DTVR and the client does not want to send in all the CMS metadata that is sent in loadMetadata. This allows the client to send in at least the required “channel name” value associated to the ID3 feed. When the client passes in the channelName, they can change the CMS data stored by passing new values. If this event is not called then the “channel name” value populated will be the default value of “defaultChannelName”.
sendID3 55 Used to send the ID3 metadata.
setPlayheadPosition 49 Used to send the playhead position.
stop 7 Used when switching between ad and content or content and ad.
end 57 This is triggered 1) at the end of the content stream, 2) if the user switches to another piece of content 3) when the browser is refreshed or closed
staticstart 14 Used to send the metadata for the static page.
staticend 56 In 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.
updateOTT - Used to notify Browser SDK that the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected / disconnected (change of OTT status).
onPaginate 30 Used to create a new instance of the SDK object
updateMetadata 35 This event is used for updating metadata parameters for the content or ad that is being played.
setVolume 61 Used to pass in the player volume levels in %. Default value is -1.

Retrieving ID3 Tags

The video player must have the ability to extract ID3 tags and supply them to the Browser SDK, based on the HLS standard.

  • An ID3 tag spans two PES packets.
    • In the first PES packet, look for www.nielsen.com, this is the start of the ID3 tag. Continue to parse the first PES packet until the undefined char "\ufffd" is found. This forms the first half of the ID3 tag
    • In the second PES packet, identify the end pattern – a regEx of /(\/\d+){3}/ and look to remove the lowest index of either "\x00" and/or "\ufffd". Now the second packet has been appended and the demarcation of the Nielsen-specific data has been defined.


Follow the procedure below, to extract Nielsen ID3 tags from an MPEG-2 transport stream (including HLS streams).

  1. Parse the Program Map Table (PMT) to find the PID of the metadata stream. Confirm the presence of the metadata descriptor described in section 2.3.3 of Apple’s “HTTP Live Streaming Metadata Spec.pdf”. Only private streams with metadata descriptor present should be considered as ID3-tag metadata streams.
  2. Parse the HLS/Transport stream for any PES header with the PID found in step 1.
  3. Follow standard MPEG-2 parsing procedures to locate the start of the payload of the PES packet.
  4. Copy the PES payload into a buffer.
  5. The ID3 tag spans 2 PES packets. Parse the stream for the next packet whose PID is set to the PID found in step 1. Typically the ID3 Tag is of 249 bytes. The steps below guide towards extraction of the ID3 tag
    1. In the first PES packet, look for "www.nielsen.com" , this is the start of the ID3 tag. Keep on parsing the first PES packet until the undefined char "\ufffd" is found. This forms the first half of the ID3 tag
    2. In the second PES packet, identify the end pattern, a regEx of /(\/\d+){3}/ and look to remove the lowest index of either “\x00” and/or “\ufffd”. Now the second packet has been appended and the demarcation of the Nielsen specific data has been defined. This segment can be simply substringed.
    3. Concatenate this substringed segment with the payload derived from the first packet get the ID3 payload.
  6. Check the length of the contents in the buffer to make sure that it is equal to the size of a Nielsen ID3 tag.
  7. Ensure that the ID3 byte array is converted into the string and escape it, so that the SDK can consume it.

Repeat steps 2 through 7 for all ID3 tags in the stream.

References

Sample ID3 tags

  • www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/X100zdCIGeIlgZnkYj6UvQ==/AAAB2Jz2_k74GXSzx4npHuI_JwJd3QSUpW30rDkGTcbHEzIMWleCzM-uvNOP9fzJcQMWQLJqzXMCAxParOb5sGijSV9dNM3QiBniJYGZ5GI-lL1fXTTN0IgZ4iWBmeRiPpS9AAAAAAAAAAAAAAAAAAAAAFJWFM5SVhTONNU=/00000/00000/00
  • www.nielsen.com/X100zdCIGeIlgZnkYj6UvQ==/R8WHe7pEBeqBhu8jTeXydg==/AAICoyitYqlxT7n6aZ0oMCGheFi4CXFp46AMUPZz1lMr_M9tr3_cjee1SHqxrOiVerMDLeyn9xzocZSKwi746Re8vNOtpNCAZjYABs_J0R25IHpvOc1HS8QHGgD5TgOJeS6gX100zdCIGeIlgZnkYj6UvVJWFNhSVhTiPE0=/00000/46016/00

Note: ID3 tags are not applicable for International (Germany)

Browser Opt-Out Implementation

The site in which video content is being measure via Nielsen methodology must provide the means for the user to opt-out of, or opt back into Nielsen Measurement.

For Browser-based applications, opt-out setting is stored via Nielsen cookie. Therefore, it is only necessary that users be made aware of measurement opt-out by incorporating the template below in the user interface.

Sample Opt Out Template

Our properties may feature Nielsen’s proprietary measurement software which will allow to contribute to market research, like Nielsen’s TV Ratings. To learn more about this information, see https://www.nielsen.com/digitalprivacy. Nielsen’s software may collect your choices with regards to it.

Nielsen Privacy Requirements

Privacy protections that Nielsen ensures to have with each App SDK integration are as follows.

  • Disclosure of viewership data collection in EULA / Privacy Policy
  • A link in the EULA/Privacy policy, or in another conspicuous location within the App, to a Nielsen-hosted web page outlining what Nielsen is collecting and how it is being used
  • Method for users to opt-out of Nielsen measurement, any time while using the application

Ratings Data Flow

Every view of creditable and watermarked content is measured by Nielsen. RatingsDataFlow.png

Information NOT Shared

  • With Nielsen
    • User's Identity
  • With Data Provider
    • Content information
    • Whether user is viewing an ad or video content
    • Player used to play the streaming (audio / video, etc.)
    • Values being de-duped / aggregating for

Nielsen collects only what it needs for audience measurement. Every view of creditable, watermarked content will be measured by Nielsen.

Data Collected

Type of Information Parameter Transmitted to Nielsen? Sent to Provider?
Nielsen ID3 Watermark
FinalDistributor Timestamp Yes No
Program Content Timestamp Yes No
Mobile Breakout Code Yes No
Commercial Credit Code – Linear or Dynamic Yes No
Time ShiftedViewing Code Yes No
Segment Number Yes No
Segment View Pattern Yes No
Device/App Info
Device OSVersion Yes Yes
Device Model Yes No
Cache Buster Yes Yes
SDKDisabled Flag Yes No
ServerCode Yes No
Channel or URL Yes No
Nielsen Identifiers
Client ID Yes No
Campaign ID Yes Yes
Nielsen Unique Device ID Yes No
Application ID Yes No
DeviceGroup (ex. Tablet, Smartphone, Desktop) Yes Yes
OS Group (ex. Android, iOS, Windows) Yes Yes
SDKVersion Yes No
IP Address for DMA, Country Code Yes Yes

Note: Data is hashed, and encrypted using AES 128 before transmission to data provider.

Viewability Data Collected

Parameter Description
Measured Value Value is different for different request parameters:
invs Intersection ratio for the target view in percent (from 0 to 100). Default threshold for this value is 5. Example: [50,1,1528457356,10]
inau Volume level on the device in percent (from 0 to 100), where 0 - mute, 100 - max volume level. Default threshold for this value is 1. Example: [30,1,1528457356,10]
inss Device screen size as "WxH", where W - is width in pixels, H - is height in pixels. Example: ["1024x768",1,1528457356,10]
invp Current window size. It is different than the device screen size in a multiple scene mode or on a desktop. Format is "WxH", where W - is width in pixels, H - is height in pixels. Example: ["800x600",1,1528457356,10]
ines Player view size as "WxH", where W - is width in pixels, H - is height in pixels. Example: ["300x200",1,1528457356,10]
Start offset Value contains the first playhead or the first id3 offset with non-null CID after start, flush or resume. Example playhead: [50,1,1528457356,10]. Example id3 offset: [50,70100,1528457356,10]
Start timestamp Timestamp value when the time period related to this time series item was started. Example: [50,1,1528457356,10]
Duration Duration value is calculated as a difference between the last playhead and the first playhead for the current time series item. Example: [50,1,1528457356,10]

Example ping sent to provider

  • https://provider.com/cgi-bin/brandlift.php?campaign_id=ff12725d724fac7934cf6003f096b4cd&placement_id=a4164b8fba9ee7c873a9c72c7091bb58&creative_id=25280139b61a947e127a52f56c8a2fdd&segment1=9000&segment2=41&segment3=iOS&OSVer=iOS6.1&c9=&devgrp=tablet&h=f5f243fe6d&rnd=1376971827360


This ping passes the following parameters to the provider:

  • Campaign ID – (campaign, placement, creative)
  • Country Code
  • DMA
  • OS Group (ex. iOS, Android)
  • DeviceOS Version
  • Device Advertiser ID
  • DeviceGroup (ex. Tablet, Smartphone, Desktop)
  • Cache Buster

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

Opt-Out Implementation

The site must provide the means for the user to opt-out of, or opt back into Nielsen Measurement.

Sample Opt Out Template

Our properties may feature Nielsen’s proprietary measurement software which will allow to contribute to market research, like Nielsen’s TV Ratings. To learn more about this information, please click here. Nielsen’s software may collect your choices with regards to it.

Testing

See Digital Measurement Testing - Testing Browser Implementation.