<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://engineeringportal.nielsen.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MichelFodjo</id>
	<title>Engineering Client Portal - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://engineeringportal.nielsen.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MichelFodjo"/>
	<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/wiki/Special:Contributions/MichelFodjo"/>
	<updated>2026-05-05T18:15:53Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Domless_SDK&amp;diff=7640</id>
		<title>DCR Denmark Domless SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Domless_SDK&amp;diff=7640"/>
		<updated>2026-04-22T10:18:12Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: DOMless SDK Integration for Denmark created 22-04-2026&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Nielsen SDK contains material that is protected by copyright laws, patent laws, trade secret laws, and by international treaty provisions and is Copyright © 2025 The Nielsen Company (US) LLC. All intellectual property rights and licenses therein are reserved by The Nielsen Company (US) LLC and its licensors. Please read the license agreement presented [https://engineeringportal.nielsen.com/wiki/Special:ClickThrough here], which must be accepted in order to download the Nielsen SDKs. For more information, reach out to your Nielsen Technical Account Manager(TAM).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK is a Javascript based cross-platform library that provides APIs that allows our clients to integrate the Nielsen SDK in DOM-less environments, e.g. ReactNative, NodeJS, etc. The new Amazon Vega/Kepler OS was certified by Nielsen for the DOM-less SDK Integration. &lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK can be used for '''Video''' and '''Static''' measurements.&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement on client mobile apps or webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more. This guide also includes a link to [[#Sample DOM-less SDK Implementation| github sample implementation]] with steps to implement the DCR Video product in a sample NodeJS app. It includes:&lt;br /&gt;
* DOM-less SDK Initialization&lt;br /&gt;
* DCR Video Metadata: information about the content being tracked&lt;br /&gt;
* DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
==DOM-less SDK Initialization==&lt;br /&gt;
&lt;br /&gt;
===Obtain the Nielsen Application ID (apid)===&lt;br /&gt;
The Nielsen &amp;lt;code&amp;gt;apid&amp;lt;/code&amp;gt; is required to enable SDK functionality. A Technical Account Manager(TAM) will provide an apid for each player configuration.DOM-less SDK can support URLs that use any of the protocols – HTTPS and HTTP.&lt;br /&gt;
&lt;br /&gt;
===Configure the DOM-less SDK===&lt;br /&gt;
&lt;br /&gt;
====Installation====&lt;br /&gt;
Install with &amp;lt;code&amp;gt;npm install &amp;lt;nowiki&amp;gt;https://github.com/NielsenDigitalSDK/bsdk-domless&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; and import the &amp;lt;code&amp;gt;BsdkInstance&amp;lt;/code&amp;gt; into video player component &amp;lt;code&amp;gt; import { BsdkInstance } from 'bsdk-domless' &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======status.ok()======&lt;br /&gt;
&lt;br /&gt;
Initialization of the instance can be done with &amp;lt;code&amp;gt;status.ok()&amp;lt;/code&amp;gt; function or use Promise handling approach&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = await new BsdkInstance(appID, instanceName, instanceMetadata, implementationHooks);&lt;br /&gt;
if (instance &amp;amp;&amp;amp; instance.status.ok()) {&lt;br /&gt;
      expect(instance).not.toBe(undefined);&lt;br /&gt;
      expect(instance.status.ok()).toBe(true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Implementation Hooks are mandatory for the DOM-less SDK instance. Please refer to the Implementation Hooks section below for details.&lt;br /&gt;
&lt;br /&gt;
====Exposed Interface====&lt;br /&gt;
The exposed interface is as follows:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;code&amp;gt;`ggPM`&amp;lt;/code&amp;gt; - method to send messages to the Nielsen SDK&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;code&amp;gt;`processEvent`&amp;lt;/code&amp;gt; - method to send app state to the Nielsen SDK, e.g., focus, blur, appclose&lt;br /&gt;
&lt;br /&gt;
===Initialization Global Parameters===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!'''Parameter'''&lt;br /&gt;
!'''Description'''&lt;br /&gt;
!'''Required'''&lt;br /&gt;
!'''Value'''&lt;br /&gt;
|-&lt;br /&gt;
|apid&lt;br /&gt;
|UniqueID assigned to player/site.&lt;br /&gt;
|Yes&lt;br /&gt;
|'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName&lt;br /&gt;
|Name of SDK instance&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|domlessEnv&lt;br /&gt;
|Type of DOM-less environment like ReactNative, Node, etc.&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;domlessEnv&amp;quot;: &amp;quot;1&amp;quot;, // For ReactNative&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;2&amp;quot;, // For Amazon&lt;br /&gt;
&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;3&amp;quot;, // For NodeJS&lt;br /&gt;
&lt;br /&gt;
“domlessEnv”: “4”, // For Custom&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid&lt;br /&gt;
|Optional:turn on or off the First Party ID&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|nol_sdkDebug&lt;br /&gt;
|Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementation Hooks ===&lt;br /&gt;
This object captures the required entities for the DOM-less SDK to operate correctly. These are normally platform dependent and are expected to be passed on to the DOM-less SDK as part of its initialization. See below for the descriptions of each key.&lt;br /&gt;
&lt;br /&gt;
==== '''log''' ====&lt;br /&gt;
Log the DOM-less SDK messages to an external stream, e.g. the browser console, stdout.&lt;br /&gt;
&lt;br /&gt;
e.g. Log.debug('debug', 'NIELSEN TAGS EXPECTED TO FIRE:')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;info()&lt;br /&gt;
&lt;br /&gt;
Log.info(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
debug()&lt;br /&gt;
&lt;br /&gt;
Log.debug(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
warn()&lt;br /&gt;
&lt;br /&gt;
Log.warn(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
error()&lt;br /&gt;
&lt;br /&gt;
Log.error(label: string, ...message: string[]): void&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;label Required&lt;br /&gt;
&lt;br /&gt;
● string - severity type, e.g. info, debug, warn, error or custom label&lt;br /&gt;
&lt;br /&gt;
message Required&lt;br /&gt;
&lt;br /&gt;
● string - message that will be output to the console&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== storage ====&lt;br /&gt;
Persistent storage of key/values, similar in behavior to browser localStorage.&lt;br /&gt;
&lt;br /&gt;
e.g. storage.set('nol_lsid', 'umy3w4ik9usw2ppqmw2vkecckxfob1697308388')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;set()&lt;br /&gt;
&lt;br /&gt;
storage.set(key: string, value: string)&lt;br /&gt;
&lt;br /&gt;
get()&lt;br /&gt;
&lt;br /&gt;
storage.get(key: string)&lt;br /&gt;
&lt;br /&gt;
remove()&lt;br /&gt;
&lt;br /&gt;
storage.remove(key: string)&lt;br /&gt;
&lt;br /&gt;
clear()&lt;br /&gt;
&lt;br /&gt;
storage.clear()&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== fetch ====&lt;br /&gt;
Function to fetch resources from the network. Required for the transmission of the DOM-less SDK requests (pings) to the Nielsen endpoints.&lt;br /&gt;
&lt;br /&gt;
e.g. Fetch(resource: string, options: object)&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;resource Required&lt;br /&gt;
&lt;br /&gt;
● A string that provides the URL of the resource to fetch&lt;br /&gt;
&lt;br /&gt;
options Optional Object containing settings to apply to the request:&lt;br /&gt;
&lt;br /&gt;
method&lt;br /&gt;
&lt;br /&gt;
● string - request method: &amp;quot;GET&amp;quot;, &amp;quot;POST&amp;quot;. If one is not provided SDK will default to &amp;quot;GET&amp;quot;&lt;br /&gt;
&lt;br /&gt;
headers&lt;br /&gt;
&lt;br /&gt;
● object - headers to add to the outgoing request, an object literal with String values&lt;br /&gt;
&lt;br /&gt;
body&lt;br /&gt;
&lt;br /&gt;
● string - body to add to the request; SDK will send out string&lt;br /&gt;
&lt;br /&gt;
mode&lt;br /&gt;
&lt;br /&gt;
● string - mode for request: cors, no-cors, same-origin&lt;br /&gt;
&lt;br /&gt;
referrer&lt;br /&gt;
&lt;br /&gt;
● string - a string specifying the referrer of the request&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====='''''&amp;lt;pre style=&amp;quot;color: green; font-weight: bold; font-size: 20px&amp;quot;&amp;gt;Note: Implementation Hooks are mandatory for the DOM-less SDK to function as expected.&amp;lt;/pre&amp;gt;'''''=====&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send app state to the Nielsen SDK, e.g., focus, blur, appclose==&lt;br /&gt;
&lt;br /&gt;
The method for calling events is &amp;lt;code&amp;gt;processEvent()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`blur`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the background.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'blur', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`focus`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the foreground.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'focus', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`appclose`&amp;lt;/code&amp;gt; - This event should be passed prior to closing the app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'appclose', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send messages to the Nielsen SDK==&lt;br /&gt;
&lt;br /&gt;
=== Video Measurement ===&lt;br /&gt;
&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description !!Event #&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'  || content/ad metadata object || Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad). ''[[DCR Denmark Video Browser SDK#Create Metadata Objects|See details on how to create Denmark specific metadata for content and ad]]''&lt;br /&gt;
||15&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
||49&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' || playhead position in seconds  || Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
||7&lt;br /&gt;
|-&lt;br /&gt;
| 'end' || playhead position in seconds || This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
||57&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample DOM-less SDK Implementation ====&lt;br /&gt;
&lt;br /&gt;
* Sample Implementation on github [https://github.com/NielsenDigitalSDK/bsdk-domless here].&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Integration Architecture Diagram ====&lt;br /&gt;
&lt;br /&gt;
===== For Content Playback =====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
===== For Ad Playback =====&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Interrupt Scenarios ====&lt;br /&gt;
* [[DCR Denmark Video Browser SDK#Handle Video Playback Interruption|Handle Video Playback Interruption]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Event Lifecycle ====&lt;br /&gt;
* [[DCR Denmark Video Browser SDK#SDK Call Sequence |SDK Call Sequence ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
&lt;br /&gt;
The Browser SDK video measurement does not set cross-domain cookies, therefore no centralized opt-out functionality is available. The Nielsen Browser SDK does not set cookies associated with the collection domain. The SDK sets specific cookie for the domain where the player is hosted (first party) and this cookie is not used across websites.&lt;br /&gt;
The only personal information collected with the SDK network pings is the IP address, which is  anonymized immediately after collection.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=da .&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). See [[#Initialization Global Parameters|SDK Initialization Global Parameters]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Certification ==&lt;br /&gt;
&lt;br /&gt;
While Nielsen is working on adding Support to the Certification Tool for DOM-less SDK in the future, the Certification process for the DOM-less will require detailed SDK Logs from a MMS Client integrating Nielsen DOM-less SDK. In this regard, a client will execute test cases locally and share logs for each test case with a Nielsen Technical Account Manager in charge of the Certification. &lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, disable Nielsen SDK logging by adjusting the Nielsen SDK Initialization Call, this will ensure that the App or Website is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = new BsdkInstance(&lt;br /&gt;
        nsdkConfig.app_id,&lt;br /&gt;
        nsdkConfig.instance_name,&lt;br /&gt;
        {&lt;br /&gt;
            appName: 'BSDK RN Sample App',&lt;br /&gt;
            domlessEnv: '1'// &amp;quot;1&amp;quot; for React Native | &amp;quot;2&amp;quot; for Amazon | &amp;quot;3&amp;quot; for NodeJS | &amp;quot;4&amp;quot; for Custom&lt;br /&gt;
            // reference SDK interface documentation&lt;br /&gt;
            // for additional metadata properties&lt;br /&gt;
        },&lt;br /&gt;
    implementationHooks&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7639</id>
		<title>DCR Sweden Domless SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7639"/>
		<updated>2026-04-22T10:08:11Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: minor typo fixed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Nielsen SDK contains material that is protected by copyright laws, patent laws, trade secret laws, and by international treaty provisions and is Copyright © 2025 The Nielsen Company (US) LLC. All intellectual property rights and licenses therein are reserved by The Nielsen Company (US) LLC and its licensors. Please read the license agreement presented [https://engineeringportal.nielsen.com/wiki/Special:ClickThrough here], which must be accepted in order to download the Nielsen SDKs. For more information, reach out to your Nielsen Technical Account Manager(TAM).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK is a Javascript based cross-platform library that provides APIs that allows our clients to integrate the Nielsen SDK in DOM-less environments, e.g. ReactNative, NodeJS, etc. The new Amazon Vega/Kepler OS was certified by Nielsen for the DOM-less SDK Integration. &lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK can be used for '''Video''' and '''Static''' measurements.&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement on client mobile apps or webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more. This guide also includes a link to [[#Sample DOM-less SDK Implementation| github sample implementation]] with steps to implement the DCR Video product in a sample NodeJS app. It includes:&lt;br /&gt;
* DOM-less SDK Initialization&lt;br /&gt;
* DCR Video Metadata: information about the content being tracked&lt;br /&gt;
* DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
==DOM-less SDK Initialization==&lt;br /&gt;
&lt;br /&gt;
===Obtain the Nielsen Application ID (apid)===&lt;br /&gt;
The Nielsen &amp;lt;code&amp;gt;apid&amp;lt;/code&amp;gt; is required to enable SDK functionality. A Technical Account Manager(TAM) will provide an apid for each player configuration.DOM-less SDK can support URLs that use any of the protocols – HTTPS and HTTP.&lt;br /&gt;
&lt;br /&gt;
===Configure the DOM-less SDK===&lt;br /&gt;
&lt;br /&gt;
====Installation====&lt;br /&gt;
Install with &amp;lt;code&amp;gt;npm install &amp;lt;nowiki&amp;gt;https://github.com/NielsenDigitalSDK/bsdk-domless&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; and import the &amp;lt;code&amp;gt;BsdkInstance&amp;lt;/code&amp;gt; into video player component &amp;lt;code&amp;gt; import { BsdkInstance } from 'bsdk-domless' &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======status.ok()======&lt;br /&gt;
&lt;br /&gt;
Initialization of the instance can be done with &amp;lt;code&amp;gt;status.ok()&amp;lt;/code&amp;gt; function or use Promise handling approach&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = await new BsdkInstance(appID, instanceName, instanceMetadata, implementationHooks);&lt;br /&gt;
if (instance &amp;amp;&amp;amp; instance.status.ok()) {&lt;br /&gt;
      expect(instance).not.toBe(undefined);&lt;br /&gt;
      expect(instance.status.ok()).toBe(true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Implementation Hooks are mandatory for the DOM-less SDK instance. Please refer to the Implementation Hooks section below for details.&lt;br /&gt;
&lt;br /&gt;
====Exposed Interface====&lt;br /&gt;
The exposed interface is as follows:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;code&amp;gt;`ggPM`&amp;lt;/code&amp;gt; - method to send messages to the Nielsen SDK&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;code&amp;gt;`processEvent`&amp;lt;/code&amp;gt; - method to send app state to the Nielsen SDK, e.g., focus, blur, appclose&lt;br /&gt;
&lt;br /&gt;
===Initialization Global Parameters===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!'''Parameter'''&lt;br /&gt;
!'''Description'''&lt;br /&gt;
!'''Required'''&lt;br /&gt;
!'''Value'''&lt;br /&gt;
|-&lt;br /&gt;
|apid&lt;br /&gt;
|UniqueID assigned to player/site.&lt;br /&gt;
|Yes&lt;br /&gt;
|'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName&lt;br /&gt;
|Name of SDK instance&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|domlessEnv&lt;br /&gt;
|Type of DOM-less environment like ReactNative, Node, etc.&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;domlessEnv&amp;quot;: &amp;quot;1&amp;quot;, // For ReactNative&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;2&amp;quot;, // For Amazon&lt;br /&gt;
&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;3&amp;quot;, // For NodeJS&lt;br /&gt;
&lt;br /&gt;
“domlessEnv”: “4”, // For Custom&lt;br /&gt;
|-&lt;br /&gt;
|hem_unknown ||   Hashed email using SHA512. This email is used by the MMS reach model.|| Required if login feature ||  &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{hem_unknown: &amp;quot;924899b875ea6767ab790bd2f4852345fcfec5d203c49be8e8...&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|optout&lt;br /&gt;
|OptOut global parameter. This optout will be maintained through the session of the SDK instance&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid&lt;br /&gt;
|Optional:turn on or off the First Party ID&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|nol_sdkDebug&lt;br /&gt;
|Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementation Hooks ===&lt;br /&gt;
This object captures the required entities for the DOM-less SDK to operate correctly. These are normally platform dependent and are expected to be passed on to the DOM-less SDK as part of its initialization. See below for the descriptions of each key.&lt;br /&gt;
&lt;br /&gt;
==== '''log''' ====&lt;br /&gt;
Log the DOM-less SDK messages to an external stream, e.g. the browser console, stdout.&lt;br /&gt;
&lt;br /&gt;
e.g. Log.debug('debug', 'NIELSEN TAGS EXPECTED TO FIRE:')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;info()&lt;br /&gt;
&lt;br /&gt;
Log.info(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
debug()&lt;br /&gt;
&lt;br /&gt;
Log.debug(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
warn()&lt;br /&gt;
&lt;br /&gt;
Log.warn(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
error()&lt;br /&gt;
&lt;br /&gt;
Log.error(label: string, ...message: string[]): void&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;label Required&lt;br /&gt;
&lt;br /&gt;
● string - severity type, e.g. info, debug, warn, error or custom label&lt;br /&gt;
&lt;br /&gt;
message Required&lt;br /&gt;
&lt;br /&gt;
● string - message that will be output to the console&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== storage ====&lt;br /&gt;
Persistent storage of key/values, similar in behavior to browser localStorage.&lt;br /&gt;
&lt;br /&gt;
e.g. storage.set('nol_lsid', 'umy3w4ik9usw2ppqmw2vkecckxfob1697308388')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;set()&lt;br /&gt;
&lt;br /&gt;
storage.set(key: string, value: string)&lt;br /&gt;
&lt;br /&gt;
get()&lt;br /&gt;
&lt;br /&gt;
storage.get(key: string)&lt;br /&gt;
&lt;br /&gt;
remove()&lt;br /&gt;
&lt;br /&gt;
storage.remove(key: string)&lt;br /&gt;
&lt;br /&gt;
clear()&lt;br /&gt;
&lt;br /&gt;
storage.clear()&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== fetch ====&lt;br /&gt;
Function to fetch resources from the network. Required for the transmission of the DOM-less SDK requests (pings) to the Nielsen endpoints.&lt;br /&gt;
&lt;br /&gt;
e.g. Fetch(resource: string, options: object)&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;resource Required&lt;br /&gt;
&lt;br /&gt;
● A string that provides the URL of the resource to fetch&lt;br /&gt;
&lt;br /&gt;
options Optional Object containing settings to apply to the request:&lt;br /&gt;
&lt;br /&gt;
method&lt;br /&gt;
&lt;br /&gt;
● string - request method: &amp;quot;GET&amp;quot;, &amp;quot;POST&amp;quot;. If one is not provided SDK will default to &amp;quot;GET&amp;quot;&lt;br /&gt;
&lt;br /&gt;
headers&lt;br /&gt;
&lt;br /&gt;
● object - headers to add to the outgoing request, an object literal with String values&lt;br /&gt;
&lt;br /&gt;
body&lt;br /&gt;
&lt;br /&gt;
● string - body to add to the request; SDK will send out string&lt;br /&gt;
&lt;br /&gt;
mode&lt;br /&gt;
&lt;br /&gt;
● string - mode for request: cors, no-cors, same-origin&lt;br /&gt;
&lt;br /&gt;
referrer&lt;br /&gt;
&lt;br /&gt;
● string - a string specifying the referrer of the request&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====='''''&amp;lt;pre style=&amp;quot;color: green; font-weight: bold; font-size: 20px&amp;quot;&amp;gt;Note: Implementation Hooks are mandatory for the DOM-less SDK to function as expected.&amp;lt;/pre&amp;gt;'''''=====&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send app state to the Nielsen SDK, e.g., focus, blur, appclose==&lt;br /&gt;
&lt;br /&gt;
The method for calling events is &amp;lt;code&amp;gt;processEvent()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`blur`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the background.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'blur', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`focus`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the foreground.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'focus', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`appclose`&amp;lt;/code&amp;gt; - This event should be passed prior to closing the app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'appclose', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send messages to the Nielsen SDK==&lt;br /&gt;
&lt;br /&gt;
=== Video Measurement ===&lt;br /&gt;
&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description !!Event #&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'  || content/ad metadata object || Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad). ''[[DCR Sweden Video Browser SDK#Create Metadata Objects|See details on how to create MMS metadata for content and ad]]''&lt;br /&gt;
||15&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
||49&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' || playhead position in seconds  || Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
||7&lt;br /&gt;
|-&lt;br /&gt;
| 'end' || playhead position in seconds || This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
||57&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample DOM-less SDK Implementation ====&lt;br /&gt;
&lt;br /&gt;
* Sample Implementation on github [https://github.com/NielsenDigitalSDK/bsdk-domless here].&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Integration Architecture Diagram ====&lt;br /&gt;
&lt;br /&gt;
===== For Content Playback =====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
===== For Ad Playback =====&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Interrupt Scenarios ====&lt;br /&gt;
* [[DCR Sweden Video Browser SDK#Handle Video Playback Interruption|Handle Video Playback Interruption]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Event Lifecycle ====&lt;br /&gt;
* [[DCR Sweden Video Browser SDK#SDK Call Sequence |SDK Call Sequence ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out  ==&lt;br /&gt;
&lt;br /&gt;
The site must provide a means for the user to opt-out of, or opt back into, Nielsen Measurement. Users can opt out if they 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.&lt;br /&gt;
*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).&lt;br /&gt;
*A link to the Nielsen Digital Measurement Privacy Policy at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=sv (or for English: https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=en-se)&lt;br /&gt;
*We have two separate entities registered with the IAB TCF, Nielsen Marketing Cloud and Nielsen LLC.  The one that is relevant to Swedish measurement is Nielsen LLC (ID: 812) and not NMC. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
* Once users have opted out via this [https://priv-policy.imrworldwide.com/priv/browser/cookie-policy.html?optout=1 link], their browser cookies will contain the value '''TOTAL_OPTOUT'''. This will prevent a redirect to our data provider from occurring&lt;br /&gt;
* Users can opt back in via this [https://priv-policy.imrworldwide.com/priv/browser/cookie-policy.html?optout=0 link].  When a user selects that link, their opt-out cookie will be deleted and they will be able to be measured moving forward.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following paragraph is a template for a Privacy Statement.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The properties may feature Nielsen proprietary measurement software, allowing 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 concerning it, please see the Nielsen Digital Measurement Privacy Policy at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=sv&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== User Opt Back In ====&lt;br /&gt;
Once users have opted-out, they can choose to opt back into Nielsen Measurement at any time 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.&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). See [[#Initialization Global Parameters|SDK Initialization Global Parameters]].&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The optout Flag is set by default to &amp;quot;false&amp;quot; in the Browser SDK. For Opt-out users, the optout Flag can be set to &amp;quot;true&amp;quot; during the initialization of the SDK Instance, i.e. the parameter optout can be set to &amp;quot;true&amp;quot; (opted out) or &amp;quot;false&amp;quot; (opted in or NOT opted out). See [[#Initialization Global Parameters|SDK Initialization Global Parameters]].&lt;br /&gt;
&lt;br /&gt;
== Certification ==&lt;br /&gt;
&lt;br /&gt;
While Nielsen is working on adding Support to the Certification Tool for DOM-less SDK in the future, the Certification process for the DOM-less will require detailed SDK Logs from a MMS Client integrating Nielsen DOM-less SDK. In this regard, a client will execute test cases locally and share logs for each test case with a Nielsen Technical Account Manager in charge of the Certification. &lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, disable Nielsen SDK logging by adjusting the Nielsen SDK Initialization Call, this will ensure that the App or Website is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = new BsdkInstance(&lt;br /&gt;
        nsdkConfig.app_id,&lt;br /&gt;
        nsdkConfig.instance_name,&lt;br /&gt;
        {&lt;br /&gt;
            appName: 'BSDK RN Sample App',&lt;br /&gt;
            domlessEnv: '1'// &amp;quot;1&amp;quot; for React Native | &amp;quot;2&amp;quot; for Amazon | &amp;quot;3&amp;quot; for NodeJS | &amp;quot;4&amp;quot; for Custom&lt;br /&gt;
            // reference SDK interface documentation&lt;br /&gt;
            // for additional metadata properties&lt;br /&gt;
        },&lt;br /&gt;
    implementationHooks&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_Cloud_API&amp;diff=7638</id>
		<title>DCR Denmark Video Cloud API</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_Cloud_API&amp;diff=7638"/>
		<updated>2026-04-22T07:55:45Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Disclose Nielsen Privacy Statement */  new sub-section &amp;quot;Nielsen Cloud API payload for Opt-out Users in your App &amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing Cloud API =&lt;br /&gt;
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
 || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Integration==&lt;br /&gt;
We will cover the steps for constructing the Cloud API Calls.&lt;br /&gt;
&lt;br /&gt;
====URL Structure====&lt;br /&gt;
&lt;br /&gt;
The Cloud API Calls are HTTP GET Requests with the URL structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;[endpoint]/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The URL includes the following components:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;[endpoint]&amp;lt;/code&amp;gt;: location of data collection environment&lt;br /&gt;
*&amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt;: provided App ID. &lt;br /&gt;
** '''Note: P prefix must be removed before adding it to the URL'''&lt;br /&gt;
** Example App ID with P prefix: &amp;quot;PDF20695-XXXX-XXXX-XXXX-3E334133D917&amp;quot;&lt;br /&gt;
** &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/DF20695-XXXX-XXXX-XXXX-3E334133D917/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;: unique value for each user session&lt;br /&gt;
*&amp;lt;code&amp;gt;[payload]&amp;lt;/code&amp;gt;: metadata and events&lt;br /&gt;
&lt;br /&gt;
====Endpoint====&lt;br /&gt;
&lt;br /&gt;
There are endpoints for testing and production:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Production: &amp;lt;code&amp;gt;https://capi-dmk.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide.&lt;br /&gt;
&lt;br /&gt;
====URL Example====&lt;br /&gt;
As you move through the integration steps, you can reference the below URL structure with the expanded payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content_metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event],&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playhead_position],&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type],&lt;br /&gt;
  &amp;quot;utc&amp;quot;: [Unix time in ms],&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: [unique view session ID for each video play]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create Session ID and send EMM Ping===&lt;br /&gt;
&lt;br /&gt;
====Create Session ID====&lt;br /&gt;
&lt;br /&gt;
A unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app.&lt;br /&gt;
&lt;br /&gt;
A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see  [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference and use.&lt;br /&gt;
&lt;br /&gt;
Session ID example: '''LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
'''// Create random GUID'''&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon exiting the app, the session will need to be terminated using the delete event. &amp;lt;br&amp;gt;&lt;br /&gt;
Sessions will automatically expire after 30 minutes of cloud inactivity.&lt;br /&gt;
&lt;br /&gt;
====Send EMM Ping====&lt;br /&gt;
An EMM Ping must be sent using the created unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; upon start of the first stream playback.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://[sessionID].uaid.nmrodam.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also see  [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference.&lt;br /&gt;
&lt;br /&gt;
===Create First Party ID===&lt;br /&gt;
* An First Party ID  &amp;lt;code&amp;gt;[fpid]&amp;lt;/code&amp;gt; must be created and stored on the device. It is re-used until expiration date or if the user has deleted it on from the device storage.&lt;br /&gt;
The default expiration date should be set to the equivalent of 180 days. &lt;br /&gt;
* Additionally the Creation Time &amp;lt;code&amp;gt;[fpcrtm]&amp;lt;/code&amp;gt; of the First Party ID should be stored as well. The same value should be used as long as the First Party ID is available on the device.&lt;br /&gt;
&lt;br /&gt;
===Create View Session ID for each Video Start===&lt;br /&gt;
An View Session ID &amp;lt;code&amp;gt;[sessid]&amp;lt;/code&amp;gt; must be created upon start of each stream playback, sessid is unique per video play.&lt;br /&gt;
&lt;br /&gt;
===Define URL Structure===&lt;br /&gt;
Define the URL structure using your provided &amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt; and a unique &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure Payload===&lt;br /&gt;
&lt;br /&gt;
All Cloud API requests must contain the following payload data:&lt;br /&gt;
&lt;br /&gt;
*''devInfo'': device and app info&lt;br /&gt;
*''metadata'': asset metadata&lt;br /&gt;
*''event metadata'': type of event&lt;br /&gt;
&lt;br /&gt;
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section.&lt;br /&gt;
&lt;br /&gt;
'''Payload Example'''&lt;br /&gt;
&lt;br /&gt;
The example below should be referenced when following the steps for configuring the request payload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// 3.1 Configure Payload: devInfo &lt;br /&gt;
payload = {&lt;br /&gt;
    &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
        &amp;quot;devId&amp;quot;: &amp;quot;SHA-256 value of the Device ID&amp;quot;, &lt;br /&gt;
        &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
        &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
        &amp;quot;fpid&amp;quot;: &amp;quot;First Party ID&amp;quot;,&lt;br /&gt;
        &amp;quot;fpcrtm&amp;quot;: &amp;quot;Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds)&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    // 3.2 Configure Payload: metadata&lt;br /&gt;
    &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
        &amp;quot;content&amp;quot;: { // object for measuring video content&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, // &amp;quot;content&amp;quot; for video&lt;br /&gt;
            &amp;quot;assetid&amp;quot;: &amp;quot;VIDEO-ID123&amp;quot;, // unique ID for video&lt;br /&gt;
            &amp;quot;isfullepisode&amp;quot;: &amp;quot;y&amp;quot;, // full episode flag&lt;br /&gt;
            &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;, // program name&lt;br /&gt;
            &amp;quot;title&amp;quot;: &amp;quot;Episode Title S3 - EP1&amp;quot;, // episode name&lt;br /&gt;
            &amp;quot;length&amp;quot;: &amp;quot;1800&amp;quot;, // content duration in seconds&lt;br /&gt;
            &amp;quot;airdate&amp;quot;: &amp;quot;20161013 20:00:00&amp;quot;, // airdate&lt;br /&gt;
            &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot;, //ad load flag&lt;br /&gt;
            &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;, // channel ID or subrand provided by Nielsen&lt;br /&gt;
            &amp;quot;stationId&amp;quot;: &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
            &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
            &amp;quot;pbstarttm&amp;quot;: &amp;quot;1631098029&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;ad&amp;quot;: {&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;, // type of ad&lt;br /&gt;
            &amp;quot;assetid&amp;quot;: &amp;quot;AD-ID123&amp;quot; // unique ID for ad&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    // 3.3 Configure Payload: events&lt;br /&gt;
    &amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, //event name&lt;br /&gt;
    &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, // position in seconds&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, //&amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
    &amp;quot;utc&amp;quot;: &amp;quot;1456448742000&amp;quot;, //unix timestamp in milliseconds &lt;br /&gt;
    &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Configure Payload: devInfo=====&lt;br /&gt;
An object &amp;lt;code&amp;gt;&amp;quot;devInfo&amp;quot;&amp;lt;/code&amp;gt; will need to be created to capture App and Device information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| devId || unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented  SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot;  || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || custom || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| fpid || First Party ID || custom || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| fpcrtm || Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Example devInfo Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create devInfo object&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;devId&amp;quot;: &amp;quot;SHA-256 value of the Device ID&amp;quot;,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;First Party ID&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds)&amp;quot;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3.2 Configure Payload: metadata ====&lt;br /&gt;
Asset metadata can be passed through &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt;. There are two asset types: &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; for video and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; for ads. The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
You will need to set up &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt; objects for &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
===== Content Metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type ||	type of asset	|| &amp;quot;content&amp;quot; for main content	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid	|| unique ID assigned to asset 	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| program	|| name of program 	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| title	|| episode name	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| length	|| length of content in seconds	|| Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||	✓&lt;br /&gt;
|-&lt;br /&gt;
| airdate	|| the original date (local time with hh:mm:ss as 24h time stamp) content became available. This date does not change if the content is rebroadcasted on linear TV. ||	YYYYMMDD HH:MI:SS (if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot;)	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode	|| full episode flag ||	&lt;br /&gt;
* &amp;quot;y&amp;quot; full episode (full content for a program)&lt;br /&gt;
* &amp;quot;n&amp;quot; non full episode (only one part of the entire content for a program , i.e. preview, sub-episodes)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
|adloadtype	|| type of Ad load&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;1&amp;quot; Linear - matches TV ad load &lt;br /&gt;
* &amp;quot;2&amp;quot; Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Example Content Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang='json'&amp;gt;// create content object&lt;br /&gt;
&amp;quot;content&amp;quot;: {&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
  &amp;quot;program&amp;quot;: &amp;quot;program name&amp;quot;,&lt;br /&gt;
  &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
  &amp;quot;length&amp;quot;: &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
  &amp;quot;airdate&amp;quot;: &amp;quot;20200713 10:22:00&amp;quot;,&lt;br /&gt;
  &amp;quot;isfullepisode&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
  &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot;,&lt;br /&gt;
  &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;,&lt;br /&gt;
  &amp;quot;stationId&amp;quot;: &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
  &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
  &amp;quot;pbstarttm&amp;quot;: &amp;quot;1631098029&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ad Metadata (optional for DR) =====&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;&amp;quot;preroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;midroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;postroll&amp;quot;&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	|| provided by Nielsen || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Ad Object =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;unique_preroll_ad_id&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure Payload: Events ===&lt;br /&gt;
&lt;br /&gt;
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below.&lt;br /&gt;
&lt;br /&gt;
==== Event Types ====&lt;br /&gt;
&lt;br /&gt;
The available events are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; || &lt;br /&gt;
&lt;br /&gt;
===== Handling Playhead =====&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; is critical for accurate duration crediting. You can reference the below guidance to determine the correct playhead position to pass depending on the playback scenario.&lt;br /&gt;
&lt;br /&gt;
'''General'''&lt;br /&gt;
* Playhead position in seconds, must be passed as a whole number every 10 seconds. &lt;br /&gt;
* The final playhead position should be sent before before sending &amp;quot;complete&amp;quot; event when content playback is complete. &lt;br /&gt;
&lt;br /&gt;
'''Live Stream'''&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position. Note that ad playheads must also use Unix Time for each single Ad in an Ad Pod.&lt;br /&gt;
&lt;br /&gt;
'''VoD Stream'''&lt;br /&gt;
* For VoD stream use the player position for Content and Ad at playback start of a content or single Ad in an Ad Pod, playheads will then be 0, 10, 20, ....&lt;br /&gt;
&lt;br /&gt;
'''End of an Asset'''&lt;br /&gt;
* Final postion must be sent at the end of Content or Ad playback&lt;br /&gt;
&lt;br /&gt;
'''Ads'''&lt;br /&gt;
* The final playhead position must be sent when switching from content to ad, or ad to content.&lt;br /&gt;
* For Ad Pods, playhead must be called for each individual ad.&lt;br /&gt;
* When content has resumed following a mid-roll ad break, the next playhead position must continue where the previous content segment left off.&lt;br /&gt;
&lt;br /&gt;
'''User Actions'''&lt;br /&gt;
* SCRUBBING: Upon user scrubbing, the current position must be sent before a user scrubs, and the new position should be sent where the user lands, and begin sending in the 10 second updates thereafter.&lt;br /&gt;
* PAUSE: When content is paused, send current playhead position and stop passing playhead position until content is resumed.&lt;br /&gt;
* EXIT Stream: If a user exits a stream early, the last current position must be sent in a playhead update to receive accurate duration.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt; || The complete event must be sent when full playback of the content has completed . Before calling the complete event, a final playhead update with the final position is required to be sent to receive full duration credit. For Live streams, a complete event must be sent at program boundaries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || The delete event is sent when the viewing session is terminated (typically on App close). A new session ID must be generated after sending a delete event. Delete should not be sent on app interruptions or foreground/background events. All creditable duration will be summarized for all asset types when delete occurs (content and ads).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Event Parameters =====&lt;br /&gt;
&lt;br /&gt;
The following parameters need to be passed when calling events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description !! Value !! Required&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;event&amp;quot;&amp;lt;/code&amp;gt; || event type || &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;position&amp;quot;&amp;lt;/code&amp;gt; || playhead position in seconds or Unix time in seconds || &amp;lt;code&amp;gt;&amp;quot;300&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;&amp;lt;/code&amp;gt; || asset type || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;utc&amp;quot;&amp;lt;/code&amp;gt; || Unix timestamp in milliseconds. Must be passed every 10 seconds. || &amp;lt;code&amp;gt;&amp;quot;1472760000000&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;sessid&amp;quot;&amp;lt;/code&amp;gt; || Unique View Session ID must be created upon start of each stream playback, sessid is unique per video play. || &amp;lt;code&amp;gt;&amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Event =====&lt;br /&gt;
You can call events by passing values in the required parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  // Event Parameters&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event], // event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playheadPosition], //position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type], // values are &amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;, //unix timestamp in milliseconds&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The full payload including &amp;quot;devInfo&amp;quot; and &amp;quot;metadata&amp;quot; must be populated in each event request.&lt;br /&gt;
&lt;br /&gt;
===== Sample Event Lifecycle for VoD Stream =====&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events and values to pass.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// Preroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Content&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content resumes at 15 minutes&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;900&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 30 minutes&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;1800&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Postroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Sample Event Lifecycle for VoD Stream - Detailed Storyline'''&lt;br /&gt;
This detailed event sequence provides additional insight for the correct events to call when handling certain playback scenarios.&lt;br /&gt;
&amp;lt;syntaxhighlight lang='javascript'&amp;gt;// SESSION STARTS&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// PREROLL&lt;br /&gt;
// Preroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Preroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;15&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
// CONTENT &lt;br /&gt;
// Content Start - Start new content streams with a position of &amp;quot;0&amp;quot; incrementing the position every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content Stop Before Ad Break - Send a playhead update including the current content positon before an Ad break.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;299&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787400000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
// Midroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;60&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472793500000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
// Content resumes at 5 minutes - Send playhead update with the current resumed position, and begin incrimenting the positon every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472799500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 10:12 - Make sure to send in the playhead event with the final content position before sending the complete event.&lt;br /&gt;
Final Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830700000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830800000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// POSTROLL&lt;br /&gt;
// Postroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830900000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Postroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;45&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835300000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// SESSION ENDS&lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835400000&amp;quot;} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Interruption Scenarios =====&lt;br /&gt;
&lt;br /&gt;
As part of configuring events, you will need to handle all possible interruption scenarios such as:&lt;br /&gt;
&lt;br /&gt;
*Wi-Fi OFF / ON&lt;br /&gt;
*App going Background / Foreground (Video players only, not for Audio players)&lt;br /&gt;
*App Crash or Exit&lt;br /&gt;
&lt;br /&gt;
'''Note:''' A session will automatically timeout after 30 minutes of inactivity.&lt;br /&gt;
&lt;br /&gt;
=== Example Request ===&lt;br /&gt;
&lt;br /&gt;
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// 1. Create Session ID&lt;br /&gt;
sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088  // Example sessionID created using a UUID Generator&lt;br /&gt;
&lt;br /&gt;
// 2. Define URL Structure with App ID and Session ID&lt;br /&gt;
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
&lt;br /&gt;
// 3. Configure Payload&lt;br /&gt;
// 3.1 Configure Payload: devInfo &lt;br /&gt;
payload = {&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   &amp;quot;devId&amp;quot;: &amp;quot;SHA-256 value of the Device ID&amp;quot;,&lt;br /&gt;
   &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
   &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
   &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
   &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  // 3.2 Configure Payload: metadata&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: { // object for measuring video content&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, // &amp;quot;content&amp;quot; for video&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;VIDEO-ID123&amp;quot;, // unique ID for video&lt;br /&gt;
      &amp;quot;isfullepisode&amp;quot;: &amp;quot;y&amp;quot;, // full episode flag&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;, // program name&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;Episode Title S3 - EP1&amp;quot;, // episode name&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;1800&amp;quot;, // content duration in seconds&lt;br /&gt;
      &amp;quot;airdate&amp;quot;: &amp;quot;20161013 20:00:00&amp;quot;, // airdate&lt;br /&gt;
      &amp;quot;adloadtype&amp;quot;: &amp;quot;2&amp;quot; // ad load flag,&lt;br /&gt;
      &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;,&lt;br /&gt;
      &amp;quot;stationId&amp;quot;: &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
      &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
      &amp;quot;pbstarttm&amp;quot;: &amp;quot;1631098029&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;, // type of ad&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;AD-ID123&amp;quot; // unique ID for ad&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  // 3.3 Configure Payload: events&lt;br /&gt;
  &amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, //event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, // position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, //&amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1456448742000&amp;quot;, //unix timestamp in milliseconds &lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot; // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Append payload to URL&lt;br /&gt;
function sendPayloadToNielsen() {&lt;br /&gt;
  var payloadStr  = JSON.stringify(payload); // payload as string&lt;br /&gt;
  var imgPing = new Image();&lt;br /&gt;
  imgPing.onload = function() {&lt;br /&gt;
    // onload event, payload succesfull sent&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.onerror = function() {&lt;br /&gt;
    // handle error i.e. wait and send again&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.src = sessionURL+encodeURIComponent(payloadStr);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Enable Debug Logging ====&lt;br /&gt;
&lt;br /&gt;
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification.&lt;br /&gt;
&lt;br /&gt;
==== GET Request ====&lt;br /&gt;
&lt;br /&gt;
Display GET Request to console using a name to identify each event (e.g. playhead).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event&amp;quot;, image); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Output payload to identify required metadata and events.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event Payload&amp;quot;, payload); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response Code ====&lt;br /&gt;
&lt;br /&gt;
Confirm request was completed by viewing HTTP response code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
code = msg.GetResponseCode();&lt;br /&gt;
console.log(&amp;quot;Response Code&amp;quot;, code); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can reference the HTTP Response Code table when reviewing your requests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Status Code !! Status Text !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;200&amp;lt;/code&amp;gt; || OK || request received&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;403&amp;lt;/code&amp;gt; || Forbidden || invalid App ID&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;404&amp;lt;/code&amp;gt; || Not Found || JSON issue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll and postroll Ads.&lt;br /&gt;
&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; in the &amp;lt;code&amp;gt;Playback Settings&amp;lt;/code&amp;gt; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for DK [https://nielsenonlinesupport.com/dk/cloudapi/index.htm?debug=true RefImplCloudAPIDK].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen CloudAPI Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=da .&lt;br /&gt;
&lt;br /&gt;
=== Nielsen Cloud API payload for Opt-out Users in your App ===&lt;br /&gt;
&lt;br /&gt;
The First Party ID(fpid) and the Device ID(devId) fields can remain empty for '''opt-out users'''. &lt;br /&gt;
&lt;br /&gt;
==== First Party ID(fpid) ====&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   ...,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   ...&lt;br /&gt;
  }&lt;br /&gt;
==== Device ID(devId) ====&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   ...,&lt;br /&gt;
  &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
   ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Before providing an app build to Nielsen for testing, it is important to run validation checks once you have enabled debug logging.&lt;br /&gt;
&lt;br /&gt;
=== Payload Validation ===&lt;br /&gt;
&lt;br /&gt;
Ensure that all of the required payload data is populating while testing several videos. The following areas are critical to measurement:&lt;br /&gt;
*devInfo&lt;br /&gt;
*Asset metadata for both content, and ads&lt;br /&gt;
*Events&lt;br /&gt;
&lt;br /&gt;
=== Player Events ===&lt;br /&gt;
Review event calls:&lt;br /&gt;
&lt;br /&gt;
==== playhead ====&lt;br /&gt;
*Playhead position updates every 10 seconds starting at position '0' for each new asset for VoD stream and UTC Unix Time in seconds for Live stream.&lt;br /&gt;
*Final playhead position is sent on content, or ad before switching between assets.&lt;br /&gt;
*Content metadata remains constant throughout an episode, or clip play.&lt;br /&gt;
*Ad metadata is populated appropriately for each individual ad.&lt;br /&gt;
*Playhead position update resumes for content after an ad break, and resets to 0 for each individual ad.&lt;br /&gt;
*For scrubbing, last current position should be sent while scrubbing occurs, and the new position should also be sent where the user scrubs to.&lt;br /&gt;
*Exiting a stream early should execute the last current position in a playhead update to receive accurate duration.&lt;br /&gt;
*Upon pause, the current position should be sent, and playhead updates should stop incrementing until resume play occurs.&lt;br /&gt;
&lt;br /&gt;
==== complete ====&lt;br /&gt;
*Check that the complete event executes upon content complete after the final playhead update is sent&lt;br /&gt;
*Do not execute the complete event for ads&lt;br /&gt;
&lt;br /&gt;
==== delete ====&lt;br /&gt;
*Check to see that the delete event occurs upon app exit, if the platform has the necessary exit callback events.&lt;br /&gt;
&lt;br /&gt;
==== GET Request Format ====&lt;br /&gt;
*Ensure that the event payloads are formatted in JSON&lt;br /&gt;
*Check to see that each of the Cloud API GET requests are properly encoded&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response ====&lt;br /&gt;
*Make sure that each of the Cloud API Get requests are received by the Nielsen Cloud API properly through use of the HTTP Response Code outputs enabled in console.&lt;br /&gt;
&lt;br /&gt;
== Go Live ==&lt;br /&gt;
After your integration has been certified, you will need to: Change Endpoint and Disable Logging.&lt;br /&gt;
&lt;br /&gt;
'''Change Endpoint:''' You will need to update to the production endpoint:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Production: &amp;lt;code&amp;gt;https://capi-dmk.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your production URL structure should now be:&lt;br /&gt;
&amp;lt;code&amp;gt;https://capi-dmk.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Disable Logging:''' You can now disable debug logging&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7636</id>
		<title>DCR Germany Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7636"/>
		<updated>2026-04-07T09:28:54Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a S2S Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S (Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (AppID)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have its own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but '''latest within 3 hours of the start of that hourly viewing file interval'''. For example, files from '''2:00 AM to 3:00 AM''' must be delivered latest before '''5 AM'''.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving an exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicit request from AGF.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported formats are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delivered to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''. Only for the Asset Metadata Optimization use case, '''all''' is used additionally, see [[#Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day|Optimization for all Platforms]]&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653476400&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| end_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653479999&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
    &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
    &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Asset Metadata Delivery Optimization===&lt;br /&gt;
&lt;br /&gt;
====Optimization when the Asset Metadata File remains unchanged during the whole day per platform====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged during the whole day per platform, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File  Location per platform.&lt;br /&gt;
&lt;br /&gt;
The File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced in the manifest file for the following 23 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the Asset Metadata File for HOUR 00'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the Asset Metadata File for HOUR 00):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged for all platforms during the whole day, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File Location for all platforms.&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced hourly in the manifest file for all the 24 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the global Asset Metadata File'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the global Asset Metadata File):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Global Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC for all Platforms=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the global Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! AGF Metadata Convention Name - &amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Only for your Reference&lt;br /&gt;
&amp;lt;/pre&amp;gt;  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid  || assetid|| Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c0) separated by an underscore character ('''&amp;lt;c7_c0&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname  || program || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || title || episode name || custom -  no backslash allowed in string (because of 3rd party data processing)  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen   || length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || N/A|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand ||  subbrand (vcid) || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
 &lt;br /&gt;
|-&lt;br /&gt;
| nol_c0   || nol_c0 || number of episode part (Sendungsteilenummer)   || custom, if a content is not divided into several episode parts, set &amp;quot;0&amp;quot; as value.  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2   || nol_c2 || web only  || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || nol_c5   || page URL   || custom, The “Page URL” custom variable is reserved for sending the video’s server address.  ||  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || nol_c7  || Video ID. This variable is applicable in case the video asset is broken into multiple files each with their own asset ID. If a client has a single asset for a given episode/program, the value here should be identical to the assetid already provided in the viewership file. &lt;br /&gt;
  || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || nol_c9  || episode title   || custom - no backslash allowed in string (because of 3rd party data processing). if no further differentiation, then use &amp;quot;episodetitle&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10  || nol_c10  || publisher   || custom, used to differentiate different publishers   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c12  || nol_c12  || type of asset   || &amp;quot;Trailer&amp;quot; or &amp;quot;Content&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15  || nol_c15   || format ID   || If nol_c2 is always Yes, then it can stay blank &amp;quot;&amp;quot;   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c16  || nol_c16   || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads)   || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes&amp;quot;, etc   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c18  || nol_c18  || is a live stream    || &amp;quot;Y&amp;quot; for live stream otherwise &amp;quot;N&amp;quot;  || ✓  &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c8   || nol_c8 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c13   || nol_c13  || custom variable   || custom   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c14   || nol_c14 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c19   || nol_c19  || custom variable   || custom   || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;programname&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;episodetitle&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c02&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,3&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,publisherName&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c0) separated by an underscore character ('''&amp;lt;c7_c0&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''ONLY for''' '''android''' platform, DO NOT pass device_id for '''ios''', '''browser''' and '''ott''' platforms.  Mobile Ad ID ,  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; - OPTIONAL if passed in the Audit Ping|| i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638655&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android Platform : Example Metadata with &amp;quot;device_id&amp;quot;  =====&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; not available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in the respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || '''ONLY for''' '''android''' platform, DO NOT pass devid for '''ios''', '''browser''' and '''ott''' platforms. devid,  SHA-256 value of Device Id (ADID) -  OPTIONAL if passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;intid=&amp;lt;Integration ID&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;Android ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;&amp;amp;intid=xxxxxxxx&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7635</id>
		<title>DCR Germany Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7635"/>
		<updated>2026-04-07T09:28:23Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a S2S Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S (Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (AppID)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have its own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but '''latest within 3 hours of the start of that hourly viewing file interval'''. For example, files from '''2:00 AM to 3:00 AM''' must be delivered latest before '''5 AM'''.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving an exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicit request from AGF.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported formats are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delivered to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''. Only for the Asset Metadata Optimization use case, '''all''' is used additionally, see [[#Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day|Optimization for all Platforms]]&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653476400&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| end_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653479999&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
    &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
    &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Asset Metadata Delivery Optimization===&lt;br /&gt;
&lt;br /&gt;
====Optimization when the Asset Metadata File remains unchanged during the whole day per platform====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged during the whole day per platform, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File  Location per platform.&lt;br /&gt;
&lt;br /&gt;
The File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced in the manifest file for the following 23 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the Asset Metadata File for HOUR 00'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the Asset Metadata File for HOUR 00):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged for all platforms during the whole day, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File Location for all platforms.&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced hourly in the manifest file for all the 24 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the global Asset Metadata File'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the global Asset Metadata File):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Global Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC for all Platforms=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the global Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! AGF Metadata Convention Name - &amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Only for your Reference&lt;br /&gt;
&amp;lt;/pre&amp;gt;  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid  || assetid|| Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c0) separated by an underscore character ('''&amp;lt;c7_c0&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname  || program || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || title || episode name || custom -  no backslash allowed in string (because of 3rd party data processing)  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen   || length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || N/A|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand ||  subbrand (vcid) || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
 &lt;br /&gt;
|-&lt;br /&gt;
| nol_c0   || nol_c0 || number of episode part (Sendungsteilenummer)   || custom, if a content is not divided into several episode parts, set &amp;quot;0&amp;quot; as value.  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2   || nol_c2 || web only  || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || nol_c5   || page URL   || custom, The “Page URL” custom variable is reserved for sending the video’s server address.  ||  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || nol_c7  || Video ID. This variable is applicable in case the video asset is broken into multiple files each with their own asset ID. If a client has a single asset for a given episode/program, the value here should be identical to the assetid already provided in the viewership file. &lt;br /&gt;
  || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || nol_c9  || episode title   || custom - no backslash allowed in string (because of 3rd party data processing). if no further differentiation, then use &amp;quot;episodetitle&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10  || nol_c10  || publisher   || custom, used to differentiate different publishers   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c12  || nol_c12  || type of asset   || &amp;quot;Trailer&amp;quot; or &amp;quot;Content&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15  || nol_c15   || format ID   || If nol_c2 is always Yes, then it can stay blank &amp;quot;&amp;quot;   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c16  || nol_c16   || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads)   || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes&amp;quot;, etc   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c18  || nol_c18  || is a live stream    || &amp;quot;Y&amp;quot; for live stream otherwise &amp;quot;N&amp;quot;  || ✓  &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c8   || nol_c8 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c13   || nol_c13  || custom variable   || custom   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c14   || nol_c14 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c19   || nol_c19  || custom variable   || custom   || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;programname&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;episodetitle&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c02&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,3&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,publisherName&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''ONLY for''' '''android''' platform, DO NOT pass device_id for '''ios''', '''browser''' and '''ott''' platforms.  Mobile Ad ID ,  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; - OPTIONAL if passed in the Audit Ping|| i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638655&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android Platform : Example Metadata with &amp;quot;device_id&amp;quot;  =====&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; not available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in the respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || '''ONLY for''' '''android''' platform, DO NOT pass devid for '''ios''', '''browser''' and '''ott''' platforms. devid,  SHA-256 value of Device Id (ADID) -  OPTIONAL if passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;intid=&amp;lt;Integration ID&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;Android ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;&amp;amp;intid=xxxxxxxx&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7634</id>
		<title>DCR Germany Video Cloud API</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7634"/>
		<updated>2026-04-07T09:27:37Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing Cloud API =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a Cloud API Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging Cloud API Endpoint until you get the green light from Nielsen to move to Production!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
 || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Integration==&lt;br /&gt;
We will cover the steps for constructing the Cloud API Calls.&lt;br /&gt;
&lt;br /&gt;
====URL Structure====&lt;br /&gt;
&lt;br /&gt;
The Cloud API Calls are HTTP GET Requests with the URL structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;[endpoint]/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The URL includes the following components:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;[endpoint]&amp;lt;/code&amp;gt;: location of data collection environment&lt;br /&gt;
*&amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt;: provided App ID. &amp;lt;br&amp;gt;'''Note:'''The &amp;quot;P&amp;quot; prefix must be removed from the App ID received before adding it to the URL, i.e. if you received PDF20695-XXXX-XXXX-XXXX-3E334133D917 from Nielsen , your url will then be : &amp;lt;code&amp;gt;[endpoint]/DF20695-XXXX-XXXX-XXXX-3E334133D917/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;: unique value for each user session&lt;br /&gt;
*&amp;lt;code&amp;gt;[payload]&amp;lt;/code&amp;gt;: metadata and events&lt;br /&gt;
&lt;br /&gt;
====Endpoint====&lt;br /&gt;
&lt;br /&gt;
There are endpoints for testing and production:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide.&lt;br /&gt;
&lt;br /&gt;
====URL Example====&lt;br /&gt;
As you move through the integration steps, you can reference the below URL structure with the expanded payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content_metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event],&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playhead_position],&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type],&lt;br /&gt;
  &amp;quot;utc&amp;quot;: [Unix time in ms],&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: [unique view session ID for each video play]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create Session ID and send EMM Ping===&lt;br /&gt;
&lt;br /&gt;
====Create Session ID====&lt;br /&gt;
&lt;br /&gt;
A unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app.&lt;br /&gt;
&lt;br /&gt;
A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference and use.&lt;br /&gt;
&lt;br /&gt;
Session ID example: '''LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
'''// Create random GUID'''&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon exiting the app, the session will need to be terminated using the delete event. &amp;lt;br&amp;gt;&lt;br /&gt;
Sessions will automatically expire after 30 minutes of cloud inactivity.&lt;br /&gt;
&lt;br /&gt;
==== Send EMM Ping ====&lt;br /&gt;
An EMM Ping must be sent using the created unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; upon start of the first stream playback.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://[sessionID].uaid.nmrodam.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also see  [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference.&lt;br /&gt;
&lt;br /&gt;
===Create View Session ID for each Video Start===&lt;br /&gt;
An View Session ID &amp;lt;code&amp;gt;[sessid]&amp;lt;/code&amp;gt; must be created upon start of each stream playback, sessid is unique per video play.&lt;br /&gt;
&lt;br /&gt;
===Define URL Structure===&lt;br /&gt;
Define the URL structure using your provided &amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt; and a unique &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure Payload===&lt;br /&gt;
&lt;br /&gt;
====Description Payload====&lt;br /&gt;
&lt;br /&gt;
All Cloud API requests must contain the following payload data:&lt;br /&gt;
&lt;br /&gt;
*''devInfo'': device and app info&lt;br /&gt;
*''metadata'': asset metadata&lt;br /&gt;
*''event metadata'': type of event&lt;br /&gt;
&lt;br /&gt;
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section.&lt;br /&gt;
&lt;br /&gt;
==== Payload Example ====&lt;br /&gt;
&lt;br /&gt;
The example below should be referenced when following the steps for configuring the request payload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// 1. Create Session ID using the UUID Generator code provided&lt;br /&gt;
sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088  // Example sessionID &lt;br /&gt;
&lt;br /&gt;
// 2. Define URL Structure with App ID and Session ID&lt;br /&gt;
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
&lt;br /&gt;
// 3. Configure Payload&lt;br /&gt;
// 3.1 Configure Payload: devInfo &lt;br /&gt;
payload = {&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
   &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  // 3.2 Configure Payload: metadata&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: { // object for measuring video content&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  // 3.3 Configure Payload: events&lt;br /&gt;
  &amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, //event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, // position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, //&amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1456448742000&amp;quot;, //unix timestamp in milliseconds &lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot; // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Configure Payload: devInfo====&lt;br /&gt;
An object &amp;lt;code&amp;gt;&amp;quot;devInfo&amp;quot;&amp;lt;/code&amp;gt; will need to be created to capture App and Device information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| devId || unique ID to identify user (e.g. Advertising ID, Roku Device ID) - Not required for AGF || custom || &lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Example devInfo Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create devInfo object&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3.2 Configure Payload: metadata ====&lt;br /&gt;
Asset metadata can be passed through &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt;. There are two asset types: &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; for video and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; for ads. The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
You will need to set up &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt; objects for &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
===== Content Metadata =====&lt;br /&gt;
&lt;br /&gt;
====== Description of Content metadata ======&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c0) separated by an underscore character ('''&amp;lt;c7_c0&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Example Content metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang='json'&amp;gt;// create content object&lt;br /&gt;
&amp;quot;content&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ad Metadata (optional for public broadcasters) =====&lt;br /&gt;
====== Description of Ad metadata ======&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the Ad asset corresponding to  the  AGF custom variable '''c11'''.&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Example Ad metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;      &lt;br /&gt;
}&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Payload: Events ====&lt;br /&gt;
&lt;br /&gt;
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below.&lt;br /&gt;
&lt;br /&gt;
===== Event Types =====&lt;br /&gt;
&lt;br /&gt;
The available events are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; || &lt;br /&gt;
&lt;br /&gt;
===== Handling Playhead =====&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; is critical for accurate duration crediting. You can reference the below guidance to determine the correct playhead position to pass depending on the playback scenario.&lt;br /&gt;
&lt;br /&gt;
'''General'''&lt;br /&gt;
* Playhead position in seconds, must be passed as a whole number every 10 seconds. &lt;br /&gt;
* The final playhead position should be sent before before sending &amp;quot;complete&amp;quot; event when content playback is complete. &lt;br /&gt;
&lt;br /&gt;
'''Live Stream'''&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position. Note that ad playheads must also use Unix Time for each single Ad in an Ad Pod.&lt;br /&gt;
&lt;br /&gt;
'''VoD Stream'''&lt;br /&gt;
* For VoD stream use the player position for Content and Ad at playback start of a content or single Ad in an Ad Pod, playheads will then be 0, 10, 20, ....&lt;br /&gt;
&lt;br /&gt;
'''End of an Asset'''&lt;br /&gt;
* Final postion must be sent at the end of Content or Ad playback&lt;br /&gt;
&lt;br /&gt;
'''Ads'''&lt;br /&gt;
* The final playhead position must be sent when switching from content to ad, or ad to content.&lt;br /&gt;
* For Ad Pods, playhead must be called for each individual ad.&lt;br /&gt;
* When content has resumed following a mid-roll ad break, the next playhead position must continue where the previous content segment left off.&lt;br /&gt;
&lt;br /&gt;
'''User Actions'''&lt;br /&gt;
* SCRUBBING: Upon user scrubbing, the current position must be sent before a user scrubs, and the new position should be sent where the user lands, and begin sending in the 10 second updates thereafter.&lt;br /&gt;
* PAUSE: When content is paused, send current playhead position and stop passing playhead position until content is resumed.&lt;br /&gt;
* EXIT Stream: If a user exits a stream early, the last current position must be sent in a playhead update to receive accurate duration.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt; || The complete event must be sent : &lt;br /&gt;
* when the current video asset playback is terminated or completed, &lt;br /&gt;
* at the end of the current stream playback when the user switches to another piece of content or when the App is closed.&lt;br /&gt;
Before calling the complete event, a final playhead update with the final position is required to be sent to receive full duration credit. For Live streams, a complete event must be sent at program boundaries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || The delete event is optional and can be sent when the viewing session is terminated (typically on App close). A new session ID must be generated after sending a delete event. Delete should not be sent on app interruptions or foreground/background events. All creditable duration will be summarized for all asset types when delete occurs (content and ads).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Event Parameters =====&lt;br /&gt;
&lt;br /&gt;
The following parameters need to be passed when calling events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description !! Value !! Required&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;event&amp;quot;&amp;lt;/code&amp;gt; || event type || &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;position&amp;quot;&amp;lt;/code&amp;gt; || playhead position in seconds or Unix time in seconds || &amp;lt;code&amp;gt;&amp;quot;300&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;&amp;lt;/code&amp;gt; || asset type || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;utc&amp;quot;&amp;lt;/code&amp;gt; || Unix timestamp in milliseconds. Must be passed every 10 seconds. || &amp;lt;code&amp;gt;&amp;quot;1472760000000&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;sessid&amp;quot;&amp;lt;/code&amp;gt; || Unique View Session ID must be created upon start of each stream playback, sessid is unique per video play. || &amp;lt;code&amp;gt;&amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Event =====&lt;br /&gt;
You can call events by passing values in the required parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  // Event Parameters&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event], // event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playheadPosition], //position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type], // values are &amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;, //unix timestamp in milliseconds&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The full payload including &amp;quot;devInfo&amp;quot; and &amp;quot;metadata&amp;quot; must be populated in each event request.&lt;br /&gt;
&lt;br /&gt;
===== Sample Event Lifecycle for VoD Stream =====&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events and values to pass.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// Preroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Content&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content resumes at 15 minutes&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;900&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 30 minutes&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;1800&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Postroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Sample Event Lifecycle for VoD Stream - Detailed Storyline'''&lt;br /&gt;
This detailed event sequence provides additional insight for the correct events to call when handling certain playback scenarios.&lt;br /&gt;
&amp;lt;syntaxhighlight lang='javascript'&amp;gt;// SESSION STARTS&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// PREROLL&lt;br /&gt;
// Preroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Preroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;15&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
// CONTENT &lt;br /&gt;
// Content Start - Start new content streams with a position of &amp;quot;0&amp;quot; incrementing the position every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content Stop Before Ad Break - Send a playhead update including the current content positon before an Ad break.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;299&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787400000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
// Midroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;60&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472793500000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
// Content resumes at 5 minutes - Send playhead update with the current resumed position, and begin incrimenting the positon every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472799500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 10:12 - Make sure to send in the playhead event with the final content position before sending the complete event.&lt;br /&gt;
Final Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830700000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830800000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// POSTROLL&lt;br /&gt;
// Postroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830900000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Postroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;45&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835300000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// SESSION ENDS&lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835400000&amp;quot;} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Interruption Scenarios =====&lt;br /&gt;
&lt;br /&gt;
As part of configuring events, you will need to handle all possible interruption scenarios such as:&lt;br /&gt;
&lt;br /&gt;
*Wi-Fi OFF / ON&lt;br /&gt;
*App Crash or Exit&lt;br /&gt;
&lt;br /&gt;
When playback is interrupted, the app needs to send delete immediately.&lt;br /&gt;
&lt;br /&gt;
Once playback resumes, a new session will need to be created with a unique session ID. All of the required metadata and events will need to be sent.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The session will automatically timeout after 30 minutes of inactivity.&lt;br /&gt;
&lt;br /&gt;
=== Example Request ===&lt;br /&gt;
&lt;br /&gt;
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration.&lt;br /&gt;
&lt;br /&gt;
see '''[[#Payload Example|Payload Example]]'''&lt;br /&gt;
&lt;br /&gt;
// Append payload to URL&lt;br /&gt;
function sendPayloadToNielsen() {&lt;br /&gt;
  var payloadStr  = JSON.stringify(payload); // payload as string&lt;br /&gt;
  var imgPing = new Image();&lt;br /&gt;
  imgPing.onload = function() {&lt;br /&gt;
    // onload event, payload succesfull sent&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.onerror = function() {&lt;br /&gt;
    // handle error i.e. wait and send again&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.src = sessionURL+encodeURIComponent(payloadStr);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable Debug Logging ===&lt;br /&gt;
&lt;br /&gt;
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification.&lt;br /&gt;
&lt;br /&gt;
==== GET Request ====&lt;br /&gt;
&lt;br /&gt;
Display GET Request to console using a name to identify each event (e.g. playhead).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event&amp;quot;, image); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Output payload to identify required metadata and events.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event Payload&amp;quot;, payload); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response Code ====&lt;br /&gt;
&lt;br /&gt;
Confirm request was completed by viewing HTTP response code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
code = msg.GetResponseCode();&lt;br /&gt;
console.log(&amp;quot;Response Code&amp;quot;, code);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can reference the HTTP Response Code table when reviewing your requests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Status Code !! Status Text !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;200&amp;lt;/code&amp;gt; || OK || request received&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;403&amp;lt;/code&amp;gt; || Forbidden || invalid App ID&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;404&amp;lt;/code&amp;gt; || Not Found || JSON issue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll and postroll Ads.&lt;br /&gt;
&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; in the &amp;lt;code&amp;gt;Playback Settings&amp;lt;/code&amp;gt; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for AGF by selection Germany in the country dropbox [https://nielsenonlinesupport.com/agf/RefImplCloudAPI/index.htm?debug=true RefImplCloudAPI].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen CloudAPI Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen Cloud API measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Cloud API measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
&lt;br /&gt;
A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Before providing an app build to Nielsen for testing, it is important to run validation checks once you have enabled debug logging.&lt;br /&gt;
&lt;br /&gt;
=== Payload Validation ===&lt;br /&gt;
&lt;br /&gt;
Ensure that all of the required payload data is populating while testing several videos. The following areas are critical to measurement:&lt;br /&gt;
*devInfo&lt;br /&gt;
*Asset metadata for both content, and ads&lt;br /&gt;
*Events&lt;br /&gt;
&lt;br /&gt;
=== Player Events ===&lt;br /&gt;
Review event calls:&lt;br /&gt;
&lt;br /&gt;
==== playhead ====&lt;br /&gt;
*Playhead position updates every 10 seconds starting at position '0' for each new asset for VoD stream and UTC Unix Time in seconds for Live stream.&lt;br /&gt;
*Final playhead position is sent on content, or ad before switching between assets.&lt;br /&gt;
*Content metadata remains constant throughout an episode, or clip play.&lt;br /&gt;
*Ad metadata is populated appropriately for each individual ad.&lt;br /&gt;
*Playhead position update resumes for content after an ad break, and resets to 0 for each individual ad.&lt;br /&gt;
*For scrubbing, last current position should be sent while scrubbing occurs, and the new position should also be sent where the user scrubs to.&lt;br /&gt;
*Exiting a stream early should execute the last current position in a playhead update to receive accurate duration.&lt;br /&gt;
*Upon pause, the current position should be sent, and playhead updates should stop incrementing until resume play occurs.&lt;br /&gt;
&lt;br /&gt;
==== complete ====&lt;br /&gt;
*Check that the complete event executes upon content complete after the final playhead update is sent&lt;br /&gt;
*Do not execute the complete event for ads&lt;br /&gt;
&lt;br /&gt;
==== delete ====&lt;br /&gt;
*Check to see that the delete event occurs upon app exit, if the platform has the necessary exit callback events.&lt;br /&gt;
&lt;br /&gt;
==== GET Request Format ====&lt;br /&gt;
*Ensure that the event payloads are formatted in JSON&lt;br /&gt;
*Check to see that each of the Cloud API GET requests are properly encoded&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response ====&lt;br /&gt;
*Make sure that each of the Cloud API Get requests are received by the Nielsen Cloud API properly through use of the HTTP Response Code outputs enabled in console.&lt;br /&gt;
&lt;br /&gt;
== Go Live ==&lt;br /&gt;
After your integration has been certified, you will need to: Change Endpoint and Disable Logging.&lt;br /&gt;
&lt;br /&gt;
'''Change Endpoint:''' You will need to update to the production endpoint:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Production: &amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your production URL structure should now be:&lt;br /&gt;
&amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Disable Logging:''' You can now disable debug logging&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7633</id>
		<title>DCR Germany Video App SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7633"/>
		<updated>2026-04-07T09:27:09Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR), [[Digital Audio]]. Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long the app was running&lt;br /&gt;
*Time of viewing a sub-section/page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following details are required:&lt;br /&gt;
* '''App ID (appid):''' Unique ID assigned to the player/site and configured by product.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''No ID AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;ONLY the No ID AppSDK should be downloaded for the AGF market!&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Nielsen SDK:''' The Nielsen SDK package contains a variety of sample players for your reference.&lt;br /&gt;
Please contact our SDK sales support team if you do not have any of these prerequisites or have any questions.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode and Android using Android Studio.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
&lt;br /&gt;
=== iOS  ===&lt;br /&gt;
&lt;br /&gt;
==== Special Notes regarding iOS17 or TVOS17  ====&lt;br /&gt;
Beginning with iOS/TVOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs.&lt;br /&gt;
&lt;br /&gt;
Since AGF market is not making use of the IDFA, the change is expected to have no impact.&lt;br /&gt;
&lt;br /&gt;
However, in order to minimize any eventual impact, we are asking that AGF clients do the following:&lt;br /&gt;
&lt;br /&gt;
* '''Do not declare the Nielsen nmrodam.com domain in the privacy manifest'''&lt;br /&gt;
* Update to the latest Nielsen SDK release &amp;gt;= 9.2.0.0 when compiling your app for iOS 17&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For any additional information please refer to the Nielsen global page: [[DCR and DTVR with iOS17 or TVOS17]].&lt;br /&gt;
&lt;br /&gt;
==== General  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Xcode Development Environment''' &lt;br /&gt;
&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK is compatible with Apple iOS versions 9.0 and above.&lt;br /&gt;
&lt;br /&gt;
The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Importing Frameworks'''&amp;lt;/big&amp;gt;&lt;br /&gt;
The first step is to ensure that the following frameworks and libraries are imported into the Frameworks folder of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework uses several functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework &lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Example'''&lt;br /&gt;
* Extract “NielsenAppApi.Framework” from the Nielsen App SDK sample app and copy it to the Frameworks folder of the Xcode project.&lt;br /&gt;
* Add the code &amp;lt;code&amp;gt;-#import NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller’s header file.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Ensure that the following are included in the Linked Frameworks and Libraries list (located in the project’s Summary settings).&lt;br /&gt;
* Nielsen App SDK&lt;br /&gt;
* iOS security framework&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Swift'''&amp;lt;/big&amp;gt;&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Objective-C'''&amp;lt;/big&amp;gt;&lt;br /&gt;
Add the code &lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Android  ===&lt;br /&gt;
==== General  ====&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Android Java Development Environment'''&lt;br /&gt;
&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The Nielsen App SDK (located in the ''com.nielsen.app.sdk'' package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
&lt;br /&gt;
'''Nielsen App SDK is compatible with Android OS versions 2.3+. Clients can control/configure the protocol to be used – HTTPS or HTTP to suit their needs.'''&lt;br /&gt;
&lt;br /&gt;
The Nielsen App SDK 1.2 library is composed of two parts:&lt;br /&gt;
* The Java AppSdk.jar library runs on the Android’s Dalvik Virtual Machine.&lt;br /&gt;
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.&lt;br /&gt;
* '''For Video player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 3.0 and later will support it natively).&lt;br /&gt;
** If the player application uses a 3rd party media player implementing its own HLS, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
* '''For Audio player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should be at version 2.3 and later since the SDK depends on Google Play support to work properly.&lt;br /&gt;
Unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.&lt;br /&gt;
Add the following permissions on the project’s ''AndroidManifest.xml'' file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For more details on handling runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.&lt;br /&gt;
* App SDK checks to see if a Google service is available and updated.&lt;br /&gt;
* If unavailable or updated, App SDK will not use this service when executing its functions and will reference missing imports and the app will not be compiled.&lt;br /&gt;
To include the Google Play library in the media player project, copy the ''google-play-services_lib'' folder into the same location as the project&lt;br /&gt;
* Access '''File &amp;gt; Import'''.&lt;br /&gt;
* Select '''Existing Android Code into Workspace''' and click '''Next'''.&lt;br /&gt;
* Click '''Browse''' and navigate to the ''google-play-services_lib'' to include it into the projects.&lt;br /&gt;
* Select the exact '''Project Build Target''' for Eclipse to use from Android SDK.&lt;br /&gt;
** Android 4.4.2, etc. OR&lt;br /&gt;
** Edit ''project.properties'' file to point to Android target version e.g. target= android-19.&lt;br /&gt;
Once the google-play-services_lib is included into the App project, include the following code under the &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; node in the &amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data android:name=&amp;quot;com.google.android.gms.version&amp;quot; android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, include the ''version.xml'' file that comes with the ''google-play-services_lib'' under the res/values directory of the media player project.&lt;br /&gt;
* Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Library'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Classes/package&amp;lt;/big&amp;gt;'''&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
==== Add the dependency &amp;quot;lifecycle-extensions&amp;quot; to your project  ====&lt;br /&gt;
Add the dependency &amp;quot;lifecycle-extensions&amp;quot; in the in the app gradle file as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will enable the AppSdk to detect the application UI visibility state transitions between background and foreground by utilizing the LifeCycleObserver. This is i.e. required for the Static Measurement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated before version 5.1.1. (Version 4.0 for Android)&lt;br /&gt;
&lt;br /&gt;
* A maximum of four SDK instances per appid are supported. When a fifth SDK instance is launched, the SDK will return “nil” from [[initWithAppInfo:delegate:]]&lt;br /&gt;
* When four SDK instances exist, you must destroy an old instance before creating a new one.&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
&lt;br /&gt;
* The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || No || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || Client-defined || No || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
'''AGF Clients'''&lt;br /&gt;
* &amp;quot;eu&amp;quot; (For Testing/Certification and in Production)&lt;br /&gt;
|| Nielsen-specified || ✓ || &amp;quot;eu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Has to be set to &amp;quot;DEBUG&amp;quot; until certified&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
=====  iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
    &lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======  Objective-C ======&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====  Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&lt;br /&gt;
AppSDK is no longer a singleton object and should be initialized as below.&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;appname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sfcode&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on the type of client app.&amp;lt;br /&amp;gt;&lt;br /&gt;
* Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on the property page of the App’s project).&lt;br /&gt;
&lt;br /&gt;
== APP SDK Error &amp;amp; Event Codes ==&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
== Configure Payload ==&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handle only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of the unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** The error message will be logged if the string has an invalid JSON format.&lt;br /&gt;
* JSON value must be a string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
&lt;br /&gt;
=== Configure ChannelInfo metadata === &lt;br /&gt;
==== Description of ChannelInfo metadata ====&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ChannelInfo metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
       let channelInfo = [&lt;br /&gt;
            &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Configure Content metadata ===&lt;br /&gt;
&lt;br /&gt;
==== Description of Content metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c0) separated by an underscore character ('''&amp;lt;c7_c0&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example Content metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
	&amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
        &lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;, &lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;88675545&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;3600&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;88675545&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;3600&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c0&amp;quot;, &amp;quot;p0,1&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c2&amp;quot;, &amp;quot;p2,Y&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c7&amp;quot;, &amp;quot;p7,videoid123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c9&amp;quot;, &amp;quot;p9,VideoTitle123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c18&amp;quot;, &amp;quot;p18,N&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure Ad Metadata ===&lt;br /&gt;
==== Description of Ad metadata ====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the Ad asset corresponding to  the  AGF custom variable '''c11'''.&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
let adMetadata = [&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;preroll&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;ad345-67483&amp;quot;&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;ad_title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;25&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JSONObject adMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;preroll&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;ad345-67483&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;25&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c11&amp;quot;, &amp;quot;p11,2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Werbung&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c17&amp;quot;, &amp;quot;p17,preroll&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
=== Sample API Sequence ===&lt;br /&gt;
A Sample API sequence could follow this flow:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;[nielsenMeter play: channelName];&amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadataObject];&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;[nielsenMeter playheadPosition: position];&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;[nielsenMeter end];&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Life cycle of SDK instance ===&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance processes playing information. [[play]] and [[loadMetadata]] calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## [[playheadPosition]] – Call this API every one second when playhead position timer is fired.&lt;br /&gt;
## [[stop]] – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## [[end]] – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to pause the measurement.&lt;br /&gt;
* As soon as the playback resumes, call [[loadMetadata]] and  [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
'''[[#Example Content metadata|Example Content metadata]]'''&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the stream playback is interrupted or has ended.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: ONLY for a preroll Ad , Call [[loadMetadata()]] for Content before calling it for preroll ad &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
'''[[#Example Ad metadata|Example Ad metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the Ad playback is interrupted or has ended for each single Ad. Playhead should be passed for the entire duration of ad pod, if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after the content is paused (ad starts)&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the midroll ad is being played &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content (Content resume) || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Always call stop irrespective of postroll is followed or not&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequence of Calls ===&lt;br /&gt;
&lt;br /&gt;
=== play ===&lt;br /&gt;
Use [[play]] to pass the channel descriptor information through channelName parameter after the SDK has been initialized and the content starts playing. If the user is returning from a '''Pause/Stop''' interaction, call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   - (void)play:(id)channelInfo;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    public void play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenAppApi?.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void)loadMetadata:(id)contentMetadata;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;playheadPosition&amp;quot; has to be called every second.&lt;br /&gt;
&lt;br /&gt;
* VOD : &lt;br /&gt;
** For Content and each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
*Live : &lt;br /&gt;
**For Content, pass the Unix timestamp (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... . &lt;br /&gt;
**For each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
– (void) playheadPosition: (long long) playheadPos&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
AVPlayer *player;&lt;br /&gt;
CMTime curTime=[player currentTime];&lt;br /&gt;
int pos = CMTimeGetSeconds(curTime);&lt;br /&gt;
[nAppApiObject playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        //Monitor the Playhead position of the AVPlayer&lt;br /&gt;
        let timeInterval: CMTime = CMTimeMakeWithSeconds(1.0,10)&lt;br /&gt;
        self.avPlayerViewController.player?.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) {(elapsedTime: CMTime) -&amp;gt; Void in&lt;br /&gt;
            if self.avPlayerViewController.player!.currentItem?.status == .readyToPlay {&lt;br /&gt;
                let time : Float64 = self.avPlayerViewController.player!.currentTime().seconds;&lt;br /&gt;
                let pos = Int64(time);&lt;br /&gt;
                NSLog(&amp;quot;New Elapse Time = \(time)&amp;quot;);&lt;br /&gt;
                self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void setPlayheadPosition(long position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void) stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
Call when the content asset completes playback. Stops measurement progress. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;- (void) end;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending [[playheadPosition]] once the playback resumes (no [[loadMetadata]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional information:&lt;br /&gt;
* '''For type 'content': '''Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== App termination ===&lt;br /&gt;
If your app is executing a termination process and therefore ending the Content or Ad Playback, call [[end]] if the Content is playing or [[stop]] if an Ad is playing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
&lt;br /&gt;
The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain.&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
 &lt;br /&gt;
Please contact your Nielsen SDK support team directly for any related questions.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
#* '''Example Production Initialization Call''' - Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;iOS Example:&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Android Example:&amp;lt;/big&amp;gt;''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live, you have to inform the Nielsen team - this is necessary because the Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7632</id>
		<title>DCR Germany Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7632"/>
		<updated>2026-04-07T09:25:54Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK is the framework for browser developers to integrate Nielsen Measurement into their media player pages. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of pages like:&lt;br /&gt;
*Site launch events and how long page is viewed&lt;br /&gt;
*Time of viewing a sub-section / page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Please note:'''&lt;br /&gt;
The Browser SDK is intended to be used for native Browser implementations and cannot be used in a hybrid framework environment on Apps (Android, iOS) - e.g. for Cordova. Only native webview implementations may work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To get started, an AppID is needed. The AppID is a unique ID assigned to the player/site/app. This will be provided upon starting the integration from Nielsen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  apid: &amp;quot;XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot; // eg. PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* NLSQUEUE build v*/&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration files 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.&lt;br /&gt;
&lt;br /&gt;
===Create SDK Instance===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When creating an instance, pass the following three values:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/site ||	'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging. Only required for testing (not in production) || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;})&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example SDK Initialization ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on the apid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.eu.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Configuration ===&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique AppID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	// Add Static Queue Snippet&lt;br /&gt;
	!function(e,n){&lt;br /&gt;
		function t(e){&lt;br /&gt;
			return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
		}&lt;br /&gt;
		e[n]=e[n]||&lt;br /&gt;
		{&lt;br /&gt;
			nlsQ:function(o,r,c){&lt;br /&gt;
				var s=e.document,&lt;br /&gt;
				a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
				a.async=1,&lt;br /&gt;
				a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
				var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
				return i.parentNode.insertBefore(a,i),&lt;br /&gt;
				e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
				e[n][r]&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	// Created SDK Instance&lt;br /&gt;
	var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;, {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. Users will need to set up content and ad objects with the required Nielsen keys, as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Content Metadata ====&lt;br /&gt;
&lt;br /&gt;
===== Description of Content metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c0) separated by an underscore character ('''&amp;lt;c7_c0&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Example Content metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var content_metadata_object = {  &lt;br /&gt;
  type:     'content',&lt;br /&gt;
  assetid:  '88675545',&lt;br /&gt;
  program:  'Program Name',&lt;br /&gt;
  title:    'episode title',&lt;br /&gt;
  length:   '3600',&lt;br /&gt;
  nol_c0:  'p0,1',&lt;br /&gt;
  nol_c2:  'p2,Y',&lt;br /&gt;
  nol_c7:  'p7,videoid123',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c9:  'p9,VideoTitle123',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c12: 'p12,Content',&lt;br /&gt;
  nol_c18: 'p18,N'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ad Metadata ====&lt;br /&gt;
===== Description of Ad metadata =====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the Ad asset corresponding to  the  AGF custom variable '''c11'''.&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Ad metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var ad_metadata_object = {  &lt;br /&gt;
  type:     'preroll',&lt;br /&gt;
  assetid:  'ad345-67483',&lt;br /&gt;
  title:    'ad_title',&lt;br /&gt;
  length:   '25',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c11: 'p11,2352723141',&lt;br /&gt;
  nol_c12: 'p12,Werbung',&lt;br /&gt;
  nol_c17: 'p17,preroll'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Pause Event ===&lt;br /&gt;
To indicate pause&lt;br /&gt;
&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Send '''loadMetadata''' with the same metadata and continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
&lt;br /&gt;
=== Other Interrupt Scenarios ===&lt;br /&gt;
The following possible browser interruption scenarios must be handled:&lt;br /&gt;
&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
&lt;br /&gt;
There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. midroll vs. content).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var stopped = false;&lt;br /&gt;
function closePlayer() {&lt;br /&gt;
	if (stopped) {return;}&lt;br /&gt;
	stopped = true;&lt;br /&gt;
	if (inMidroll) {    // Only inside a midroll indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
		nSdkInstance.ggPM('stop', playheadPositionMidroll);&lt;br /&gt;
	}&lt;br /&gt;
	nSdkInstance.ggPM('end', playheadPositionContent);    // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
};&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer or covering Safari on mobile browsers ... you may use &amp;quot;onpagehide&amp;quot; event as well).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Call Nielsen APIs ==&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad)&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
*&amp;quot;VOD (or ad ): || current position in seconds (integer) &amp;lt;br/&amp;gt;&lt;br /&gt;
*&amp;quot;Live: current UTC timestamp (seconds since January 1st 1970)&amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position in seconds	|| Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==  SDK Event Lifecycle ==&lt;br /&gt;
&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Examples|&lt;br /&gt;
without Ads|&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle without ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:even browser no ads.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example without ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);  // must be called as start of stream&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playheads every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|with Ads=&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle with ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:event browser.png|event browser.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example with ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); // must be called as start of stream (even if 1st asset is preroll)&lt;br /&gt;
 &lt;br /&gt;
// PREROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end pre-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 for the first segment (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
  &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end mid-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from where it left off before mid-roll (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); &lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// POSTROLL&lt;br /&gt;
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); // end post-roll stream&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
* 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.&lt;br /&gt;
&lt;br /&gt;
* after an 'end' in case there is a new content played, there is a need to have another 'loadmetadata' again.&lt;br /&gt;
&lt;br /&gt;
* For Ad, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&lt;br /&gt;
* For pre-roll ads you have to call the loadMetadata event for content at the start of stream and after the preroll&lt;br /&gt;
&lt;br /&gt;
* '''For type 'content' ''': Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
== Livestream ==&lt;br /&gt;
For '''Livestreams'''  please make sure playheadPosition is in UNIX-Timestamp for Content.&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
The Browser SDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Browser SDK measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make a couple of updates to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7631</id>
		<title>DCR Germany Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7631"/>
		<updated>2026-04-07T08:42:25Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Body Record */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a S2S Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S (Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (AppID)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have its own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but '''latest within 3 hours of the start of that hourly viewing file interval'''. For example, files from '''2:00 AM to 3:00 AM''' must be delivered latest before '''5 AM'''.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving an exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicit request from AGF.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported formats are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delivered to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''. Only for the Asset Metadata Optimization use case, '''all''' is used additionally, see [[#Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day|Optimization for all Platforms]]&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653476400&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| end_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653479999&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
    &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
    &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Asset Metadata Delivery Optimization===&lt;br /&gt;
&lt;br /&gt;
====Optimization when the Asset Metadata File remains unchanged during the whole day per platform====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged during the whole day per platform, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File  Location per platform.&lt;br /&gt;
&lt;br /&gt;
The File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced in the manifest file for the following 23 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the Asset Metadata File for HOUR 00'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the Asset Metadata File for HOUR 00):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged for all platforms during the whole day, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File Location for all platforms.&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced hourly in the manifest file for all the 24 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the global Asset Metadata File'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the global Asset Metadata File):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Global Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC for all Platforms=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the global Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! AGF Metadata Convention Name - &amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Only for your Reference&lt;br /&gt;
&amp;lt;/pre&amp;gt;  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid  || assetid|| Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname  || program || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || title || episode name || custom -  no backslash allowed in string (because of 3rd party data processing)  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen   || length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || N/A|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand ||  subbrand (vcid) || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
 &lt;br /&gt;
|-&lt;br /&gt;
| nol_c0   || nol_c0 || number of episode part (Sendungsteilenummer)   || custom, if a content is not divided into several episode parts, set &amp;quot;0&amp;quot; as value.  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2   || nol_c2 || web only  || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || nol_c5   || page URL   || custom, The “Page URL” custom variable is reserved for sending the video’s server address.  ||  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || nol_c7  || Video ID. This variable is applicable in case the video asset is broken into multiple files each with their own asset ID. If a client has a single asset for a given episode/program, the value here should be identical to the assetid already provided in the viewership file. &lt;br /&gt;
  || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || nol_c9  || episode title   || custom - no backslash allowed in string (because of 3rd party data processing). if no further differentiation, then use &amp;quot;episodetitle&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10  || nol_c10  || publisher   || custom, used to differentiate different publishers   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c12  || nol_c12  || type of asset   || &amp;quot;Trailer&amp;quot; or &amp;quot;Content&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15  || nol_c15   || format ID   || If nol_c2 is always Yes, then it can stay blank &amp;quot;&amp;quot;   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c16  || nol_c16   || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads)   || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes&amp;quot;, etc   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c18  || nol_c18  || is a live stream    || &amp;quot;Y&amp;quot; for live stream otherwise &amp;quot;N&amp;quot;  || ✓  &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c8   || nol_c8 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c13   || nol_c13  || custom variable   || custom   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c14   || nol_c14 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c19   || nol_c19  || custom variable   || custom   || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;programname&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;episodetitle&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c02&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,3&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,publisherName&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''ONLY for''' '''android''' platform, DO NOT pass device_id for '''ios''', '''browser''' and '''ott''' platforms.  Mobile Ad ID ,  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; - OPTIONAL if passed in the Audit Ping|| i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638655&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android Platform : Example Metadata with &amp;quot;device_id&amp;quot;  =====&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; not available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in the respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || '''ONLY for''' '''android''' platform, DO NOT pass devid for '''ios''', '''browser''' and '''ott''' platforms. devid,  SHA-256 value of Device Id (ADID) -  OPTIONAL if passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;intid=&amp;lt;Integration ID&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;Android ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;&amp;amp;intid=xxxxxxxx&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7630</id>
		<title>DCR Germany Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7630"/>
		<updated>2026-04-07T08:39:20Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a S2S Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S (Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (AppID)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have its own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but '''latest within 3 hours of the start of that hourly viewing file interval'''. For example, files from '''2:00 AM to 3:00 AM''' must be delivered latest before '''5 AM'''.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving an exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicit request from AGF.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported formats are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delivered to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''. Only for the Asset Metadata Optimization use case, '''all''' is used additionally, see [[#Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day|Optimization for all Platforms]]&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653476400&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| end_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653479999&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
    &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
    &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Asset Metadata Delivery Optimization===&lt;br /&gt;
&lt;br /&gt;
====Optimization when the Asset Metadata File remains unchanged during the whole day per platform====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged during the whole day per platform, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File  Location per platform.&lt;br /&gt;
&lt;br /&gt;
The File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced in the manifest file for the following 23 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the Asset Metadata File for HOUR 00'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the Asset Metadata File for HOUR 00):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged for all platforms during the whole day, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File Location for all platforms.&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced hourly in the manifest file for all the 24 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the global Asset Metadata File'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the global Asset Metadata File):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Global Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC for all Platforms=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the global Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! AGF Metadata Convention Name - &amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Only for your Reference&lt;br /&gt;
&amp;lt;/pre&amp;gt;  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid  || assetid|| Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname  || program || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || title || episode name || custom -  no backslash allowed in string (because of 3rd party data processing)  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen   || length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || N/A|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand ||  subbrand (vcid) || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
 &lt;br /&gt;
|-&lt;br /&gt;
| nol_c0   || nol_c0 || number of episode part (Sendungsteilenummer)   || custom, if a content is not divided into several episode parts, set &amp;quot;0&amp;quot; as value.  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2   || nol_c2 || web only  || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || nol_c5   || page URL   || custom, The “Page URL” custom variable is reserved for sending the video’s server address.  ||  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || nol_c7  || Video ID. This variable is applicable in case the video asset is broken into multiple files each with their own asset ID. If a client has a single asset for a given episode/program, the value here should be identical to the assetid already provided in the viewership file. &lt;br /&gt;
  || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || nol_c9  || episode title   || custom - no backslash allowed in string (because of 3rd party data processing). if no further differentiation, then use &amp;quot;episodetitle&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10  || nol_c10  || publisher   || custom, used to differentiate different publishers   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c12  || nol_c12  || type of asset   || &amp;quot;Trailer&amp;quot; or &amp;quot;Content&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15  || nol_c15   || format ID   || If nol_c2 is always Yes, then it can stay blank &amp;quot;&amp;quot;   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c16  || nol_c16   || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads)   || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes&amp;quot;, etc   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c18  || nol_c18  || is a live stream    || &amp;quot;Y&amp;quot; for live stream otherwise &amp;quot;N&amp;quot;  || ✓  &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c8   || nol_c8 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c13   || nol_c13  || custom variable   || custom   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c14   || nol_c14 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c19   || nol_c19  || custom variable   || custom   || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;programname&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;episodetitle&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c02&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,3&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,publisherName&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''ONLY for''' '''android''' platform, DO NOT pass device_id for '''ios''', '''browser''' and '''ott''' platforms.  Mobile Ad ID ,  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; - OPTIONAL if passed in the Audit Ping|| i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638655&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android Platform : Example Metadata with &amp;quot;device_id&amp;quot;  =====&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; not available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in the respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || '''ONLY for''' '''android''' platform, DO NOT pass devid for '''ios''', '''browser''' and '''ott''' platforms. devid,  SHA-256 value of Device Id (ADID) -  OPTIONAL if passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;intid=&amp;lt;Integration ID&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;Android ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;&amp;amp;intid=xxxxxxxx&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7629</id>
		<title>DCR Germany Video Cloud API</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7629"/>
		<updated>2026-04-07T08:37:59Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Ad metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing Cloud API =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a Cloud API Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging Cloud API Endpoint until you get the green light from Nielsen to move to Production!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
 || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Integration==&lt;br /&gt;
We will cover the steps for constructing the Cloud API Calls.&lt;br /&gt;
&lt;br /&gt;
====URL Structure====&lt;br /&gt;
&lt;br /&gt;
The Cloud API Calls are HTTP GET Requests with the URL structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;[endpoint]/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The URL includes the following components:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;[endpoint]&amp;lt;/code&amp;gt;: location of data collection environment&lt;br /&gt;
*&amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt;: provided App ID. &amp;lt;br&amp;gt;'''Note:'''The &amp;quot;P&amp;quot; prefix must be removed from the App ID received before adding it to the URL, i.e. if you received PDF20695-XXXX-XXXX-XXXX-3E334133D917 from Nielsen , your url will then be : &amp;lt;code&amp;gt;[endpoint]/DF20695-XXXX-XXXX-XXXX-3E334133D917/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;: unique value for each user session&lt;br /&gt;
*&amp;lt;code&amp;gt;[payload]&amp;lt;/code&amp;gt;: metadata and events&lt;br /&gt;
&lt;br /&gt;
====Endpoint====&lt;br /&gt;
&lt;br /&gt;
There are endpoints for testing and production:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide.&lt;br /&gt;
&lt;br /&gt;
====URL Example====&lt;br /&gt;
As you move through the integration steps, you can reference the below URL structure with the expanded payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content_metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event],&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playhead_position],&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type],&lt;br /&gt;
  &amp;quot;utc&amp;quot;: [Unix time in ms],&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: [unique view session ID for each video play]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create Session ID and send EMM Ping===&lt;br /&gt;
&lt;br /&gt;
====Create Session ID====&lt;br /&gt;
&lt;br /&gt;
A unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app.&lt;br /&gt;
&lt;br /&gt;
A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference and use.&lt;br /&gt;
&lt;br /&gt;
Session ID example: '''LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
'''// Create random GUID'''&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon exiting the app, the session will need to be terminated using the delete event. &amp;lt;br&amp;gt;&lt;br /&gt;
Sessions will automatically expire after 30 minutes of cloud inactivity.&lt;br /&gt;
&lt;br /&gt;
==== Send EMM Ping ====&lt;br /&gt;
An EMM Ping must be sent using the created unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; upon start of the first stream playback.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://[sessionID].uaid.nmrodam.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also see  [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference.&lt;br /&gt;
&lt;br /&gt;
===Create View Session ID for each Video Start===&lt;br /&gt;
An View Session ID &amp;lt;code&amp;gt;[sessid]&amp;lt;/code&amp;gt; must be created upon start of each stream playback, sessid is unique per video play.&lt;br /&gt;
&lt;br /&gt;
===Define URL Structure===&lt;br /&gt;
Define the URL structure using your provided &amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt; and a unique &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure Payload===&lt;br /&gt;
&lt;br /&gt;
====Description Payload====&lt;br /&gt;
&lt;br /&gt;
All Cloud API requests must contain the following payload data:&lt;br /&gt;
&lt;br /&gt;
*''devInfo'': device and app info&lt;br /&gt;
*''metadata'': asset metadata&lt;br /&gt;
*''event metadata'': type of event&lt;br /&gt;
&lt;br /&gt;
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section.&lt;br /&gt;
&lt;br /&gt;
==== Payload Example ====&lt;br /&gt;
&lt;br /&gt;
The example below should be referenced when following the steps for configuring the request payload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// 1. Create Session ID using the UUID Generator code provided&lt;br /&gt;
sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088  // Example sessionID &lt;br /&gt;
&lt;br /&gt;
// 2. Define URL Structure with App ID and Session ID&lt;br /&gt;
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
&lt;br /&gt;
// 3. Configure Payload&lt;br /&gt;
// 3.1 Configure Payload: devInfo &lt;br /&gt;
payload = {&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
   &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  // 3.2 Configure Payload: metadata&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: { // object for measuring video content&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  // 3.3 Configure Payload: events&lt;br /&gt;
  &amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, //event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, // position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, //&amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1456448742000&amp;quot;, //unix timestamp in milliseconds &lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot; // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Configure Payload: devInfo====&lt;br /&gt;
An object &amp;lt;code&amp;gt;&amp;quot;devInfo&amp;quot;&amp;lt;/code&amp;gt; will need to be created to capture App and Device information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| devId || unique ID to identify user (e.g. Advertising ID, Roku Device ID) - Not required for AGF || custom || &lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Example devInfo Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create devInfo object&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3.2 Configure Payload: metadata ====&lt;br /&gt;
Asset metadata can be passed through &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt;. There are two asset types: &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; for video and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; for ads. The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
You will need to set up &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt; objects for &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
===== Content Metadata =====&lt;br /&gt;
&lt;br /&gt;
====== Description of Content metadata ======&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Example Content metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang='json'&amp;gt;// create content object&lt;br /&gt;
&amp;quot;content&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ad Metadata (optional for public broadcasters) =====&lt;br /&gt;
====== Description of Ad metadata ======&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the Ad asset corresponding to  the  AGF custom variable '''c11'''.&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Example Ad metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;      &lt;br /&gt;
}&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Payload: Events ====&lt;br /&gt;
&lt;br /&gt;
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below.&lt;br /&gt;
&lt;br /&gt;
===== Event Types =====&lt;br /&gt;
&lt;br /&gt;
The available events are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; || &lt;br /&gt;
&lt;br /&gt;
===== Handling Playhead =====&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; is critical for accurate duration crediting. You can reference the below guidance to determine the correct playhead position to pass depending on the playback scenario.&lt;br /&gt;
&lt;br /&gt;
'''General'''&lt;br /&gt;
* Playhead position in seconds, must be passed as a whole number every 10 seconds. &lt;br /&gt;
* The final playhead position should be sent before before sending &amp;quot;complete&amp;quot; event when content playback is complete. &lt;br /&gt;
&lt;br /&gt;
'''Live Stream'''&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position. Note that ad playheads must also use Unix Time for each single Ad in an Ad Pod.&lt;br /&gt;
&lt;br /&gt;
'''VoD Stream'''&lt;br /&gt;
* For VoD stream use the player position for Content and Ad at playback start of a content or single Ad in an Ad Pod, playheads will then be 0, 10, 20, ....&lt;br /&gt;
&lt;br /&gt;
'''End of an Asset'''&lt;br /&gt;
* Final postion must be sent at the end of Content or Ad playback&lt;br /&gt;
&lt;br /&gt;
'''Ads'''&lt;br /&gt;
* The final playhead position must be sent when switching from content to ad, or ad to content.&lt;br /&gt;
* For Ad Pods, playhead must be called for each individual ad.&lt;br /&gt;
* When content has resumed following a mid-roll ad break, the next playhead position must continue where the previous content segment left off.&lt;br /&gt;
&lt;br /&gt;
'''User Actions'''&lt;br /&gt;
* SCRUBBING: Upon user scrubbing, the current position must be sent before a user scrubs, and the new position should be sent where the user lands, and begin sending in the 10 second updates thereafter.&lt;br /&gt;
* PAUSE: When content is paused, send current playhead position and stop passing playhead position until content is resumed.&lt;br /&gt;
* EXIT Stream: If a user exits a stream early, the last current position must be sent in a playhead update to receive accurate duration.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt; || The complete event must be sent : &lt;br /&gt;
* when the current video asset playback is terminated or completed, &lt;br /&gt;
* at the end of the current stream playback when the user switches to another piece of content or when the App is closed.&lt;br /&gt;
Before calling the complete event, a final playhead update with the final position is required to be sent to receive full duration credit. For Live streams, a complete event must be sent at program boundaries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || The delete event is optional and can be sent when the viewing session is terminated (typically on App close). A new session ID must be generated after sending a delete event. Delete should not be sent on app interruptions or foreground/background events. All creditable duration will be summarized for all asset types when delete occurs (content and ads).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Event Parameters =====&lt;br /&gt;
&lt;br /&gt;
The following parameters need to be passed when calling events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description !! Value !! Required&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;event&amp;quot;&amp;lt;/code&amp;gt; || event type || &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;position&amp;quot;&amp;lt;/code&amp;gt; || playhead position in seconds or Unix time in seconds || &amp;lt;code&amp;gt;&amp;quot;300&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;&amp;lt;/code&amp;gt; || asset type || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;utc&amp;quot;&amp;lt;/code&amp;gt; || Unix timestamp in milliseconds. Must be passed every 10 seconds. || &amp;lt;code&amp;gt;&amp;quot;1472760000000&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;sessid&amp;quot;&amp;lt;/code&amp;gt; || Unique View Session ID must be created upon start of each stream playback, sessid is unique per video play. || &amp;lt;code&amp;gt;&amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Event =====&lt;br /&gt;
You can call events by passing values in the required parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  // Event Parameters&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event], // event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playheadPosition], //position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type], // values are &amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;, //unix timestamp in milliseconds&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The full payload including &amp;quot;devInfo&amp;quot; and &amp;quot;metadata&amp;quot; must be populated in each event request.&lt;br /&gt;
&lt;br /&gt;
===== Sample Event Lifecycle for VoD Stream =====&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events and values to pass.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// Preroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Content&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content resumes at 15 minutes&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;900&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 30 minutes&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;1800&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Postroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Sample Event Lifecycle for VoD Stream - Detailed Storyline'''&lt;br /&gt;
This detailed event sequence provides additional insight for the correct events to call when handling certain playback scenarios.&lt;br /&gt;
&amp;lt;syntaxhighlight lang='javascript'&amp;gt;// SESSION STARTS&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// PREROLL&lt;br /&gt;
// Preroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Preroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;15&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
// CONTENT &lt;br /&gt;
// Content Start - Start new content streams with a position of &amp;quot;0&amp;quot; incrementing the position every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content Stop Before Ad Break - Send a playhead update including the current content positon before an Ad break.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;299&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787400000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
// Midroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;60&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472793500000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
// Content resumes at 5 minutes - Send playhead update with the current resumed position, and begin incrimenting the positon every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472799500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 10:12 - Make sure to send in the playhead event with the final content position before sending the complete event.&lt;br /&gt;
Final Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830700000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830800000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// POSTROLL&lt;br /&gt;
// Postroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830900000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Postroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;45&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835300000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// SESSION ENDS&lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835400000&amp;quot;} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Interruption Scenarios =====&lt;br /&gt;
&lt;br /&gt;
As part of configuring events, you will need to handle all possible interruption scenarios such as:&lt;br /&gt;
&lt;br /&gt;
*Wi-Fi OFF / ON&lt;br /&gt;
*App Crash or Exit&lt;br /&gt;
&lt;br /&gt;
When playback is interrupted, the app needs to send delete immediately.&lt;br /&gt;
&lt;br /&gt;
Once playback resumes, a new session will need to be created with a unique session ID. All of the required metadata and events will need to be sent.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The session will automatically timeout after 30 minutes of inactivity.&lt;br /&gt;
&lt;br /&gt;
=== Example Request ===&lt;br /&gt;
&lt;br /&gt;
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration.&lt;br /&gt;
&lt;br /&gt;
see '''[[#Payload Example|Payload Example]]'''&lt;br /&gt;
&lt;br /&gt;
// Append payload to URL&lt;br /&gt;
function sendPayloadToNielsen() {&lt;br /&gt;
  var payloadStr  = JSON.stringify(payload); // payload as string&lt;br /&gt;
  var imgPing = new Image();&lt;br /&gt;
  imgPing.onload = function() {&lt;br /&gt;
    // onload event, payload succesfull sent&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.onerror = function() {&lt;br /&gt;
    // handle error i.e. wait and send again&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.src = sessionURL+encodeURIComponent(payloadStr);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable Debug Logging ===&lt;br /&gt;
&lt;br /&gt;
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification.&lt;br /&gt;
&lt;br /&gt;
==== GET Request ====&lt;br /&gt;
&lt;br /&gt;
Display GET Request to console using a name to identify each event (e.g. playhead).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event&amp;quot;, image); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Output payload to identify required metadata and events.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event Payload&amp;quot;, payload); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response Code ====&lt;br /&gt;
&lt;br /&gt;
Confirm request was completed by viewing HTTP response code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
code = msg.GetResponseCode();&lt;br /&gt;
console.log(&amp;quot;Response Code&amp;quot;, code);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can reference the HTTP Response Code table when reviewing your requests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Status Code !! Status Text !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;200&amp;lt;/code&amp;gt; || OK || request received&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;403&amp;lt;/code&amp;gt; || Forbidden || invalid App ID&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;404&amp;lt;/code&amp;gt; || Not Found || JSON issue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll and postroll Ads.&lt;br /&gt;
&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; in the &amp;lt;code&amp;gt;Playback Settings&amp;lt;/code&amp;gt; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for AGF by selection Germany in the country dropbox [https://nielsenonlinesupport.com/agf/RefImplCloudAPI/index.htm?debug=true RefImplCloudAPI].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen CloudAPI Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen Cloud API measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Cloud API measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
&lt;br /&gt;
A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Before providing an app build to Nielsen for testing, it is important to run validation checks once you have enabled debug logging.&lt;br /&gt;
&lt;br /&gt;
=== Payload Validation ===&lt;br /&gt;
&lt;br /&gt;
Ensure that all of the required payload data is populating while testing several videos. The following areas are critical to measurement:&lt;br /&gt;
*devInfo&lt;br /&gt;
*Asset metadata for both content, and ads&lt;br /&gt;
*Events&lt;br /&gt;
&lt;br /&gt;
=== Player Events ===&lt;br /&gt;
Review event calls:&lt;br /&gt;
&lt;br /&gt;
==== playhead ====&lt;br /&gt;
*Playhead position updates every 10 seconds starting at position '0' for each new asset for VoD stream and UTC Unix Time in seconds for Live stream.&lt;br /&gt;
*Final playhead position is sent on content, or ad before switching between assets.&lt;br /&gt;
*Content metadata remains constant throughout an episode, or clip play.&lt;br /&gt;
*Ad metadata is populated appropriately for each individual ad.&lt;br /&gt;
*Playhead position update resumes for content after an ad break, and resets to 0 for each individual ad.&lt;br /&gt;
*For scrubbing, last current position should be sent while scrubbing occurs, and the new position should also be sent where the user scrubs to.&lt;br /&gt;
*Exiting a stream early should execute the last current position in a playhead update to receive accurate duration.&lt;br /&gt;
*Upon pause, the current position should be sent, and playhead updates should stop incrementing until resume play occurs.&lt;br /&gt;
&lt;br /&gt;
==== complete ====&lt;br /&gt;
*Check that the complete event executes upon content complete after the final playhead update is sent&lt;br /&gt;
*Do not execute the complete event for ads&lt;br /&gt;
&lt;br /&gt;
==== delete ====&lt;br /&gt;
*Check to see that the delete event occurs upon app exit, if the platform has the necessary exit callback events.&lt;br /&gt;
&lt;br /&gt;
==== GET Request Format ====&lt;br /&gt;
*Ensure that the event payloads are formatted in JSON&lt;br /&gt;
*Check to see that each of the Cloud API GET requests are properly encoded&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response ====&lt;br /&gt;
*Make sure that each of the Cloud API Get requests are received by the Nielsen Cloud API properly through use of the HTTP Response Code outputs enabled in console.&lt;br /&gt;
&lt;br /&gt;
== Go Live ==&lt;br /&gt;
After your integration has been certified, you will need to: Change Endpoint and Disable Logging.&lt;br /&gt;
&lt;br /&gt;
'''Change Endpoint:''' You will need to update to the production endpoint:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Production: &amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your production URL structure should now be:&lt;br /&gt;
&amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Disable Logging:''' You can now disable debug logging&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7628</id>
		<title>DCR Germany Video Cloud API</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7628"/>
		<updated>2026-04-07T08:37:21Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing Cloud API =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a Cloud API Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging Cloud API Endpoint until you get the green light from Nielsen to move to Production!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
 || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Integration==&lt;br /&gt;
We will cover the steps for constructing the Cloud API Calls.&lt;br /&gt;
&lt;br /&gt;
====URL Structure====&lt;br /&gt;
&lt;br /&gt;
The Cloud API Calls are HTTP GET Requests with the URL structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;[endpoint]/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The URL includes the following components:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;[endpoint]&amp;lt;/code&amp;gt;: location of data collection environment&lt;br /&gt;
*&amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt;: provided App ID. &amp;lt;br&amp;gt;'''Note:'''The &amp;quot;P&amp;quot; prefix must be removed from the App ID received before adding it to the URL, i.e. if you received PDF20695-XXXX-XXXX-XXXX-3E334133D917 from Nielsen , your url will then be : &amp;lt;code&amp;gt;[endpoint]/DF20695-XXXX-XXXX-XXXX-3E334133D917/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;: unique value for each user session&lt;br /&gt;
*&amp;lt;code&amp;gt;[payload]&amp;lt;/code&amp;gt;: metadata and events&lt;br /&gt;
&lt;br /&gt;
====Endpoint====&lt;br /&gt;
&lt;br /&gt;
There are endpoints for testing and production:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide.&lt;br /&gt;
&lt;br /&gt;
====URL Example====&lt;br /&gt;
As you move through the integration steps, you can reference the below URL structure with the expanded payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content_metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event],&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playhead_position],&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type],&lt;br /&gt;
  &amp;quot;utc&amp;quot;: [Unix time in ms],&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: [unique view session ID for each video play]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create Session ID and send EMM Ping===&lt;br /&gt;
&lt;br /&gt;
====Create Session ID====&lt;br /&gt;
&lt;br /&gt;
A unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app.&lt;br /&gt;
&lt;br /&gt;
A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference and use.&lt;br /&gt;
&lt;br /&gt;
Session ID example: '''LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
'''// Create random GUID'''&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon exiting the app, the session will need to be terminated using the delete event. &amp;lt;br&amp;gt;&lt;br /&gt;
Sessions will automatically expire after 30 minutes of cloud inactivity.&lt;br /&gt;
&lt;br /&gt;
==== Send EMM Ping ====&lt;br /&gt;
An EMM Ping must be sent using the created unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; upon start of the first stream playback.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://[sessionID].uaid.nmrodam.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also see  [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference.&lt;br /&gt;
&lt;br /&gt;
===Create View Session ID for each Video Start===&lt;br /&gt;
An View Session ID &amp;lt;code&amp;gt;[sessid]&amp;lt;/code&amp;gt; must be created upon start of each stream playback, sessid is unique per video play.&lt;br /&gt;
&lt;br /&gt;
===Define URL Structure===&lt;br /&gt;
Define the URL structure using your provided &amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt; and a unique &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure Payload===&lt;br /&gt;
&lt;br /&gt;
====Description Payload====&lt;br /&gt;
&lt;br /&gt;
All Cloud API requests must contain the following payload data:&lt;br /&gt;
&lt;br /&gt;
*''devInfo'': device and app info&lt;br /&gt;
*''metadata'': asset metadata&lt;br /&gt;
*''event metadata'': type of event&lt;br /&gt;
&lt;br /&gt;
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section.&lt;br /&gt;
&lt;br /&gt;
==== Payload Example ====&lt;br /&gt;
&lt;br /&gt;
The example below should be referenced when following the steps for configuring the request payload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// 1. Create Session ID using the UUID Generator code provided&lt;br /&gt;
sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088  // Example sessionID &lt;br /&gt;
&lt;br /&gt;
// 2. Define URL Structure with App ID and Session ID&lt;br /&gt;
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
&lt;br /&gt;
// 3. Configure Payload&lt;br /&gt;
// 3.1 Configure Payload: devInfo &lt;br /&gt;
payload = {&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
   &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  // 3.2 Configure Payload: metadata&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: { // object for measuring video content&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  // 3.3 Configure Payload: events&lt;br /&gt;
  &amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, //event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, // position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, //&amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1456448742000&amp;quot;, //unix timestamp in milliseconds &lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot; // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Configure Payload: devInfo====&lt;br /&gt;
An object &amp;lt;code&amp;gt;&amp;quot;devInfo&amp;quot;&amp;lt;/code&amp;gt; will need to be created to capture App and Device information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| devId || unique ID to identify user (e.g. Advertising ID, Roku Device ID) - Not required for AGF || custom || &lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Example devInfo Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create devInfo object&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3.2 Configure Payload: metadata ====&lt;br /&gt;
Asset metadata can be passed through &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt;. There are two asset types: &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; for video and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; for ads. The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
You will need to set up &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt; objects for &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
===== Content Metadata =====&lt;br /&gt;
&lt;br /&gt;
====== Description of Content metadata ======&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Example Content metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang='json'&amp;gt;// create content object&lt;br /&gt;
&amp;quot;content&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ad Metadata (optional for public broadcasters) =====&lt;br /&gt;
====== Description of Ad metadata ======&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Example Ad metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;      &lt;br /&gt;
}&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Payload: Events ====&lt;br /&gt;
&lt;br /&gt;
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below.&lt;br /&gt;
&lt;br /&gt;
===== Event Types =====&lt;br /&gt;
&lt;br /&gt;
The available events are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; || &lt;br /&gt;
&lt;br /&gt;
===== Handling Playhead =====&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; is critical for accurate duration crediting. You can reference the below guidance to determine the correct playhead position to pass depending on the playback scenario.&lt;br /&gt;
&lt;br /&gt;
'''General'''&lt;br /&gt;
* Playhead position in seconds, must be passed as a whole number every 10 seconds. &lt;br /&gt;
* The final playhead position should be sent before before sending &amp;quot;complete&amp;quot; event when content playback is complete. &lt;br /&gt;
&lt;br /&gt;
'''Live Stream'''&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position. Note that ad playheads must also use Unix Time for each single Ad in an Ad Pod.&lt;br /&gt;
&lt;br /&gt;
'''VoD Stream'''&lt;br /&gt;
* For VoD stream use the player position for Content and Ad at playback start of a content or single Ad in an Ad Pod, playheads will then be 0, 10, 20, ....&lt;br /&gt;
&lt;br /&gt;
'''End of an Asset'''&lt;br /&gt;
* Final postion must be sent at the end of Content or Ad playback&lt;br /&gt;
&lt;br /&gt;
'''Ads'''&lt;br /&gt;
* The final playhead position must be sent when switching from content to ad, or ad to content.&lt;br /&gt;
* For Ad Pods, playhead must be called for each individual ad.&lt;br /&gt;
* When content has resumed following a mid-roll ad break, the next playhead position must continue where the previous content segment left off.&lt;br /&gt;
&lt;br /&gt;
'''User Actions'''&lt;br /&gt;
* SCRUBBING: Upon user scrubbing, the current position must be sent before a user scrubs, and the new position should be sent where the user lands, and begin sending in the 10 second updates thereafter.&lt;br /&gt;
* PAUSE: When content is paused, send current playhead position and stop passing playhead position until content is resumed.&lt;br /&gt;
* EXIT Stream: If a user exits a stream early, the last current position must be sent in a playhead update to receive accurate duration.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt; || The complete event must be sent : &lt;br /&gt;
* when the current video asset playback is terminated or completed, &lt;br /&gt;
* at the end of the current stream playback when the user switches to another piece of content or when the App is closed.&lt;br /&gt;
Before calling the complete event, a final playhead update with the final position is required to be sent to receive full duration credit. For Live streams, a complete event must be sent at program boundaries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || The delete event is optional and can be sent when the viewing session is terminated (typically on App close). A new session ID must be generated after sending a delete event. Delete should not be sent on app interruptions or foreground/background events. All creditable duration will be summarized for all asset types when delete occurs (content and ads).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Event Parameters =====&lt;br /&gt;
&lt;br /&gt;
The following parameters need to be passed when calling events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description !! Value !! Required&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;event&amp;quot;&amp;lt;/code&amp;gt; || event type || &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;position&amp;quot;&amp;lt;/code&amp;gt; || playhead position in seconds or Unix time in seconds || &amp;lt;code&amp;gt;&amp;quot;300&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;&amp;lt;/code&amp;gt; || asset type || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;utc&amp;quot;&amp;lt;/code&amp;gt; || Unix timestamp in milliseconds. Must be passed every 10 seconds. || &amp;lt;code&amp;gt;&amp;quot;1472760000000&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;sessid&amp;quot;&amp;lt;/code&amp;gt; || Unique View Session ID must be created upon start of each stream playback, sessid is unique per video play. || &amp;lt;code&amp;gt;&amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Event =====&lt;br /&gt;
You can call events by passing values in the required parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  // Event Parameters&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event], // event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playheadPosition], //position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type], // values are &amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;, //unix timestamp in milliseconds&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The full payload including &amp;quot;devInfo&amp;quot; and &amp;quot;metadata&amp;quot; must be populated in each event request.&lt;br /&gt;
&lt;br /&gt;
===== Sample Event Lifecycle for VoD Stream =====&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events and values to pass.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// Preroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Content&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content resumes at 15 minutes&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;900&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 30 minutes&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;1800&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Postroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Sample Event Lifecycle for VoD Stream - Detailed Storyline'''&lt;br /&gt;
This detailed event sequence provides additional insight for the correct events to call when handling certain playback scenarios.&lt;br /&gt;
&amp;lt;syntaxhighlight lang='javascript'&amp;gt;// SESSION STARTS&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// PREROLL&lt;br /&gt;
// Preroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Preroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;15&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
// CONTENT &lt;br /&gt;
// Content Start - Start new content streams with a position of &amp;quot;0&amp;quot; incrementing the position every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content Stop Before Ad Break - Send a playhead update including the current content positon before an Ad break.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;299&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787400000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
// Midroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;60&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472793500000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
// Content resumes at 5 minutes - Send playhead update with the current resumed position, and begin incrimenting the positon every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472799500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 10:12 - Make sure to send in the playhead event with the final content position before sending the complete event.&lt;br /&gt;
Final Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830700000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830800000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// POSTROLL&lt;br /&gt;
// Postroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830900000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Postroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;45&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835300000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// SESSION ENDS&lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835400000&amp;quot;} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Interruption Scenarios =====&lt;br /&gt;
&lt;br /&gt;
As part of configuring events, you will need to handle all possible interruption scenarios such as:&lt;br /&gt;
&lt;br /&gt;
*Wi-Fi OFF / ON&lt;br /&gt;
*App Crash or Exit&lt;br /&gt;
&lt;br /&gt;
When playback is interrupted, the app needs to send delete immediately.&lt;br /&gt;
&lt;br /&gt;
Once playback resumes, a new session will need to be created with a unique session ID. All of the required metadata and events will need to be sent.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The session will automatically timeout after 30 minutes of inactivity.&lt;br /&gt;
&lt;br /&gt;
=== Example Request ===&lt;br /&gt;
&lt;br /&gt;
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration.&lt;br /&gt;
&lt;br /&gt;
see '''[[#Payload Example|Payload Example]]'''&lt;br /&gt;
&lt;br /&gt;
// Append payload to URL&lt;br /&gt;
function sendPayloadToNielsen() {&lt;br /&gt;
  var payloadStr  = JSON.stringify(payload); // payload as string&lt;br /&gt;
  var imgPing = new Image();&lt;br /&gt;
  imgPing.onload = function() {&lt;br /&gt;
    // onload event, payload succesfull sent&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.onerror = function() {&lt;br /&gt;
    // handle error i.e. wait and send again&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.src = sessionURL+encodeURIComponent(payloadStr);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable Debug Logging ===&lt;br /&gt;
&lt;br /&gt;
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification.&lt;br /&gt;
&lt;br /&gt;
==== GET Request ====&lt;br /&gt;
&lt;br /&gt;
Display GET Request to console using a name to identify each event (e.g. playhead).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event&amp;quot;, image); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Output payload to identify required metadata and events.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event Payload&amp;quot;, payload); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response Code ====&lt;br /&gt;
&lt;br /&gt;
Confirm request was completed by viewing HTTP response code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
code = msg.GetResponseCode();&lt;br /&gt;
console.log(&amp;quot;Response Code&amp;quot;, code);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can reference the HTTP Response Code table when reviewing your requests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Status Code !! Status Text !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;200&amp;lt;/code&amp;gt; || OK || request received&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;403&amp;lt;/code&amp;gt; || Forbidden || invalid App ID&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;404&amp;lt;/code&amp;gt; || Not Found || JSON issue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll and postroll Ads.&lt;br /&gt;
&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; in the &amp;lt;code&amp;gt;Playback Settings&amp;lt;/code&amp;gt; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for AGF by selection Germany in the country dropbox [https://nielsenonlinesupport.com/agf/RefImplCloudAPI/index.htm?debug=true RefImplCloudAPI].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen CloudAPI Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen Cloud API measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Cloud API measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
&lt;br /&gt;
A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Before providing an app build to Nielsen for testing, it is important to run validation checks once you have enabled debug logging.&lt;br /&gt;
&lt;br /&gt;
=== Payload Validation ===&lt;br /&gt;
&lt;br /&gt;
Ensure that all of the required payload data is populating while testing several videos. The following areas are critical to measurement:&lt;br /&gt;
*devInfo&lt;br /&gt;
*Asset metadata for both content, and ads&lt;br /&gt;
*Events&lt;br /&gt;
&lt;br /&gt;
=== Player Events ===&lt;br /&gt;
Review event calls:&lt;br /&gt;
&lt;br /&gt;
==== playhead ====&lt;br /&gt;
*Playhead position updates every 10 seconds starting at position '0' for each new asset for VoD stream and UTC Unix Time in seconds for Live stream.&lt;br /&gt;
*Final playhead position is sent on content, or ad before switching between assets.&lt;br /&gt;
*Content metadata remains constant throughout an episode, or clip play.&lt;br /&gt;
*Ad metadata is populated appropriately for each individual ad.&lt;br /&gt;
*Playhead position update resumes for content after an ad break, and resets to 0 for each individual ad.&lt;br /&gt;
*For scrubbing, last current position should be sent while scrubbing occurs, and the new position should also be sent where the user scrubs to.&lt;br /&gt;
*Exiting a stream early should execute the last current position in a playhead update to receive accurate duration.&lt;br /&gt;
*Upon pause, the current position should be sent, and playhead updates should stop incrementing until resume play occurs.&lt;br /&gt;
&lt;br /&gt;
==== complete ====&lt;br /&gt;
*Check that the complete event executes upon content complete after the final playhead update is sent&lt;br /&gt;
*Do not execute the complete event for ads&lt;br /&gt;
&lt;br /&gt;
==== delete ====&lt;br /&gt;
*Check to see that the delete event occurs upon app exit, if the platform has the necessary exit callback events.&lt;br /&gt;
&lt;br /&gt;
==== GET Request Format ====&lt;br /&gt;
*Ensure that the event payloads are formatted in JSON&lt;br /&gt;
*Check to see that each of the Cloud API GET requests are properly encoded&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response ====&lt;br /&gt;
*Make sure that each of the Cloud API Get requests are received by the Nielsen Cloud API properly through use of the HTTP Response Code outputs enabled in console.&lt;br /&gt;
&lt;br /&gt;
== Go Live ==&lt;br /&gt;
After your integration has been certified, you will need to: Change Endpoint and Disable Logging.&lt;br /&gt;
&lt;br /&gt;
'''Change Endpoint:''' You will need to update to the production endpoint:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Production: &amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your production URL structure should now be:&lt;br /&gt;
&amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Disable Logging:''' You can now disable debug logging&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7627</id>
		<title>DCR Germany Video App SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7627"/>
		<updated>2026-04-07T08:30:05Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Ad metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR), [[Digital Audio]]. Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long the app was running&lt;br /&gt;
*Time of viewing a sub-section/page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following details are required:&lt;br /&gt;
* '''App ID (appid):''' Unique ID assigned to the player/site and configured by product.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''No ID AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;ONLY the No ID AppSDK should be downloaded for the AGF market!&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Nielsen SDK:''' The Nielsen SDK package contains a variety of sample players for your reference.&lt;br /&gt;
Please contact our SDK sales support team if you do not have any of these prerequisites or have any questions.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode and Android using Android Studio.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
&lt;br /&gt;
=== iOS  ===&lt;br /&gt;
&lt;br /&gt;
==== Special Notes regarding iOS17 or TVOS17  ====&lt;br /&gt;
Beginning with iOS/TVOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs.&lt;br /&gt;
&lt;br /&gt;
Since AGF market is not making use of the IDFA, the change is expected to have no impact.&lt;br /&gt;
&lt;br /&gt;
However, in order to minimize any eventual impact, we are asking that AGF clients do the following:&lt;br /&gt;
&lt;br /&gt;
* '''Do not declare the Nielsen nmrodam.com domain in the privacy manifest'''&lt;br /&gt;
* Update to the latest Nielsen SDK release &amp;gt;= 9.2.0.0 when compiling your app for iOS 17&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For any additional information please refer to the Nielsen global page: [[DCR and DTVR with iOS17 or TVOS17]].&lt;br /&gt;
&lt;br /&gt;
==== General  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Xcode Development Environment''' &lt;br /&gt;
&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK is compatible with Apple iOS versions 9.0 and above.&lt;br /&gt;
&lt;br /&gt;
The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Importing Frameworks'''&amp;lt;/big&amp;gt;&lt;br /&gt;
The first step is to ensure that the following frameworks and libraries are imported into the Frameworks folder of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework uses several functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework &lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Example'''&lt;br /&gt;
* Extract “NielsenAppApi.Framework” from the Nielsen App SDK sample app and copy it to the Frameworks folder of the Xcode project.&lt;br /&gt;
* Add the code &amp;lt;code&amp;gt;-#import NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller’s header file.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Ensure that the following are included in the Linked Frameworks and Libraries list (located in the project’s Summary settings).&lt;br /&gt;
* Nielsen App SDK&lt;br /&gt;
* iOS security framework&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Swift'''&amp;lt;/big&amp;gt;&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Objective-C'''&amp;lt;/big&amp;gt;&lt;br /&gt;
Add the code &lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Android  ===&lt;br /&gt;
==== General  ====&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Android Java Development Environment'''&lt;br /&gt;
&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The Nielsen App SDK (located in the ''com.nielsen.app.sdk'' package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
&lt;br /&gt;
'''Nielsen App SDK is compatible with Android OS versions 2.3+. Clients can control/configure the protocol to be used – HTTPS or HTTP to suit their needs.'''&lt;br /&gt;
&lt;br /&gt;
The Nielsen App SDK 1.2 library is composed of two parts:&lt;br /&gt;
* The Java AppSdk.jar library runs on the Android’s Dalvik Virtual Machine.&lt;br /&gt;
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.&lt;br /&gt;
* '''For Video player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 3.0 and later will support it natively).&lt;br /&gt;
** If the player application uses a 3rd party media player implementing its own HLS, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
* '''For Audio player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should be at version 2.3 and later since the SDK depends on Google Play support to work properly.&lt;br /&gt;
Unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.&lt;br /&gt;
Add the following permissions on the project’s ''AndroidManifest.xml'' file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For more details on handling runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.&lt;br /&gt;
* App SDK checks to see if a Google service is available and updated.&lt;br /&gt;
* If unavailable or updated, App SDK will not use this service when executing its functions and will reference missing imports and the app will not be compiled.&lt;br /&gt;
To include the Google Play library in the media player project, copy the ''google-play-services_lib'' folder into the same location as the project&lt;br /&gt;
* Access '''File &amp;gt; Import'''.&lt;br /&gt;
* Select '''Existing Android Code into Workspace''' and click '''Next'''.&lt;br /&gt;
* Click '''Browse''' and navigate to the ''google-play-services_lib'' to include it into the projects.&lt;br /&gt;
* Select the exact '''Project Build Target''' for Eclipse to use from Android SDK.&lt;br /&gt;
** Android 4.4.2, etc. OR&lt;br /&gt;
** Edit ''project.properties'' file to point to Android target version e.g. target= android-19.&lt;br /&gt;
Once the google-play-services_lib is included into the App project, include the following code under the &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; node in the &amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data android:name=&amp;quot;com.google.android.gms.version&amp;quot; android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, include the ''version.xml'' file that comes with the ''google-play-services_lib'' under the res/values directory of the media player project.&lt;br /&gt;
* Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Library'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Classes/package&amp;lt;/big&amp;gt;'''&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
==== Add the dependency &amp;quot;lifecycle-extensions&amp;quot; to your project  ====&lt;br /&gt;
Add the dependency &amp;quot;lifecycle-extensions&amp;quot; in the in the app gradle file as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will enable the AppSdk to detect the application UI visibility state transitions between background and foreground by utilizing the LifeCycleObserver. This is i.e. required for the Static Measurement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated before version 5.1.1. (Version 4.0 for Android)&lt;br /&gt;
&lt;br /&gt;
* A maximum of four SDK instances per appid are supported. When a fifth SDK instance is launched, the SDK will return “nil” from [[initWithAppInfo:delegate:]]&lt;br /&gt;
* When four SDK instances exist, you must destroy an old instance before creating a new one.&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
&lt;br /&gt;
* The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || No || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || Client-defined || No || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
'''AGF Clients'''&lt;br /&gt;
* &amp;quot;eu&amp;quot; (For Testing/Certification and in Production)&lt;br /&gt;
|| Nielsen-specified || ✓ || &amp;quot;eu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Has to be set to &amp;quot;DEBUG&amp;quot; until certified&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
=====  iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
    &lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======  Objective-C ======&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====  Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&lt;br /&gt;
AppSDK is no longer a singleton object and should be initialized as below.&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;appname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sfcode&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on the type of client app.&amp;lt;br /&amp;gt;&lt;br /&gt;
* Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on the property page of the App’s project).&lt;br /&gt;
&lt;br /&gt;
== APP SDK Error &amp;amp; Event Codes ==&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
== Configure Payload ==&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handle only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of the unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** The error message will be logged if the string has an invalid JSON format.&lt;br /&gt;
* JSON value must be a string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
&lt;br /&gt;
=== Configure ChannelInfo metadata === &lt;br /&gt;
==== Description of ChannelInfo metadata ====&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ChannelInfo metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
       let channelInfo = [&lt;br /&gt;
            &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Configure Content metadata ===&lt;br /&gt;
&lt;br /&gt;
==== Description of Content metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example Content metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
	&amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
        &lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;, &lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;88675545&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;3600&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;88675545&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;3600&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c0&amp;quot;, &amp;quot;p0,1&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c2&amp;quot;, &amp;quot;p2,Y&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c7&amp;quot;, &amp;quot;p7,videoid123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c9&amp;quot;, &amp;quot;p9,VideoTitle123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c18&amp;quot;, &amp;quot;p18,N&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure Ad Metadata ===&lt;br /&gt;
==== Description of Ad metadata ====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the Ad asset corresponding to  the  AGF custom variable '''c11'''.&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
let adMetadata = [&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;preroll&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;ad345-67483&amp;quot;&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;ad_title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;25&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JSONObject adMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;preroll&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;ad345-67483&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;25&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c11&amp;quot;, &amp;quot;p11,2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Werbung&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c17&amp;quot;, &amp;quot;p17,preroll&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
=== Sample API Sequence ===&lt;br /&gt;
A Sample API sequence could follow this flow:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;[nielsenMeter play: channelName];&amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadataObject];&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;[nielsenMeter playheadPosition: position];&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;[nielsenMeter end];&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Life cycle of SDK instance ===&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance processes playing information. [[play]] and [[loadMetadata]] calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## [[playheadPosition]] – Call this API every one second when playhead position timer is fired.&lt;br /&gt;
## [[stop]] – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## [[end]] – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to pause the measurement.&lt;br /&gt;
* As soon as the playback resumes, call [[loadMetadata]] and  [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
'''[[#Example Content metadata|Example Content metadata]]'''&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the stream playback is interrupted or has ended.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: ONLY for a preroll Ad , Call [[loadMetadata()]] for Content before calling it for preroll ad &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
'''[[#Example Ad metadata|Example Ad metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the Ad playback is interrupted or has ended for each single Ad. Playhead should be passed for the entire duration of ad pod, if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after the content is paused (ad starts)&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the midroll ad is being played &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content (Content resume) || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Always call stop irrespective of postroll is followed or not&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequence of Calls ===&lt;br /&gt;
&lt;br /&gt;
=== play ===&lt;br /&gt;
Use [[play]] to pass the channel descriptor information through channelName parameter after the SDK has been initialized and the content starts playing. If the user is returning from a '''Pause/Stop''' interaction, call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   - (void)play:(id)channelInfo;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    public void play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenAppApi?.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void)loadMetadata:(id)contentMetadata;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;playheadPosition&amp;quot; has to be called every second.&lt;br /&gt;
&lt;br /&gt;
* VOD : &lt;br /&gt;
** For Content and each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
*Live : &lt;br /&gt;
**For Content, pass the Unix timestamp (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... . &lt;br /&gt;
**For each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
– (void) playheadPosition: (long long) playheadPos&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
AVPlayer *player;&lt;br /&gt;
CMTime curTime=[player currentTime];&lt;br /&gt;
int pos = CMTimeGetSeconds(curTime);&lt;br /&gt;
[nAppApiObject playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        //Monitor the Playhead position of the AVPlayer&lt;br /&gt;
        let timeInterval: CMTime = CMTimeMakeWithSeconds(1.0,10)&lt;br /&gt;
        self.avPlayerViewController.player?.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) {(elapsedTime: CMTime) -&amp;gt; Void in&lt;br /&gt;
            if self.avPlayerViewController.player!.currentItem?.status == .readyToPlay {&lt;br /&gt;
                let time : Float64 = self.avPlayerViewController.player!.currentTime().seconds;&lt;br /&gt;
                let pos = Int64(time);&lt;br /&gt;
                NSLog(&amp;quot;New Elapse Time = \(time)&amp;quot;);&lt;br /&gt;
                self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void setPlayheadPosition(long position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void) stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
Call when the content asset completes playback. Stops measurement progress. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;- (void) end;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending [[playheadPosition]] once the playback resumes (no [[loadMetadata]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional information:&lt;br /&gt;
* '''For type 'content': '''Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== App termination ===&lt;br /&gt;
If your app is executing a termination process and therefore ending the Content or Ad Playback, call [[end]] if the Content is playing or [[stop]] if an Ad is playing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
&lt;br /&gt;
The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain.&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
 &lt;br /&gt;
Please contact your Nielsen SDK support team directly for any related questions.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
#* '''Example Production Initialization Call''' - Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;iOS Example:&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Android Example:&amp;lt;/big&amp;gt;''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live, you have to inform the Nielsen team - this is necessary because the Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7626</id>
		<title>DCR Germany Video App SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7626"/>
		<updated>2026-04-07T08:29:08Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR), [[Digital Audio]]. Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long the app was running&lt;br /&gt;
*Time of viewing a sub-section/page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following details are required:&lt;br /&gt;
* '''App ID (appid):''' Unique ID assigned to the player/site and configured by product.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''No ID AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;ONLY the No ID AppSDK should be downloaded for the AGF market!&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Nielsen SDK:''' The Nielsen SDK package contains a variety of sample players for your reference.&lt;br /&gt;
Please contact our SDK sales support team if you do not have any of these prerequisites or have any questions.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode and Android using Android Studio.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
&lt;br /&gt;
=== iOS  ===&lt;br /&gt;
&lt;br /&gt;
==== Special Notes regarding iOS17 or TVOS17  ====&lt;br /&gt;
Beginning with iOS/TVOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs.&lt;br /&gt;
&lt;br /&gt;
Since AGF market is not making use of the IDFA, the change is expected to have no impact.&lt;br /&gt;
&lt;br /&gt;
However, in order to minimize any eventual impact, we are asking that AGF clients do the following:&lt;br /&gt;
&lt;br /&gt;
* '''Do not declare the Nielsen nmrodam.com domain in the privacy manifest'''&lt;br /&gt;
* Update to the latest Nielsen SDK release &amp;gt;= 9.2.0.0 when compiling your app for iOS 17&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For any additional information please refer to the Nielsen global page: [[DCR and DTVR with iOS17 or TVOS17]].&lt;br /&gt;
&lt;br /&gt;
==== General  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Xcode Development Environment''' &lt;br /&gt;
&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK is compatible with Apple iOS versions 9.0 and above.&lt;br /&gt;
&lt;br /&gt;
The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Importing Frameworks'''&amp;lt;/big&amp;gt;&lt;br /&gt;
The first step is to ensure that the following frameworks and libraries are imported into the Frameworks folder of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework uses several functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework &lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Example'''&lt;br /&gt;
* Extract “NielsenAppApi.Framework” from the Nielsen App SDK sample app and copy it to the Frameworks folder of the Xcode project.&lt;br /&gt;
* Add the code &amp;lt;code&amp;gt;-#import NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller’s header file.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Ensure that the following are included in the Linked Frameworks and Libraries list (located in the project’s Summary settings).&lt;br /&gt;
* Nielsen App SDK&lt;br /&gt;
* iOS security framework&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Swift'''&amp;lt;/big&amp;gt;&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Objective-C'''&amp;lt;/big&amp;gt;&lt;br /&gt;
Add the code &lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Android  ===&lt;br /&gt;
==== General  ====&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Android Java Development Environment'''&lt;br /&gt;
&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The Nielsen App SDK (located in the ''com.nielsen.app.sdk'' package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
&lt;br /&gt;
'''Nielsen App SDK is compatible with Android OS versions 2.3+. Clients can control/configure the protocol to be used – HTTPS or HTTP to suit their needs.'''&lt;br /&gt;
&lt;br /&gt;
The Nielsen App SDK 1.2 library is composed of two parts:&lt;br /&gt;
* The Java AppSdk.jar library runs on the Android’s Dalvik Virtual Machine.&lt;br /&gt;
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.&lt;br /&gt;
* '''For Video player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 3.0 and later will support it natively).&lt;br /&gt;
** If the player application uses a 3rd party media player implementing its own HLS, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
* '''For Audio player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should be at version 2.3 and later since the SDK depends on Google Play support to work properly.&lt;br /&gt;
Unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.&lt;br /&gt;
Add the following permissions on the project’s ''AndroidManifest.xml'' file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For more details on handling runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.&lt;br /&gt;
* App SDK checks to see if a Google service is available and updated.&lt;br /&gt;
* If unavailable or updated, App SDK will not use this service when executing its functions and will reference missing imports and the app will not be compiled.&lt;br /&gt;
To include the Google Play library in the media player project, copy the ''google-play-services_lib'' folder into the same location as the project&lt;br /&gt;
* Access '''File &amp;gt; Import'''.&lt;br /&gt;
* Select '''Existing Android Code into Workspace''' and click '''Next'''.&lt;br /&gt;
* Click '''Browse''' and navigate to the ''google-play-services_lib'' to include it into the projects.&lt;br /&gt;
* Select the exact '''Project Build Target''' for Eclipse to use from Android SDK.&lt;br /&gt;
** Android 4.4.2, etc. OR&lt;br /&gt;
** Edit ''project.properties'' file to point to Android target version e.g. target= android-19.&lt;br /&gt;
Once the google-play-services_lib is included into the App project, include the following code under the &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; node in the &amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data android:name=&amp;quot;com.google.android.gms.version&amp;quot; android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, include the ''version.xml'' file that comes with the ''google-play-services_lib'' under the res/values directory of the media player project.&lt;br /&gt;
* Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Library'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Classes/package&amp;lt;/big&amp;gt;'''&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
==== Add the dependency &amp;quot;lifecycle-extensions&amp;quot; to your project  ====&lt;br /&gt;
Add the dependency &amp;quot;lifecycle-extensions&amp;quot; in the in the app gradle file as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will enable the AppSdk to detect the application UI visibility state transitions between background and foreground by utilizing the LifeCycleObserver. This is i.e. required for the Static Measurement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated before version 5.1.1. (Version 4.0 for Android)&lt;br /&gt;
&lt;br /&gt;
* A maximum of four SDK instances per appid are supported. When a fifth SDK instance is launched, the SDK will return “nil” from [[initWithAppInfo:delegate:]]&lt;br /&gt;
* When four SDK instances exist, you must destroy an old instance before creating a new one.&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
&lt;br /&gt;
* The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || No || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || Client-defined || No || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
'''AGF Clients'''&lt;br /&gt;
* &amp;quot;eu&amp;quot; (For Testing/Certification and in Production)&lt;br /&gt;
|| Nielsen-specified || ✓ || &amp;quot;eu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Has to be set to &amp;quot;DEBUG&amp;quot; until certified&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
=====  iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
    &lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======  Objective-C ======&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====  Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&lt;br /&gt;
AppSDK is no longer a singleton object and should be initialized as below.&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;appname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sfcode&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on the type of client app.&amp;lt;br /&amp;gt;&lt;br /&gt;
* Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on the property page of the App’s project).&lt;br /&gt;
&lt;br /&gt;
== APP SDK Error &amp;amp; Event Codes ==&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
== Configure Payload ==&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handle only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of the unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** The error message will be logged if the string has an invalid JSON format.&lt;br /&gt;
* JSON value must be a string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
&lt;br /&gt;
=== Configure ChannelInfo metadata === &lt;br /&gt;
==== Description of ChannelInfo metadata ====&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ChannelInfo metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
       let channelInfo = [&lt;br /&gt;
            &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Configure Content metadata ===&lt;br /&gt;
&lt;br /&gt;
==== Description of Content metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example Content metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
	&amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
        &lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;, &lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;88675545&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;3600&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;88675545&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;3600&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c0&amp;quot;, &amp;quot;p0,1&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c2&amp;quot;, &amp;quot;p2,Y&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c7&amp;quot;, &amp;quot;p7,videoid123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c9&amp;quot;, &amp;quot;p9,VideoTitle123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c18&amp;quot;, &amp;quot;p18,N&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure Ad Metadata ===&lt;br /&gt;
==== Description of Ad metadata ====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
let adMetadata = [&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;preroll&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;ad345-67483&amp;quot;&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;ad_title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;25&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JSONObject adMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;preroll&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;ad345-67483&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;25&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c11&amp;quot;, &amp;quot;p11,2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Werbung&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c17&amp;quot;, &amp;quot;p17,preroll&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
=== Sample API Sequence ===&lt;br /&gt;
A Sample API sequence could follow this flow:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;[nielsenMeter play: channelName];&amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadataObject];&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;[nielsenMeter playheadPosition: position];&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;[nielsenMeter end];&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Life cycle of SDK instance ===&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance processes playing information. [[play]] and [[loadMetadata]] calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## [[playheadPosition]] – Call this API every one second when playhead position timer is fired.&lt;br /&gt;
## [[stop]] – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## [[end]] – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to pause the measurement.&lt;br /&gt;
* As soon as the playback resumes, call [[loadMetadata]] and  [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
'''[[#Example Content metadata|Example Content metadata]]'''&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the stream playback is interrupted or has ended.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: ONLY for a preroll Ad , Call [[loadMetadata()]] for Content before calling it for preroll ad &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
'''[[#Example Ad metadata|Example Ad metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the Ad playback is interrupted or has ended for each single Ad. Playhead should be passed for the entire duration of ad pod, if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after the content is paused (ad starts)&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the midroll ad is being played &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content (Content resume) || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Always call stop irrespective of postroll is followed or not&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequence of Calls ===&lt;br /&gt;
&lt;br /&gt;
=== play ===&lt;br /&gt;
Use [[play]] to pass the channel descriptor information through channelName parameter after the SDK has been initialized and the content starts playing. If the user is returning from a '''Pause/Stop''' interaction, call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   - (void)play:(id)channelInfo;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    public void play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenAppApi?.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void)loadMetadata:(id)contentMetadata;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;playheadPosition&amp;quot; has to be called every second.&lt;br /&gt;
&lt;br /&gt;
* VOD : &lt;br /&gt;
** For Content and each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
*Live : &lt;br /&gt;
**For Content, pass the Unix timestamp (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... . &lt;br /&gt;
**For each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
– (void) playheadPosition: (long long) playheadPos&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
AVPlayer *player;&lt;br /&gt;
CMTime curTime=[player currentTime];&lt;br /&gt;
int pos = CMTimeGetSeconds(curTime);&lt;br /&gt;
[nAppApiObject playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        //Monitor the Playhead position of the AVPlayer&lt;br /&gt;
        let timeInterval: CMTime = CMTimeMakeWithSeconds(1.0,10)&lt;br /&gt;
        self.avPlayerViewController.player?.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) {(elapsedTime: CMTime) -&amp;gt; Void in&lt;br /&gt;
            if self.avPlayerViewController.player!.currentItem?.status == .readyToPlay {&lt;br /&gt;
                let time : Float64 = self.avPlayerViewController.player!.currentTime().seconds;&lt;br /&gt;
                let pos = Int64(time);&lt;br /&gt;
                NSLog(&amp;quot;New Elapse Time = \(time)&amp;quot;);&lt;br /&gt;
                self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void setPlayheadPosition(long position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void) stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
Call when the content asset completes playback. Stops measurement progress. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;- (void) end;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending [[playheadPosition]] once the playback resumes (no [[loadMetadata]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional information:&lt;br /&gt;
* '''For type 'content': '''Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== App termination ===&lt;br /&gt;
If your app is executing a termination process and therefore ending the Content or Ad Playback, call [[end]] if the Content is playing or [[stop]] if an Ad is playing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
&lt;br /&gt;
The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain.&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
 &lt;br /&gt;
Please contact your Nielsen SDK support team directly for any related questions.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
#* '''Example Production Initialization Call''' - Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;iOS Example:&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Android Example:&amp;lt;/big&amp;gt;''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live, you have to inform the Nielsen team - this is necessary because the Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7625</id>
		<title>DCR Germany Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7625"/>
		<updated>2026-04-07T08:00:42Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK is the framework for browser developers to integrate Nielsen Measurement into their media player pages. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of pages like:&lt;br /&gt;
*Site launch events and how long page is viewed&lt;br /&gt;
*Time of viewing a sub-section / page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Please note:'''&lt;br /&gt;
The Browser SDK is intended to be used for native Browser implementations and cannot be used in a hybrid framework environment on Apps (Android, iOS) - e.g. for Cordova. Only native webview implementations may work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To get started, an AppID is needed. The AppID is a unique ID assigned to the player/site/app. This will be provided upon starting the integration from Nielsen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  apid: &amp;quot;XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot; // eg. PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* NLSQUEUE build v*/&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration files 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.&lt;br /&gt;
&lt;br /&gt;
===Create SDK Instance===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When creating an instance, pass the following three values:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/site ||	'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging. Only required for testing (not in production) || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;})&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example SDK Initialization ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on the apid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.eu.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Configuration ===&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique AppID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	// Add Static Queue Snippet&lt;br /&gt;
	!function(e,n){&lt;br /&gt;
		function t(e){&lt;br /&gt;
			return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
		}&lt;br /&gt;
		e[n]=e[n]||&lt;br /&gt;
		{&lt;br /&gt;
			nlsQ:function(o,r,c){&lt;br /&gt;
				var s=e.document,&lt;br /&gt;
				a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
				a.async=1,&lt;br /&gt;
				a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
				var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
				return i.parentNode.insertBefore(a,i),&lt;br /&gt;
				e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
				e[n][r]&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	// Created SDK Instance&lt;br /&gt;
	var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;, {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. Users will need to set up content and ad objects with the required Nielsen keys, as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Content Metadata ====&lt;br /&gt;
&lt;br /&gt;
===== Description of Content metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the video asset corresponding to the combination of the 2 AGF custom variables (c7 and c10) separated by an underscore character ('''&amp;lt;c7_c10&amp;gt;''').&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Example Content metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var content_metadata_object = {  &lt;br /&gt;
  type:     'content',&lt;br /&gt;
  assetid:  '88675545',&lt;br /&gt;
  program:  'Program Name',&lt;br /&gt;
  title:    'episode title',&lt;br /&gt;
  length:   '3600',&lt;br /&gt;
  nol_c0:  'p0,1',&lt;br /&gt;
  nol_c2:  'p2,Y',&lt;br /&gt;
  nol_c7:  'p7,videoid123',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c9:  'p9,VideoTitle123',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c12: 'p12,Content',&lt;br /&gt;
  nol_c18: 'p18,N'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ad Metadata ====&lt;br /&gt;
===== Description of Ad metadata =====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the Ad asset corresponding to  the  AGF custom variable '''c11'''.&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Ad metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var ad_metadata_object = {  &lt;br /&gt;
  type:     'preroll',&lt;br /&gt;
  assetid:  'ad345-67483',&lt;br /&gt;
  title:    'ad_title',&lt;br /&gt;
  length:   '25',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c11: 'p11,2352723141',&lt;br /&gt;
  nol_c12: 'p12,Werbung',&lt;br /&gt;
  nol_c17: 'p17,preroll'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Pause Event ===&lt;br /&gt;
To indicate pause&lt;br /&gt;
&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Send '''loadMetadata''' with the same metadata and continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
&lt;br /&gt;
=== Other Interrupt Scenarios ===&lt;br /&gt;
The following possible browser interruption scenarios must be handled:&lt;br /&gt;
&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
&lt;br /&gt;
There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. midroll vs. content).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var stopped = false;&lt;br /&gt;
function closePlayer() {&lt;br /&gt;
	if (stopped) {return;}&lt;br /&gt;
	stopped = true;&lt;br /&gt;
	if (inMidroll) {    // Only inside a midroll indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
		nSdkInstance.ggPM('stop', playheadPositionMidroll);&lt;br /&gt;
	}&lt;br /&gt;
	nSdkInstance.ggPM('end', playheadPositionContent);    // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
};&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer or covering Safari on mobile browsers ... you may use &amp;quot;onpagehide&amp;quot; event as well).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Call Nielsen APIs ==&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad)&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
*&amp;quot;VOD (or ad ): || current position in seconds (integer) &amp;lt;br/&amp;gt;&lt;br /&gt;
*&amp;quot;Live: current UTC timestamp (seconds since January 1st 1970)&amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position in seconds	|| Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==  SDK Event Lifecycle ==&lt;br /&gt;
&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Examples|&lt;br /&gt;
without Ads|&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle without ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:even browser no ads.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example without ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);  // must be called as start of stream&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playheads every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|with Ads=&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle with ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:event browser.png|event browser.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example with ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); // must be called as start of stream (even if 1st asset is preroll)&lt;br /&gt;
 &lt;br /&gt;
// PREROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end pre-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 for the first segment (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
  &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end mid-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from where it left off before mid-roll (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); &lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// POSTROLL&lt;br /&gt;
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); // end post-roll stream&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
* 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.&lt;br /&gt;
&lt;br /&gt;
* after an 'end' in case there is a new content played, there is a need to have another 'loadmetadata' again.&lt;br /&gt;
&lt;br /&gt;
* For Ad, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&lt;br /&gt;
* For pre-roll ads you have to call the loadMetadata event for content at the start of stream and after the preroll&lt;br /&gt;
&lt;br /&gt;
* '''For type 'content' ''': Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
== Livestream ==&lt;br /&gt;
For '''Livestreams'''  please make sure playheadPosition is in UNIX-Timestamp for Content.&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
The Browser SDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Browser SDK measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make a couple of updates to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7624</id>
		<title>DCR Germany Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7624"/>
		<updated>2026-04-07T07:59:24Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Ad metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK is the framework for browser developers to integrate Nielsen Measurement into their media player pages. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of pages like:&lt;br /&gt;
*Site launch events and how long page is viewed&lt;br /&gt;
*Time of viewing a sub-section / page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Please note:'''&lt;br /&gt;
The Browser SDK is intended to be used for native Browser implementations and cannot be used in a hybrid framework environment on Apps (Android, iOS) - e.g. for Cordova. Only native webview implementations may work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To get started, an AppID is needed. The AppID is a unique ID assigned to the player/site/app. This will be provided upon starting the integration from Nielsen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  apid: &amp;quot;XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot; // eg. PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* NLSQUEUE build v*/&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration files 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.&lt;br /&gt;
&lt;br /&gt;
===Create SDK Instance===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When creating an instance, pass the following three values:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/site ||	'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging. Only required for testing (not in production) || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;})&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example SDK Initialization ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on the apid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.eu.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Configuration ===&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique AppID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	// Add Static Queue Snippet&lt;br /&gt;
	!function(e,n){&lt;br /&gt;
		function t(e){&lt;br /&gt;
			return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
		}&lt;br /&gt;
		e[n]=e[n]||&lt;br /&gt;
		{&lt;br /&gt;
			nlsQ:function(o,r,c){&lt;br /&gt;
				var s=e.document,&lt;br /&gt;
				a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
				a.async=1,&lt;br /&gt;
				a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
				var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
				return i.parentNode.insertBefore(a,i),&lt;br /&gt;
				e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
				e[n][r]&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	// Created SDK Instance&lt;br /&gt;
	var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;, {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. Users will need to set up content and ad objects with the required Nielsen keys, as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Content Metadata ====&lt;br /&gt;
&lt;br /&gt;
===== Description of Content metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Example Content metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var content_metadata_object = {  &lt;br /&gt;
  type:     'content',&lt;br /&gt;
  assetid:  '88675545',&lt;br /&gt;
  program:  'Program Name',&lt;br /&gt;
  title:    'episode title',&lt;br /&gt;
  length:   '3600',&lt;br /&gt;
  nol_c0:  'p0,1',&lt;br /&gt;
  nol_c2:  'p2,Y',&lt;br /&gt;
  nol_c7:  'p7,videoid123',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c9:  'p9,VideoTitle123',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c12: 'p12,Content',&lt;br /&gt;
  nol_c18: 'p18,N'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ad Metadata ====&lt;br /&gt;
===== Description of Ad metadata =====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || Unique ID assigned to the Ad asset corresponding to  the  AGF custom variable '''c11'''.&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Ad metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var ad_metadata_object = {  &lt;br /&gt;
  type:     'preroll',&lt;br /&gt;
  assetid:  'ad345-67483',&lt;br /&gt;
  title:    'ad_title',&lt;br /&gt;
  length:   '25',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c11: 'p11,2352723141',&lt;br /&gt;
  nol_c12: 'p12,Werbung',&lt;br /&gt;
  nol_c17: 'p17,preroll'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Pause Event ===&lt;br /&gt;
To indicate pause&lt;br /&gt;
&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Send '''loadMetadata''' with the same metadata and continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
&lt;br /&gt;
=== Other Interrupt Scenarios ===&lt;br /&gt;
The following possible browser interruption scenarios must be handled:&lt;br /&gt;
&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
&lt;br /&gt;
There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. midroll vs. content).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var stopped = false;&lt;br /&gt;
function closePlayer() {&lt;br /&gt;
	if (stopped) {return;}&lt;br /&gt;
	stopped = true;&lt;br /&gt;
	if (inMidroll) {    // Only inside a midroll indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
		nSdkInstance.ggPM('stop', playheadPositionMidroll);&lt;br /&gt;
	}&lt;br /&gt;
	nSdkInstance.ggPM('end', playheadPositionContent);    // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
};&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer or covering Safari on mobile browsers ... you may use &amp;quot;onpagehide&amp;quot; event as well).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Call Nielsen APIs ==&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad)&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
*&amp;quot;VOD (or ad ): || current position in seconds (integer) &amp;lt;br/&amp;gt;&lt;br /&gt;
*&amp;quot;Live: current UTC timestamp (seconds since January 1st 1970)&amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position in seconds	|| Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==  SDK Event Lifecycle ==&lt;br /&gt;
&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Examples|&lt;br /&gt;
without Ads|&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle without ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:even browser no ads.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example without ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);  // must be called as start of stream&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playheads every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|with Ads=&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle with ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:event browser.png|event browser.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example with ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); // must be called as start of stream (even if 1st asset is preroll)&lt;br /&gt;
 &lt;br /&gt;
// PREROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end pre-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 for the first segment (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
  &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end mid-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from where it left off before mid-roll (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); &lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// POSTROLL&lt;br /&gt;
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); // end post-roll stream&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
* 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.&lt;br /&gt;
&lt;br /&gt;
* after an 'end' in case there is a new content played, there is a need to have another 'loadmetadata' again.&lt;br /&gt;
&lt;br /&gt;
* For Ad, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&lt;br /&gt;
* For pre-roll ads you have to call the loadMetadata event for content at the start of stream and after the preroll&lt;br /&gt;
&lt;br /&gt;
* '''For type 'content' ''': Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
== Livestream ==&lt;br /&gt;
For '''Livestreams'''  please make sure playheadPosition is in UNIX-Timestamp for Content.&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
The Browser SDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Browser SDK measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make a couple of updates to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7618</id>
		<title>DCR Germany Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7618"/>
		<updated>2026-04-02T11:54:35Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a S2S Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S (Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (AppID)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have its own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but '''latest within 3 hours of the start of that hourly viewing file interval'''. For example, files from '''2:00 AM to 3:00 AM''' must be delivered latest before '''5 AM'''.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving an exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicit request from AGF.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported formats are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delivered to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''. Only for the Asset Metadata Optimization use case, '''all''' is used additionally, see [[#Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day|Optimization for all Platforms]]&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653476400&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| end_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653479999&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
    &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
    &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Asset Metadata Delivery Optimization===&lt;br /&gt;
&lt;br /&gt;
====Optimization when the Asset Metadata File remains unchanged during the whole day per platform====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged during the whole day per platform, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File  Location per platform.&lt;br /&gt;
&lt;br /&gt;
The File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced in the manifest file for the following 23 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the Asset Metadata File for HOUR 00'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the Asset Metadata File for HOUR 00):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged for all platforms during the whole day, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File Location for all platforms.&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced hourly in the manifest file for all the 24 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the global Asset Metadata File'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the global Asset Metadata File):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Global Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC for all Platforms=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the global Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! AGF Metadata Convention Name - &amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Only for your Reference&lt;br /&gt;
&amp;lt;/pre&amp;gt;  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid  || assetid|| unique ID assigned to asset  &lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt; &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname  || program || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || title || episode name || custom -  no backslash allowed in string (because of 3rd party data processing)  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen   || length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || N/A|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand ||  subbrand (vcid) || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
 &lt;br /&gt;
|-&lt;br /&gt;
| nol_c0   || nol_c0 || number of episode part (Sendungsteilenummer)   || custom, if a content is not divided into several episode parts, set &amp;quot;0&amp;quot; as value.  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2   || nol_c2 || web only  || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || nol_c5   || page URL   || custom, The “Page URL” custom variable is reserved for sending the video’s server address.  ||  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || nol_c7  || Video ID. This variable is applicable in case the video asset is broken into multiple files each with their own asset ID. If a client has a single asset for a given episode/program, the value here should be identical to the assetid already provided in the viewership file. &lt;br /&gt;
  || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || nol_c9  || episode title   || custom - no backslash allowed in string (because of 3rd party data processing). if no further differentiation, then use &amp;quot;episodetitle&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10  || nol_c10  || publisher   || custom, used to differentiate different publishers   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c12  || nol_c12  || type of asset   || &amp;quot;Trailer&amp;quot; or &amp;quot;Content&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15  || nol_c15   || format ID   || If nol_c2 is always Yes, then it can stay blank &amp;quot;&amp;quot;   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c16  || nol_c16   || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads)   || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes&amp;quot;, etc   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c18  || nol_c18  || is a live stream    || &amp;quot;Y&amp;quot; for live stream otherwise &amp;quot;N&amp;quot;  || ✓  &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c8   || nol_c8 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c13   || nol_c13  || custom variable   || custom   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c14   || nol_c14 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c19   || nol_c19  || custom variable   || custom   || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;programname&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;episodetitle&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c02&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,3&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,publisherName&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''ONLY for''' '''android''' platform, DO NOT pass device_id for '''ios''', '''browser''' and '''ott''' platforms.  Mobile Ad ID ,  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; - OPTIONAL if passed in the Audit Ping|| i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638655&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android Platform : Example Metadata with &amp;quot;device_id&amp;quot;  =====&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; not available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in the respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || '''ONLY for''' '''android''' platform, DO NOT pass devid for '''ios''', '''browser''' and '''ott''' platforms. devid,  SHA-256 value of Device Id (ADID) -  OPTIONAL if passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;intid=&amp;lt;Integration ID&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;Android ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;&amp;amp;intid=xxxxxxxx&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7617</id>
		<title>DCR Germany Video Cloud API</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7617"/>
		<updated>2026-04-02T11:51:35Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing Cloud API =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a Cloud API Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging Cloud API Endpoint until you get the green light from Nielsen to move to Production!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
 || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Integration==&lt;br /&gt;
We will cover the steps for constructing the Cloud API Calls.&lt;br /&gt;
&lt;br /&gt;
====URL Structure====&lt;br /&gt;
&lt;br /&gt;
The Cloud API Calls are HTTP GET Requests with the URL structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;[endpoint]/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The URL includes the following components:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;[endpoint]&amp;lt;/code&amp;gt;: location of data collection environment&lt;br /&gt;
*&amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt;: provided App ID. &amp;lt;br&amp;gt;'''Note:'''The &amp;quot;P&amp;quot; prefix must be removed from the App ID received before adding it to the URL, i.e. if you received PDF20695-XXXX-XXXX-XXXX-3E334133D917 from Nielsen , your url will then be : &amp;lt;code&amp;gt;[endpoint]/DF20695-XXXX-XXXX-XXXX-3E334133D917/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;: unique value for each user session&lt;br /&gt;
*&amp;lt;code&amp;gt;[payload]&amp;lt;/code&amp;gt;: metadata and events&lt;br /&gt;
&lt;br /&gt;
====Endpoint====&lt;br /&gt;
&lt;br /&gt;
There are endpoints for testing and production:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide.&lt;br /&gt;
&lt;br /&gt;
====URL Example====&lt;br /&gt;
As you move through the integration steps, you can reference the below URL structure with the expanded payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content_metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event],&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playhead_position],&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type],&lt;br /&gt;
  &amp;quot;utc&amp;quot;: [Unix time in ms],&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: [unique view session ID for each video play]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create Session ID and send EMM Ping===&lt;br /&gt;
&lt;br /&gt;
====Create Session ID====&lt;br /&gt;
&lt;br /&gt;
A unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app.&lt;br /&gt;
&lt;br /&gt;
A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference and use.&lt;br /&gt;
&lt;br /&gt;
Session ID example: '''LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
'''// Create random GUID'''&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon exiting the app, the session will need to be terminated using the delete event. &amp;lt;br&amp;gt;&lt;br /&gt;
Sessions will automatically expire after 30 minutes of cloud inactivity.&lt;br /&gt;
&lt;br /&gt;
==== Send EMM Ping ====&lt;br /&gt;
An EMM Ping must be sent using the created unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; upon start of the first stream playback.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://[sessionID].uaid.nmrodam.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also see  [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference.&lt;br /&gt;
&lt;br /&gt;
===Create View Session ID for each Video Start===&lt;br /&gt;
An View Session ID &amp;lt;code&amp;gt;[sessid]&amp;lt;/code&amp;gt; must be created upon start of each stream playback, sessid is unique per video play.&lt;br /&gt;
&lt;br /&gt;
===Define URL Structure===&lt;br /&gt;
Define the URL structure using your provided &amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt; and a unique &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure Payload===&lt;br /&gt;
&lt;br /&gt;
====Description Payload====&lt;br /&gt;
&lt;br /&gt;
All Cloud API requests must contain the following payload data:&lt;br /&gt;
&lt;br /&gt;
*''devInfo'': device and app info&lt;br /&gt;
*''metadata'': asset metadata&lt;br /&gt;
*''event metadata'': type of event&lt;br /&gt;
&lt;br /&gt;
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section.&lt;br /&gt;
&lt;br /&gt;
==== Payload Example ====&lt;br /&gt;
&lt;br /&gt;
The example below should be referenced when following the steps for configuring the request payload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// 1. Create Session ID using the UUID Generator code provided&lt;br /&gt;
sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088  // Example sessionID &lt;br /&gt;
&lt;br /&gt;
// 2. Define URL Structure with App ID and Session ID&lt;br /&gt;
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
&lt;br /&gt;
// 3. Configure Payload&lt;br /&gt;
// 3.1 Configure Payload: devInfo &lt;br /&gt;
payload = {&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
   &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  // 3.2 Configure Payload: metadata&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: { // object for measuring video content&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  // 3.3 Configure Payload: events&lt;br /&gt;
  &amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, //event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, // position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, //&amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1456448742000&amp;quot;, //unix timestamp in milliseconds &lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot; // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Configure Payload: devInfo====&lt;br /&gt;
An object &amp;lt;code&amp;gt;&amp;quot;devInfo&amp;quot;&amp;lt;/code&amp;gt; will need to be created to capture App and Device information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| devId || unique ID to identify user (e.g. Advertising ID, Roku Device ID) - Not required for AGF || custom || &lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Example devInfo Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create devInfo object&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3.2 Configure Payload: metadata ====&lt;br /&gt;
Asset metadata can be passed through &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt;. There are two asset types: &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; for video and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; for ads. The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
You will need to set up &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt; objects for &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
===== Content Metadata =====&lt;br /&gt;
&lt;br /&gt;
====== Description of Content metadata ======&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Example Content metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang='json'&amp;gt;// create content object&lt;br /&gt;
&amp;quot;content&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ad Metadata (optional for public broadcasters) =====&lt;br /&gt;
====== Description of Ad metadata ======&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Example Ad metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;      &lt;br /&gt;
}&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Payload: Events ====&lt;br /&gt;
&lt;br /&gt;
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below.&lt;br /&gt;
&lt;br /&gt;
===== Event Types =====&lt;br /&gt;
&lt;br /&gt;
The available events are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; || &lt;br /&gt;
&lt;br /&gt;
===== Handling Playhead =====&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; is critical for accurate duration crediting. You can reference the below guidance to determine the correct playhead position to pass depending on the playback scenario.&lt;br /&gt;
&lt;br /&gt;
'''General'''&lt;br /&gt;
* Playhead position in seconds, must be passed as a whole number every 10 seconds. &lt;br /&gt;
* The final playhead position should be sent before before sending &amp;quot;complete&amp;quot; event when content playback is complete. &lt;br /&gt;
&lt;br /&gt;
'''Live Stream'''&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position. Note that ad playheads must also use Unix Time for each single Ad in an Ad Pod.&lt;br /&gt;
&lt;br /&gt;
'''VoD Stream'''&lt;br /&gt;
* For VoD stream use the player position for Content and Ad at playback start of a content or single Ad in an Ad Pod, playheads will then be 0, 10, 20, ....&lt;br /&gt;
&lt;br /&gt;
'''End of an Asset'''&lt;br /&gt;
* Final postion must be sent at the end of Content or Ad playback&lt;br /&gt;
&lt;br /&gt;
'''Ads'''&lt;br /&gt;
* The final playhead position must be sent when switching from content to ad, or ad to content.&lt;br /&gt;
* For Ad Pods, playhead must be called for each individual ad.&lt;br /&gt;
* When content has resumed following a mid-roll ad break, the next playhead position must continue where the previous content segment left off.&lt;br /&gt;
&lt;br /&gt;
'''User Actions'''&lt;br /&gt;
* SCRUBBING: Upon user scrubbing, the current position must be sent before a user scrubs, and the new position should be sent where the user lands, and begin sending in the 10 second updates thereafter.&lt;br /&gt;
* PAUSE: When content is paused, send current playhead position and stop passing playhead position until content is resumed.&lt;br /&gt;
* EXIT Stream: If a user exits a stream early, the last current position must be sent in a playhead update to receive accurate duration.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt; || The complete event must be sent : &lt;br /&gt;
* when the current video asset playback is terminated or completed, &lt;br /&gt;
* at the end of the current stream playback when the user switches to another piece of content or when the App is closed.&lt;br /&gt;
Before calling the complete event, a final playhead update with the final position is required to be sent to receive full duration credit. For Live streams, a complete event must be sent at program boundaries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || The delete event is optional and can be sent when the viewing session is terminated (typically on App close). A new session ID must be generated after sending a delete event. Delete should not be sent on app interruptions or foreground/background events. All creditable duration will be summarized for all asset types when delete occurs (content and ads).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Event Parameters =====&lt;br /&gt;
&lt;br /&gt;
The following parameters need to be passed when calling events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description !! Value !! Required&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;event&amp;quot;&amp;lt;/code&amp;gt; || event type || &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;position&amp;quot;&amp;lt;/code&amp;gt; || playhead position in seconds or Unix time in seconds || &amp;lt;code&amp;gt;&amp;quot;300&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;&amp;lt;/code&amp;gt; || asset type || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;utc&amp;quot;&amp;lt;/code&amp;gt; || Unix timestamp in milliseconds. Must be passed every 10 seconds. || &amp;lt;code&amp;gt;&amp;quot;1472760000000&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;sessid&amp;quot;&amp;lt;/code&amp;gt; || Unique View Session ID must be created upon start of each stream playback, sessid is unique per video play. || &amp;lt;code&amp;gt;&amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Event =====&lt;br /&gt;
You can call events by passing values in the required parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  // Event Parameters&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event], // event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playheadPosition], //position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type], // values are &amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;, //unix timestamp in milliseconds&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The full payload including &amp;quot;devInfo&amp;quot; and &amp;quot;metadata&amp;quot; must be populated in each event request.&lt;br /&gt;
&lt;br /&gt;
===== Sample Event Lifecycle for VoD Stream =====&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events and values to pass.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// Preroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Content&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content resumes at 15 minutes&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;900&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 30 minutes&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;1800&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Postroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Sample Event Lifecycle for VoD Stream - Detailed Storyline'''&lt;br /&gt;
This detailed event sequence provides additional insight for the correct events to call when handling certain playback scenarios.&lt;br /&gt;
&amp;lt;syntaxhighlight lang='javascript'&amp;gt;// SESSION STARTS&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// PREROLL&lt;br /&gt;
// Preroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Preroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;15&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
// CONTENT &lt;br /&gt;
// Content Start - Start new content streams with a position of &amp;quot;0&amp;quot; incrementing the position every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content Stop Before Ad Break - Send a playhead update including the current content positon before an Ad break.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;299&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787400000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
// Midroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;60&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472793500000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
// Content resumes at 5 minutes - Send playhead update with the current resumed position, and begin incrimenting the positon every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472799500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 10:12 - Make sure to send in the playhead event with the final content position before sending the complete event.&lt;br /&gt;
Final Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830700000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830800000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// POSTROLL&lt;br /&gt;
// Postroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830900000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Postroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;45&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835300000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// SESSION ENDS&lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835400000&amp;quot;} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Interruption Scenarios =====&lt;br /&gt;
&lt;br /&gt;
As part of configuring events, you will need to handle all possible interruption scenarios such as:&lt;br /&gt;
&lt;br /&gt;
*Wi-Fi OFF / ON&lt;br /&gt;
*App Crash or Exit&lt;br /&gt;
&lt;br /&gt;
When playback is interrupted, the app needs to send delete immediately.&lt;br /&gt;
&lt;br /&gt;
Once playback resumes, a new session will need to be created with a unique session ID. All of the required metadata and events will need to be sent.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The session will automatically timeout after 30 minutes of inactivity.&lt;br /&gt;
&lt;br /&gt;
=== Example Request ===&lt;br /&gt;
&lt;br /&gt;
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration.&lt;br /&gt;
&lt;br /&gt;
see '''[[#Payload Example|Payload Example]]'''&lt;br /&gt;
&lt;br /&gt;
// Append payload to URL&lt;br /&gt;
function sendPayloadToNielsen() {&lt;br /&gt;
  var payloadStr  = JSON.stringify(payload); // payload as string&lt;br /&gt;
  var imgPing = new Image();&lt;br /&gt;
  imgPing.onload = function() {&lt;br /&gt;
    // onload event, payload succesfull sent&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.onerror = function() {&lt;br /&gt;
    // handle error i.e. wait and send again&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.src = sessionURL+encodeURIComponent(payloadStr);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable Debug Logging ===&lt;br /&gt;
&lt;br /&gt;
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification.&lt;br /&gt;
&lt;br /&gt;
==== GET Request ====&lt;br /&gt;
&lt;br /&gt;
Display GET Request to console using a name to identify each event (e.g. playhead).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event&amp;quot;, image); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Output payload to identify required metadata and events.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event Payload&amp;quot;, payload); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response Code ====&lt;br /&gt;
&lt;br /&gt;
Confirm request was completed by viewing HTTP response code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
code = msg.GetResponseCode();&lt;br /&gt;
console.log(&amp;quot;Response Code&amp;quot;, code);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can reference the HTTP Response Code table when reviewing your requests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Status Code !! Status Text !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;200&amp;lt;/code&amp;gt; || OK || request received&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;403&amp;lt;/code&amp;gt; || Forbidden || invalid App ID&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;404&amp;lt;/code&amp;gt; || Not Found || JSON issue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll and postroll Ads.&lt;br /&gt;
&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; in the &amp;lt;code&amp;gt;Playback Settings&amp;lt;/code&amp;gt; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for AGF by selection Germany in the country dropbox [https://nielsenonlinesupport.com/agf/RefImplCloudAPI/index.htm?debug=true RefImplCloudAPI].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen CloudAPI Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen Cloud API measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Cloud API measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
&lt;br /&gt;
A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Before providing an app build to Nielsen for testing, it is important to run validation checks once you have enabled debug logging.&lt;br /&gt;
&lt;br /&gt;
=== Payload Validation ===&lt;br /&gt;
&lt;br /&gt;
Ensure that all of the required payload data is populating while testing several videos. The following areas are critical to measurement:&lt;br /&gt;
*devInfo&lt;br /&gt;
*Asset metadata for both content, and ads&lt;br /&gt;
*Events&lt;br /&gt;
&lt;br /&gt;
=== Player Events ===&lt;br /&gt;
Review event calls:&lt;br /&gt;
&lt;br /&gt;
==== playhead ====&lt;br /&gt;
*Playhead position updates every 10 seconds starting at position '0' for each new asset for VoD stream and UTC Unix Time in seconds for Live stream.&lt;br /&gt;
*Final playhead position is sent on content, or ad before switching between assets.&lt;br /&gt;
*Content metadata remains constant throughout an episode, or clip play.&lt;br /&gt;
*Ad metadata is populated appropriately for each individual ad.&lt;br /&gt;
*Playhead position update resumes for content after an ad break, and resets to 0 for each individual ad.&lt;br /&gt;
*For scrubbing, last current position should be sent while scrubbing occurs, and the new position should also be sent where the user scrubs to.&lt;br /&gt;
*Exiting a stream early should execute the last current position in a playhead update to receive accurate duration.&lt;br /&gt;
*Upon pause, the current position should be sent, and playhead updates should stop incrementing until resume play occurs.&lt;br /&gt;
&lt;br /&gt;
==== complete ====&lt;br /&gt;
*Check that the complete event executes upon content complete after the final playhead update is sent&lt;br /&gt;
*Do not execute the complete event for ads&lt;br /&gt;
&lt;br /&gt;
==== delete ====&lt;br /&gt;
*Check to see that the delete event occurs upon app exit, if the platform has the necessary exit callback events.&lt;br /&gt;
&lt;br /&gt;
==== GET Request Format ====&lt;br /&gt;
*Ensure that the event payloads are formatted in JSON&lt;br /&gt;
*Check to see that each of the Cloud API GET requests are properly encoded&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response ====&lt;br /&gt;
*Make sure that each of the Cloud API Get requests are received by the Nielsen Cloud API properly through use of the HTTP Response Code outputs enabled in console.&lt;br /&gt;
&lt;br /&gt;
== Go Live ==&lt;br /&gt;
After your integration has been certified, you will need to: Change Endpoint and Disable Logging.&lt;br /&gt;
&lt;br /&gt;
'''Change Endpoint:''' You will need to update to the production endpoint:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Production: &amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your production URL structure should now be:&lt;br /&gt;
&amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Disable Logging:''' You can now disable debug logging&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7616</id>
		<title>DCR Germany Video Cloud API</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Cloud_API&amp;diff=7616"/>
		<updated>2026-04-02T11:50:45Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Ad metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing Cloud API =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a Cloud API Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This guide shows you how to integrate the Nielsen Cloud API to enable Digital Content Ratings (DCR), and fuel other measurement products on your over-the-top (OTT) Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging Cloud API Endpoint until you get the green light from Nielsen to move to Production!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
 || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Integration==&lt;br /&gt;
We will cover the steps for constructing the Cloud API Calls.&lt;br /&gt;
&lt;br /&gt;
====URL Structure====&lt;br /&gt;
&lt;br /&gt;
The Cloud API Calls are HTTP GET Requests with the URL structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;[endpoint]/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The URL includes the following components:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;[endpoint]&amp;lt;/code&amp;gt;: location of data collection environment&lt;br /&gt;
*&amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt;: provided App ID. &amp;lt;br&amp;gt;'''Note:'''The &amp;quot;P&amp;quot; prefix must be removed from the App ID received before adding it to the URL, i.e. if you received PDF20695-XXXX-XXXX-XXXX-3E334133D917 from Nielsen , your url will then be : &amp;lt;code&amp;gt;[endpoint]/DF20695-XXXX-XXXX-XXXX-3E334133D917/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;: unique value for each user session&lt;br /&gt;
*&amp;lt;code&amp;gt;[payload]&amp;lt;/code&amp;gt;: metadata and events&lt;br /&gt;
&lt;br /&gt;
====Endpoint====&lt;br /&gt;
&lt;br /&gt;
There are endpoints for testing and production:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During testing, all calls should be pointed to the testing endpoint. We will review the update to the production endpoint during the Go Live section of this guide.&lt;br /&gt;
&lt;br /&gt;
====URL Example====&lt;br /&gt;
As you move through the integration steps, you can reference the below URL structure with the expanded payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content_metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event],&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playhead_position],&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type],&lt;br /&gt;
  &amp;quot;utc&amp;quot;: [Unix time in ms],&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: [unique view session ID for each video play]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Create Session ID and send EMM Ping===&lt;br /&gt;
&lt;br /&gt;
====Create Session ID====&lt;br /&gt;
&lt;br /&gt;
A unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; must be created upon app launch and provided in the URL. This will allow the measurement to occur for the entire duration that a user is within the app.&lt;br /&gt;
&lt;br /&gt;
A Session ID needs to be completely unique so it is recommended to use our generation method example provided below to create unique alpha-numerical 29 characters + 10 characters UTC timestamp, to guarantee there are no repeats, also see [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference and use.&lt;br /&gt;
&lt;br /&gt;
Session ID example: '''LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088'''&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
'''// Create random GUID'''&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon exiting the app, the session will need to be terminated using the delete event. &amp;lt;br&amp;gt;&lt;br /&gt;
Sessions will automatically expire after 30 minutes of cloud inactivity.&lt;br /&gt;
&lt;br /&gt;
==== Send EMM Ping ====&lt;br /&gt;
An EMM Ping must be sent using the created unique Session ID &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt; upon start of the first stream playback.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
https://[sessionID].uaid.nmrodam.com/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Also see  [[#Review the Reference Implementation for VoD and Live Streams|Reference Implementation for VoD and Live Streams]] for your reference.&lt;br /&gt;
&lt;br /&gt;
===Create View Session ID for each Video Start===&lt;br /&gt;
An View Session ID &amp;lt;code&amp;gt;[sessid]&amp;lt;/code&amp;gt; must be created upon start of each stream playback, sessid is unique per video play.&lt;br /&gt;
&lt;br /&gt;
===Define URL Structure===&lt;br /&gt;
Define the URL structure using your provided &amp;lt;code&amp;gt;[appid]&amp;lt;/code&amp;gt; and a unique &amp;lt;code&amp;gt;[sessionID]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configure Payload===&lt;br /&gt;
&lt;br /&gt;
====Description Payload====&lt;br /&gt;
&lt;br /&gt;
All Cloud API requests must contain the following payload data:&lt;br /&gt;
&lt;br /&gt;
*''devInfo'': device and app info&lt;br /&gt;
*''metadata'': asset metadata&lt;br /&gt;
*''event metadata'': type of event&lt;br /&gt;
&lt;br /&gt;
The payload can be passed through key-values using the Nielsen reserved keys. The specific keys and descriptions are highlighted in the tables included in this section.&lt;br /&gt;
&lt;br /&gt;
==== Payload Example ====&lt;br /&gt;
&lt;br /&gt;
The example below should be referenced when following the steps for configuring the request payload.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// 1. Create Session ID using the UUID Generator code provided&lt;br /&gt;
sessionID = LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088  // Example sessionID &lt;br /&gt;
&lt;br /&gt;
// 2. Define URL Structure with App ID and Session ID&lt;br /&gt;
sessionURL = https://sc-eucert.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=&lt;br /&gt;
&lt;br /&gt;
// 3. Configure Payload&lt;br /&gt;
// 3.1 Configure Payload: devInfo &lt;br /&gt;
payload = {&lt;br /&gt;
 &amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
   &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
   &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  // 3.2 Configure Payload: metadata&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: { // object for measuring video content&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  // 3.3 Configure Payload: events&lt;br /&gt;
  &amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, //event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, // position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, //&amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1456448742000&amp;quot;, //unix timestamp in milliseconds &lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot; // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Configure Payload: devInfo====&lt;br /&gt;
An object &amp;lt;code&amp;gt;&amp;quot;devInfo&amp;quot;&amp;lt;/code&amp;gt; will need to be created to capture App and Device information.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| devId || unique ID to identify user (e.g. Advertising ID, Roku Device ID) - Not required for AGF || custom || &lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Example devInfo Object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create devInfo object&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;devId&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;apn&amp;quot;: &amp;quot;AppName&amp;quot;,&lt;br /&gt;
  &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3.2 Configure Payload: metadata ====&lt;br /&gt;
Asset metadata can be passed through &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt;. There are two asset types: &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; for video and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; for ads. The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
You will need to set up &amp;lt;code&amp;gt;&amp;quot;metadata&amp;quot;&amp;lt;/code&amp;gt; objects for &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
===== Content Metadata =====&lt;br /&gt;
&lt;br /&gt;
====== Description of Content metadata ======&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)|| custom (no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Example Content metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang='json'&amp;gt;// create content object&lt;br /&gt;
&amp;quot;content&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
      &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  	  // custom metadata&lt;br /&gt;
      &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ad Metadata (optional for public broadcasters) =====&lt;br /&gt;
====== Description of Ad metadata ======&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Example Ad metadata ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// create ad object&lt;br /&gt;
&amp;quot;ad&amp;quot;: {&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
      &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
      &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
      &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;      &lt;br /&gt;
}&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configure Payload: Events ====&lt;br /&gt;
&lt;br /&gt;
The last part of the payload is for enabling events so content is measured correctly when viewed. The events and required parameters are included below.&lt;br /&gt;
&lt;br /&gt;
===== Event Types =====&lt;br /&gt;
&lt;br /&gt;
The available events are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; || &lt;br /&gt;
&lt;br /&gt;
===== Handling Playhead =====&lt;br /&gt;
&lt;br /&gt;
Calling &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt; is critical for accurate duration crediting. You can reference the below guidance to determine the correct playhead position to pass depending on the playback scenario.&lt;br /&gt;
&lt;br /&gt;
'''General'''&lt;br /&gt;
* Playhead position in seconds, must be passed as a whole number every 10 seconds. &lt;br /&gt;
* The final playhead position should be sent before before sending &amp;quot;complete&amp;quot; event when content playback is complete. &lt;br /&gt;
&lt;br /&gt;
'''Live Stream'''&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position. Note that ad playheads must also use Unix Time for each single Ad in an Ad Pod.&lt;br /&gt;
&lt;br /&gt;
'''VoD Stream'''&lt;br /&gt;
* For VoD stream use the player position for Content and Ad at playback start of a content or single Ad in an Ad Pod, playheads will then be 0, 10, 20, ....&lt;br /&gt;
&lt;br /&gt;
'''End of an Asset'''&lt;br /&gt;
* Final postion must be sent at the end of Content or Ad playback&lt;br /&gt;
&lt;br /&gt;
'''Ads'''&lt;br /&gt;
* The final playhead position must be sent when switching from content to ad, or ad to content.&lt;br /&gt;
* For Ad Pods, playhead must be called for each individual ad.&lt;br /&gt;
* When content has resumed following a mid-roll ad break, the next playhead position must continue where the previous content segment left off.&lt;br /&gt;
&lt;br /&gt;
'''User Actions'''&lt;br /&gt;
* SCRUBBING: Upon user scrubbing, the current position must be sent before a user scrubs, and the new position should be sent where the user lands, and begin sending in the 10 second updates thereafter.&lt;br /&gt;
* PAUSE: When content is paused, send current playhead position and stop passing playhead position until content is resumed.&lt;br /&gt;
* EXIT Stream: If a user exits a stream early, the last current position must be sent in a playhead update to receive accurate duration.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt; || The complete event must be sent : &lt;br /&gt;
* when the current video asset playback is terminated or completed, &lt;br /&gt;
* at the end of the current stream playback when the user switches to another piece of content or when the App is closed.&lt;br /&gt;
Before calling the complete event, a final playhead update with the final position is required to be sent to receive full duration credit. For Live streams, a complete event must be sent at program boundaries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || The delete event is optional and can be sent when the viewing session is terminated (typically on App close). A new session ID must be generated after sending a delete event. Delete should not be sent on app interruptions or foreground/background events. All creditable duration will be summarized for all asset types when delete occurs (content and ads).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Event Parameters =====&lt;br /&gt;
&lt;br /&gt;
The following parameters need to be passed when calling events:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description !! Value !! Required&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;event&amp;quot;&amp;lt;/code&amp;gt; || event type || &amp;lt;code&amp;gt;&amp;quot;playhead&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;complete&amp;quot;&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;&amp;quot;delete&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;position&amp;quot;&amp;lt;/code&amp;gt; || playhead position in seconds or Unix time in seconds || &amp;lt;code&amp;gt;&amp;quot;300&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;type&amp;quot;&amp;lt;/code&amp;gt; || asset type || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;utc&amp;quot;&amp;lt;/code&amp;gt; || Unix timestamp in milliseconds. Must be passed every 10 seconds. || &amp;lt;code&amp;gt;&amp;quot;1472760000000&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;quot;sessid&amp;quot;&amp;lt;/code&amp;gt; || Unique View Session ID must be created upon start of each stream playback, sessid is unique per video play. || &amp;lt;code&amp;gt;&amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Event =====&lt;br /&gt;
You can call events by passing values in the required parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;devInfo&amp;quot;: [deviceInfo],&lt;br /&gt;
  &amp;quot;metadata&amp;quot;: {&lt;br /&gt;
    &amp;quot;content&amp;quot;: [content metadata],&lt;br /&gt;
    &amp;quot;ad&amp;quot;: [ad metadata]&lt;br /&gt;
  },&lt;br /&gt;
  // Event Parameters&lt;br /&gt;
  &amp;quot;event&amp;quot;: [event], // event name&lt;br /&gt;
  &amp;quot;position&amp;quot;: [playheadPosition], //position in seconds&lt;br /&gt;
  &amp;quot;type&amp;quot;: [asset type], // values are &amp;quot;content&amp;quot; or &amp;quot;ad&amp;quot;&lt;br /&gt;
  &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;, //unix timestamp in milliseconds&lt;br /&gt;
  &amp;quot;sessid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // unique for each video play&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The full payload including &amp;quot;devInfo&amp;quot; and &amp;quot;metadata&amp;quot; must be populated in each event request.&lt;br /&gt;
&lt;br /&gt;
===== Sample Event Lifecycle for VoD Stream =====&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events and values to pass.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// Preroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Content&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content resumes at 15 minutes&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;900&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 30 minutes&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;1800&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
 &lt;br /&gt;
// Postroll&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Sample Event Lifecycle for VoD Stream - Detailed Storyline'''&lt;br /&gt;
This detailed event sequence provides additional insight for the correct events to call when handling certain playback scenarios.&lt;br /&gt;
&amp;lt;syntaxhighlight lang='javascript'&amp;gt;// SESSION STARTS&lt;br /&gt;
// Start of Session: session ID created when App is opened&lt;br /&gt;
&lt;br /&gt;
// PREROLL&lt;br /&gt;
// Preroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472760000000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Preroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;15&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
// CONTENT &lt;br /&gt;
// Content Start - Start new content streams with a position of &amp;quot;0&amp;quot; incrementing the position every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472761500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content Stop Before Ad Break - Send a playhead update including the current content positon before an Ad break.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;299&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787400000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
// Midroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Midroll Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472787500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Midroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;60&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472793500000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
// Content resumes at 5 minutes - Send playhead update with the current resumed position, and begin incrimenting the positon every 10 seconds.&lt;br /&gt;
Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;300&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472799500000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Content completes at 10:12 - Make sure to send in the playhead event with the final content position before sending the complete event.&lt;br /&gt;
Final Content Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830700000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
Complete {&amp;quot;event&amp;quot;: &amp;quot;complete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;612&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830800000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// POSTROLL&lt;br /&gt;
// Postroll Start - Start each Ad with a position of &amp;quot;0&amp;quot;, resetting to '0' for each Ad, and Ad break.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;0&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472830900000&amp;quot;} &lt;br /&gt;
&lt;br /&gt;
// Postroll Stop - End each Ad with the final position of the Ad.&lt;br /&gt;
Ad Playhead {&amp;quot;event&amp;quot;: &amp;quot;playhead&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;45&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;ad&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835300000&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
// SESSION ENDS&lt;br /&gt;
&lt;br /&gt;
//End of Session: The delete event should be called when the App is exited. The values for position and type not required to be passed.&lt;br /&gt;
Delete { &amp;quot;event&amp;quot;: &amp;quot;delete&amp;quot;, &amp;quot;position&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;type&amp;quot;: &amp;quot;&amp;quot;, &amp;quot;utc&amp;quot;: &amp;quot;1472835400000&amp;quot;} &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Interruption Scenarios =====&lt;br /&gt;
&lt;br /&gt;
As part of configuring events, you will need to handle all possible interruption scenarios such as:&lt;br /&gt;
&lt;br /&gt;
*Wi-Fi OFF / ON&lt;br /&gt;
*App Crash or Exit&lt;br /&gt;
&lt;br /&gt;
When playback is interrupted, the app needs to send delete immediately.&lt;br /&gt;
&lt;br /&gt;
Once playback resumes, a new session will need to be created with a unique session ID. All of the required metadata and events will need to be sent.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The session will automatically timeout after 30 minutes of inactivity.&lt;br /&gt;
&lt;br /&gt;
=== Example Request ===&lt;br /&gt;
&lt;br /&gt;
Now that we walked through the Cloud API integration steps, your requests should have the following components: Session ID, App ID, and Payload. You can reference the example below when your reviewing your integration.&lt;br /&gt;
&lt;br /&gt;
see '''[[#Payload Example|Payload Example]]'''&lt;br /&gt;
&lt;br /&gt;
// Append payload to URL&lt;br /&gt;
function sendPayloadToNielsen() {&lt;br /&gt;
  var payloadStr  = JSON.stringify(payload); // payload as string&lt;br /&gt;
  var imgPing = new Image();&lt;br /&gt;
  imgPing.onload = function() {&lt;br /&gt;
    // onload event, payload succesfull sent&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.onerror = function() {&lt;br /&gt;
    // handle error i.e. wait and send again&lt;br /&gt;
  };&lt;br /&gt;
  imgPing.src = sessionURL+encodeURIComponent(payloadStr);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable Debug Logging ===&lt;br /&gt;
&lt;br /&gt;
Now that you have set up the Cloud API requests, you can enable debug logging to validate your integration. Enabling debug logging is required for Nielsen certification.&lt;br /&gt;
&lt;br /&gt;
==== GET Request ====&lt;br /&gt;
&lt;br /&gt;
Display GET Request to console using a name to identify each event (e.g. playhead).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event&amp;quot;, image); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Output payload to identify required metadata and events.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
console.log(&amp;quot;Event Payload&amp;quot;, payload); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response Code ====&lt;br /&gt;
&lt;br /&gt;
Confirm request was completed by viewing HTTP response code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
code = msg.GetResponseCode();&lt;br /&gt;
console.log(&amp;quot;Response Code&amp;quot;, code);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can reference the HTTP Response Code table when reviewing your requests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Status Code !! Status Text !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;200&amp;lt;/code&amp;gt; || OK || request received&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;403&amp;lt;/code&amp;gt; || Forbidden || invalid App ID&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;404&amp;lt;/code&amp;gt; || Not Found || JSON issue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll and postroll Ads.&lt;br /&gt;
&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; in the &amp;lt;code&amp;gt;Playback Settings&amp;lt;/code&amp;gt; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for AGF by selection Germany in the country dropbox [https://nielsenonlinesupport.com/agf/RefImplCloudAPI/index.htm?debug=true RefImplCloudAPI].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen CloudAPI Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen Cloud API measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Cloud API measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
&lt;br /&gt;
A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
Before providing an app build to Nielsen for testing, it is important to run validation checks once you have enabled debug logging.&lt;br /&gt;
&lt;br /&gt;
=== Payload Validation ===&lt;br /&gt;
&lt;br /&gt;
Ensure that all of the required payload data is populating while testing several videos. The following areas are critical to measurement:&lt;br /&gt;
*devInfo&lt;br /&gt;
*Asset metadata for both content, and ads&lt;br /&gt;
*Events&lt;br /&gt;
&lt;br /&gt;
=== Player Events ===&lt;br /&gt;
Review event calls:&lt;br /&gt;
&lt;br /&gt;
==== playhead ====&lt;br /&gt;
*Playhead position updates every 10 seconds starting at position '0' for each new asset for VoD stream and UTC Unix Time in seconds for Live stream.&lt;br /&gt;
*Final playhead position is sent on content, or ad before switching between assets.&lt;br /&gt;
*Content metadata remains constant throughout an episode, or clip play.&lt;br /&gt;
*Ad metadata is populated appropriately for each individual ad.&lt;br /&gt;
*Playhead position update resumes for content after an ad break, and resets to 0 for each individual ad.&lt;br /&gt;
*For scrubbing, last current position should be sent while scrubbing occurs, and the new position should also be sent where the user scrubs to.&lt;br /&gt;
*Exiting a stream early should execute the last current position in a playhead update to receive accurate duration.&lt;br /&gt;
*Upon pause, the current position should be sent, and playhead updates should stop incrementing until resume play occurs.&lt;br /&gt;
&lt;br /&gt;
==== complete ====&lt;br /&gt;
*Check that the complete event executes upon content complete after the final playhead update is sent&lt;br /&gt;
*Do not execute the complete event for ads&lt;br /&gt;
&lt;br /&gt;
==== delete ====&lt;br /&gt;
*Check to see that the delete event occurs upon app exit, if the platform has the necessary exit callback events.&lt;br /&gt;
&lt;br /&gt;
==== GET Request Format ====&lt;br /&gt;
*Ensure that the event payloads are formatted in JSON&lt;br /&gt;
*Check to see that each of the Cloud API GET requests are properly encoded&lt;br /&gt;
&lt;br /&gt;
==== HTTP Response ====&lt;br /&gt;
*Make sure that each of the Cloud API Get requests are received by the Nielsen Cloud API properly through use of the HTTP Response Code outputs enabled in console.&lt;br /&gt;
&lt;br /&gt;
== Go Live ==&lt;br /&gt;
After your integration has been certified, you will need to: Change Endpoint and Disable Logging.&lt;br /&gt;
&lt;br /&gt;
'''Change Endpoint:''' You will need to update to the production endpoint:&lt;br /&gt;
&lt;br /&gt;
*Testing: &amp;lt;code&amp;gt;https://sc-eucert.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
*Production: &amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your production URL structure should now be:&lt;br /&gt;
&amp;lt;code&amp;gt;https://???.nmrodam.com/nmapi/v2/[appid]/[sessionID]/a?b=[payload]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Disable Logging:''' You can now disable debug logging&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7615</id>
		<title>DCR Germany Video App SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7615"/>
		<updated>2026-04-02T11:49:58Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Ad metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR), [[Digital Audio]]. Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long the app was running&lt;br /&gt;
*Time of viewing a sub-section/page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following details are required:&lt;br /&gt;
* '''App ID (appid):''' Unique ID assigned to the player/site and configured by product.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''No ID AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;ONLY the No ID AppSDK should be downloaded for the AGF market!&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Nielsen SDK:''' The Nielsen SDK package contains a variety of sample players for your reference.&lt;br /&gt;
Please contact our SDK sales support team if you do not have any of these prerequisites or have any questions.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode and Android using Android Studio.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
&lt;br /&gt;
=== iOS  ===&lt;br /&gt;
&lt;br /&gt;
==== Special Notes regarding iOS17 or TVOS17  ====&lt;br /&gt;
Beginning with iOS/TVOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs.&lt;br /&gt;
&lt;br /&gt;
Since AGF market is not making use of the IDFA, the change is expected to have no impact.&lt;br /&gt;
&lt;br /&gt;
However, in order to minimize any eventual impact, we are asking that AGF clients do the following:&lt;br /&gt;
&lt;br /&gt;
* '''Do not declare the Nielsen nmrodam.com domain in the privacy manifest'''&lt;br /&gt;
* Update to the latest Nielsen SDK release &amp;gt;= 9.2.0.0 when compiling your app for iOS 17&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For any additional information please refer to the Nielsen global page: [[DCR and DTVR with iOS17 or TVOS17]].&lt;br /&gt;
&lt;br /&gt;
==== General  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Xcode Development Environment''' &lt;br /&gt;
&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK is compatible with Apple iOS versions 9.0 and above.&lt;br /&gt;
&lt;br /&gt;
The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Importing Frameworks'''&amp;lt;/big&amp;gt;&lt;br /&gt;
The first step is to ensure that the following frameworks and libraries are imported into the Frameworks folder of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework uses several functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework &lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Example'''&lt;br /&gt;
* Extract “NielsenAppApi.Framework” from the Nielsen App SDK sample app and copy it to the Frameworks folder of the Xcode project.&lt;br /&gt;
* Add the code &amp;lt;code&amp;gt;-#import NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller’s header file.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Ensure that the following are included in the Linked Frameworks and Libraries list (located in the project’s Summary settings).&lt;br /&gt;
* Nielsen App SDK&lt;br /&gt;
* iOS security framework&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Swift'''&amp;lt;/big&amp;gt;&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Objective-C'''&amp;lt;/big&amp;gt;&lt;br /&gt;
Add the code &lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Android  ===&lt;br /&gt;
==== General  ====&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Android Java Development Environment'''&lt;br /&gt;
&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The Nielsen App SDK (located in the ''com.nielsen.app.sdk'' package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
&lt;br /&gt;
'''Nielsen App SDK is compatible with Android OS versions 2.3+. Clients can control/configure the protocol to be used – HTTPS or HTTP to suit their needs.'''&lt;br /&gt;
&lt;br /&gt;
The Nielsen App SDK 1.2 library is composed of two parts:&lt;br /&gt;
* The Java AppSdk.jar library runs on the Android’s Dalvik Virtual Machine.&lt;br /&gt;
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.&lt;br /&gt;
* '''For Video player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 3.0 and later will support it natively).&lt;br /&gt;
** If the player application uses a 3rd party media player implementing its own HLS, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
* '''For Audio player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should be at version 2.3 and later since the SDK depends on Google Play support to work properly.&lt;br /&gt;
Unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.&lt;br /&gt;
Add the following permissions on the project’s ''AndroidManifest.xml'' file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For more details on handling runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.&lt;br /&gt;
* App SDK checks to see if a Google service is available and updated.&lt;br /&gt;
* If unavailable or updated, App SDK will not use this service when executing its functions and will reference missing imports and the app will not be compiled.&lt;br /&gt;
To include the Google Play library in the media player project, copy the ''google-play-services_lib'' folder into the same location as the project&lt;br /&gt;
* Access '''File &amp;gt; Import'''.&lt;br /&gt;
* Select '''Existing Android Code into Workspace''' and click '''Next'''.&lt;br /&gt;
* Click '''Browse''' and navigate to the ''google-play-services_lib'' to include it into the projects.&lt;br /&gt;
* Select the exact '''Project Build Target''' for Eclipse to use from Android SDK.&lt;br /&gt;
** Android 4.4.2, etc. OR&lt;br /&gt;
** Edit ''project.properties'' file to point to Android target version e.g. target= android-19.&lt;br /&gt;
Once the google-play-services_lib is included into the App project, include the following code under the &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; node in the &amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data android:name=&amp;quot;com.google.android.gms.version&amp;quot; android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, include the ''version.xml'' file that comes with the ''google-play-services_lib'' under the res/values directory of the media player project.&lt;br /&gt;
* Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Library'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Classes/package&amp;lt;/big&amp;gt;'''&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
==== Add the dependency &amp;quot;lifecycle-extensions&amp;quot; to your project  ====&lt;br /&gt;
Add the dependency &amp;quot;lifecycle-extensions&amp;quot; in the in the app gradle file as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will enable the AppSdk to detect the application UI visibility state transitions between background and foreground by utilizing the LifeCycleObserver. This is i.e. required for the Static Measurement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated before version 5.1.1. (Version 4.0 for Android)&lt;br /&gt;
&lt;br /&gt;
* A maximum of four SDK instances per appid are supported. When a fifth SDK instance is launched, the SDK will return “nil” from [[initWithAppInfo:delegate:]]&lt;br /&gt;
* When four SDK instances exist, you must destroy an old instance before creating a new one.&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
&lt;br /&gt;
* The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || No || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || Client-defined || No || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
'''AGF Clients'''&lt;br /&gt;
* &amp;quot;eu&amp;quot; (For Testing/Certification and in Production)&lt;br /&gt;
|| Nielsen-specified || ✓ || &amp;quot;eu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Has to be set to &amp;quot;DEBUG&amp;quot; until certified&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
=====  iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
    &lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======  Objective-C ======&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====  Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&lt;br /&gt;
AppSDK is no longer a singleton object and should be initialized as below.&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;appname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sfcode&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on the type of client app.&amp;lt;br /&amp;gt;&lt;br /&gt;
* Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on the property page of the App’s project).&lt;br /&gt;
&lt;br /&gt;
== APP SDK Error &amp;amp; Event Codes ==&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
== Configure Payload ==&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handle only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of the unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** The error message will be logged if the string has an invalid JSON format.&lt;br /&gt;
* JSON value must be a string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
&lt;br /&gt;
=== Configure ChannelInfo metadata === &lt;br /&gt;
==== Description of ChannelInfo metadata ====&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ChannelInfo metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
       let channelInfo = [&lt;br /&gt;
            &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Configure Content metadata ===&lt;br /&gt;
&lt;br /&gt;
==== Description of Content metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example Content metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
	&amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
        &lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;, &lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;88675545&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;3600&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;88675545&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;3600&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c0&amp;quot;, &amp;quot;p0,1&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c2&amp;quot;, &amp;quot;p2,Y&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c7&amp;quot;, &amp;quot;p7,videoid123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c9&amp;quot;, &amp;quot;p9,VideoTitle123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c18&amp;quot;, &amp;quot;p18,N&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure Ad Metadata ===&lt;br /&gt;
==== Description of Ad metadata ====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
let adMetadata = [&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;preroll&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;ad345-67483&amp;quot;&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;ad_title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;25&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JSONObject adMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;preroll&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;ad345-67483&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;25&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c11&amp;quot;, &amp;quot;p11,2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Werbung&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c17&amp;quot;, &amp;quot;p17,preroll&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
=== Sample API Sequence ===&lt;br /&gt;
A Sample API sequence could follow this flow:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;[nielsenMeter play: channelName];&amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadataObject];&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;[nielsenMeter playheadPosition: position];&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;[nielsenMeter end];&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Life cycle of SDK instance ===&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance processes playing information. [[play]] and [[loadMetadata]] calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## [[playheadPosition]] – Call this API every one second when playhead position timer is fired.&lt;br /&gt;
## [[stop]] – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## [[end]] – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to pause the measurement.&lt;br /&gt;
* As soon as the playback resumes, call [[loadMetadata]] and  [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
'''[[#Example Content metadata|Example Content metadata]]'''&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the stream playback is interrupted or has ended.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: ONLY for a preroll Ad , Call [[loadMetadata()]] for Content before calling it for preroll ad &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
'''[[#Example Ad metadata|Example Ad metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the Ad playback is interrupted or has ended for each single Ad. Playhead should be passed for the entire duration of ad pod, if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after the content is paused (ad starts)&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the midroll ad is being played &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content (Content resume) || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Always call stop irrespective of postroll is followed or not&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequence of Calls ===&lt;br /&gt;
&lt;br /&gt;
=== play ===&lt;br /&gt;
Use [[play]] to pass the channel descriptor information through channelName parameter after the SDK has been initialized and the content starts playing. If the user is returning from a '''Pause/Stop''' interaction, call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   - (void)play:(id)channelInfo;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    public void play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenAppApi?.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void)loadMetadata:(id)contentMetadata;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;playheadPosition&amp;quot; has to be called every second.&lt;br /&gt;
&lt;br /&gt;
* VOD : &lt;br /&gt;
** For Content and each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
*Live : &lt;br /&gt;
**For Content, pass the Unix timestamp (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... . &lt;br /&gt;
**For each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
– (void) playheadPosition: (long long) playheadPos&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
AVPlayer *player;&lt;br /&gt;
CMTime curTime=[player currentTime];&lt;br /&gt;
int pos = CMTimeGetSeconds(curTime);&lt;br /&gt;
[nAppApiObject playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        //Monitor the Playhead position of the AVPlayer&lt;br /&gt;
        let timeInterval: CMTime = CMTimeMakeWithSeconds(1.0,10)&lt;br /&gt;
        self.avPlayerViewController.player?.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) {(elapsedTime: CMTime) -&amp;gt; Void in&lt;br /&gt;
            if self.avPlayerViewController.player!.currentItem?.status == .readyToPlay {&lt;br /&gt;
                let time : Float64 = self.avPlayerViewController.player!.currentTime().seconds;&lt;br /&gt;
                let pos = Int64(time);&lt;br /&gt;
                NSLog(&amp;quot;New Elapse Time = \(time)&amp;quot;);&lt;br /&gt;
                self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void setPlayheadPosition(long position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void) stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
Call when the content asset completes playback. Stops measurement progress. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;- (void) end;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending [[playheadPosition]] once the playback resumes (no [[loadMetadata]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional information:&lt;br /&gt;
* '''For type 'content': '''Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== App termination ===&lt;br /&gt;
If your app is executing a termination process and therefore ending the Content or Ad Playback, call [[end]] if the Content is playing or [[stop]] if an Ad is playing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
&lt;br /&gt;
The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain.&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
 &lt;br /&gt;
Please contact your Nielsen SDK support team directly for any related questions.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
#* '''Example Production Initialization Call''' - Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;iOS Example:&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Android Example:&amp;lt;/big&amp;gt;''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live, you have to inform the Nielsen team - this is necessary because the Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7614</id>
		<title>DCR Germany Video App SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_App_SDK&amp;diff=7614"/>
		<updated>2026-04-02T11:48:49Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR), [[Digital Audio]]. Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long the app was running&lt;br /&gt;
*Time of viewing a sub-section/page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To start using the App SDK, the following details are required:&lt;br /&gt;
* '''App ID (appid):''' Unique ID assigned to the player/site and configured by product.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''No ID AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;ONLY the No ID AppSDK should be downloaded for the AGF market!&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Nielsen SDK:''' The Nielsen SDK package contains a variety of sample players for your reference.&lt;br /&gt;
Please contact our SDK sales support team if you do not have any of these prerequisites or have any questions.&lt;br /&gt;
Refer to [[Digital Measurement Onboarding]] guide for information on how to get a Nielsen App SDK and appid.&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
This guide covers implementation steps for iOS using Xcode and Android using Android Studio.&lt;br /&gt;
&lt;br /&gt;
== Setting up your  Development Environment  ==&lt;br /&gt;
&lt;br /&gt;
=== iOS  ===&lt;br /&gt;
&lt;br /&gt;
==== Special Notes regarding iOS17 or TVOS17  ====&lt;br /&gt;
Beginning with iOS/TVOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs.&lt;br /&gt;
&lt;br /&gt;
Since AGF market is not making use of the IDFA, the change is expected to have no impact.&lt;br /&gt;
&lt;br /&gt;
However, in order to minimize any eventual impact, we are asking that AGF clients do the following:&lt;br /&gt;
&lt;br /&gt;
* '''Do not declare the Nielsen nmrodam.com domain in the privacy manifest'''&lt;br /&gt;
* Update to the latest Nielsen SDK release &amp;gt;= 9.2.0.0 when compiling your app for iOS 17&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For any additional information please refer to the Nielsen global page: [[DCR and DTVR with iOS17 or TVOS17]].&lt;br /&gt;
&lt;br /&gt;
==== General  ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Xcode Development Environment''' &lt;br /&gt;
&amp;lt;/big&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK is compatible with Apple iOS versions 9.0 and above.&lt;br /&gt;
&lt;br /&gt;
The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': All communications between the SDK and the Census (Collection Facility) use HTTPS.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Importing Frameworks'''&amp;lt;/big&amp;gt;&lt;br /&gt;
The first step is to ensure that the following frameworks and libraries are imported into the Frameworks folder of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework uses several functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework &lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Example'''&lt;br /&gt;
* Extract “NielsenAppApi.Framework” from the Nielsen App SDK sample app and copy it to the Frameworks folder of the Xcode project.&lt;br /&gt;
* Add the code &amp;lt;code&amp;gt;-#import NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller’s header file.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Ensure that the following are included in the Linked Frameworks and Libraries list (located in the project’s Summary settings).&lt;br /&gt;
* Nielsen App SDK&lt;br /&gt;
* iOS security framework&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Swift'''&amp;lt;/big&amp;gt;&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;'''Using Objective-C'''&amp;lt;/big&amp;gt;&lt;br /&gt;
Add the code &lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Android  ===&lt;br /&gt;
==== General  ====&lt;br /&gt;
&amp;lt;big&amp;gt;&lt;br /&gt;
'''Configuring Android Java Development Environment'''&lt;br /&gt;
&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*The Nielsen App SDK (located in the ''com.nielsen.app.sdk'' package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
&lt;br /&gt;
'''Nielsen App SDK is compatible with Android OS versions 2.3+. Clients can control/configure the protocol to be used – HTTPS or HTTP to suit their needs.'''&lt;br /&gt;
&lt;br /&gt;
The Nielsen App SDK 1.2 library is composed of two parts:&lt;br /&gt;
* The Java AppSdk.jar library runs on the Android’s Dalvik Virtual Machine.&lt;br /&gt;
* The C/C++ libAppSdk.so native library that runs directly on the device’s hardware.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': App SDK 4.0.0 contains AppSDK.jar component only and does not support C/C++ libAppSdk.so components.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The requirement for the Java ''AppSdk.jar'' library and the ''libAppSdk.so'' native library will depend on the type of host application that will make use of them.&lt;br /&gt;
* '''For Video player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 3.0 and later will support it natively).&lt;br /&gt;
** If the player application uses a 3rd party media player implementing its own HLS, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
* '''For Audio player applications'''&lt;br /&gt;
** The Android OS hosting the App SDK should be at version 2.3 and later since the SDK depends on Google Play support to work properly.&lt;br /&gt;
Unzip the Nielsen App SDK sample app and copy the ''AppSdk.jar'' into the libs/ folder on the App’s Eclipse project. Copy the ''libAppSdk.so'' file under ''libs/armeabi/'' folder into the same Eclipse project.&lt;br /&gt;
* App SDK 1.2 provides support for x86, mips, and armeabi-7a architecture; the respective ''libAppSdk.so'' can be found under the ''libs/x86/'', ''libs/mips/'', and ''libs/armeabi-7a/'' folders.&lt;br /&gt;
Add the following permissions on the project’s ''AndroidManifest.xml'' file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For more details on handling runtime permissions in Android versions, please visit [https://developer.android.com/training/permissions/requesting.html].   Download the latest ''google-play-services_lib'' and include it in the App’s project in order to use the App SDK.&lt;br /&gt;
* App SDK checks to see if a Google service is available and updated.&lt;br /&gt;
* If unavailable or updated, App SDK will not use this service when executing its functions and will reference missing imports and the app will not be compiled.&lt;br /&gt;
To include the Google Play library in the media player project, copy the ''google-play-services_lib'' folder into the same location as the project&lt;br /&gt;
* Access '''File &amp;gt; Import'''.&lt;br /&gt;
* Select '''Existing Android Code into Workspace''' and click '''Next'''.&lt;br /&gt;
* Click '''Browse''' and navigate to the ''google-play-services_lib'' to include it into the projects.&lt;br /&gt;
* Select the exact '''Project Build Target''' for Eclipse to use from Android SDK.&lt;br /&gt;
** Android 4.4.2, etc. OR&lt;br /&gt;
** Edit ''project.properties'' file to point to Android target version e.g. target= android-19.&lt;br /&gt;
Once the google-play-services_lib is included into the App project, include the following code under the &amp;lt;code&amp;gt;&amp;lt;application&amp;gt;&amp;lt;/code&amp;gt; node in the &amp;lt;code&amp;gt;AndroidManifest.xml&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&amp;lt;meta-data android:name=&amp;quot;com.google.android.gms.version&amp;quot; android:value=&amp;quot;@integer/google_play_services_version&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, include the ''version.xml'' file that comes with the ''google-play-services_lib'' under the res/values directory of the media player project.&lt;br /&gt;
* Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt;'''Library'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nielsen App SDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
* google-play-services_lib&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Classes/package&amp;lt;/big&amp;gt;'''&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
==== Add the dependency &amp;quot;lifecycle-extensions&amp;quot; to your project  ====&lt;br /&gt;
Add the dependency &amp;quot;lifecycle-extensions&amp;quot; in the in the app gradle file as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will enable the AppSdk to detect the application UI visibility state transitions between background and foreground by utilizing the LifeCycleObserver. This is i.e. required for the Static Measurement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== SDK Initialization ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object, which can be used simultaneously without any issue. The sharedInstance API that creates a singleton object was deprecated before version 5.1.1. (Version 4.0 for Android)&lt;br /&gt;
&lt;br /&gt;
* A maximum of four SDK instances per appid are supported. When a fifth SDK instance is launched, the SDK will return “nil” from [[initWithAppInfo:delegate:]]&lt;br /&gt;
* When four SDK instances exist, you must destroy an old instance before creating a new one.&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
&lt;br /&gt;
* The appid is provided by the Nielsen Technical Account Manager (TAM). The appid is a GUID data type and is specific to the application.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || Client-defined || No || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || Client-defined || No || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| sfcode || Nielsen collection facility to which the SDK should connect.&lt;br /&gt;
'''AGF Clients'''&lt;br /&gt;
* &amp;quot;eu&amp;quot; (For Testing/Certification and in Production)&lt;br /&gt;
|| Nielsen-specified || ✓ || &amp;quot;eu&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Has to be set to &amp;quot;DEBUG&amp;quot; until certified&lt;br /&gt;
|| Nielsen-specified || Optional || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
=====  iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
    &lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======  Objective-C ======&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;    &lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject &lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====  Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&lt;br /&gt;
AppSDK is no longer a singleton object and should be initialized as below.&lt;br /&gt;
&lt;br /&gt;
'''Initialization of App SDK object through a JSON object'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here, &amp;lt;code&amp;gt;appContext&amp;lt;/code&amp;gt; is the App context object and &amp;lt;code&amp;gt;appSdkConfig&amp;lt;/code&amp;gt; is JSON object for holding the parameters (&amp;lt;code&amp;gt;appid&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;appname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sfcode&amp;lt;/code&amp;gt;) the App passes to the Nielsen App SDK via a JSON string. The appid is obtained from Nielsen operational support and is unique to the app.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The integration of Nielsen App SDK will depend on the type of client app.&amp;lt;br /&amp;gt;&lt;br /&gt;
* Ensure that SDK files (AppSdk.jar and libAppSdk.so [App SDK 1.2 Only]) are included under the App’s project and the App SDK is linked to the App (the setting to link App SDK to the App can be found on the property page of the App’s project).&lt;br /&gt;
&lt;br /&gt;
== APP SDK Error &amp;amp; Event Codes ==&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
== Configure Payload ==&lt;br /&gt;
=== Handling JSON Metadata ===&lt;br /&gt;
All the SDK methods handle only two types of objects: NSString, NSDictionary. The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of the unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** The error message will be logged if the string has an invalid JSON format.&lt;br /&gt;
* JSON value must be a string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, sfcode, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&lt;br /&gt;
&lt;br /&gt;
=== Configure ChannelInfo metadata === &lt;br /&gt;
==== Description of ChannelInfo metadata ====&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example ChannelInfo metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
       let channelInfo = [&lt;br /&gt;
            &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Configure Content metadata ===&lt;br /&gt;
&lt;br /&gt;
==== Description of Content metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example Content metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
let channelInfo = [&lt;br /&gt;
	&amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
];&lt;br /&gt;
        &lt;br /&gt;
let contentMetadata = [&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;88675545&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot;: &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;, &lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;88675545&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;3600&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c0&amp;quot;: &amp;quot;p0,1&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;88675545&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;program&amp;quot;, &amp;quot;Program Name&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;3600&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c0&amp;quot;, &amp;quot;p0,1&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c2&amp;quot;, &amp;quot;p2,Y&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c7&amp;quot;, &amp;quot;p7,videoid123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c9&amp;quot;, &amp;quot;p9,VideoTitle123&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Content&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c18&amp;quot;, &amp;quot;p18,N&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configure Ad Metadata ===&lt;br /&gt;
==== Description of Ad metadata ====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)|| custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example Ad metadata ====&lt;br /&gt;
===== iOS =====&lt;br /&gt;
====== Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt; &lt;br /&gt;
let adMetadata = [&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;ad345-67483&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ad_title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot;: &amp;quot;25&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
====== Objective-C ======&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt; &lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {@&amp;quot;type&amp;quot;: @&amp;quot;preroll&amp;quot;,&lt;br /&gt;
  @&amp;quot;assetid&amp;quot;: @&amp;quot;ad345-67483&amp;quot;&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot;: @&amp;quot;ad_title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot;: @&amp;quot;25&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c8&amp;quot;: &amp;quot;p8,&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c10&amp;quot;: &amp;quot;p10,clientname&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c11&amp;quot;: &amp;quot;p11,2352723141&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Werbung&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_c17&amp;quot;: &amp;quot;p17,preroll&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android =====&lt;br /&gt;
====== Java ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JSONObject adMetadata = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;type&amp;quot;, &amp;quot;preroll&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;assetid&amp;quot;, &amp;quot;ad345-67483&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;title&amp;quot;, &amp;quot;2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;length&amp;quot;, &amp;quot;25&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c8&amp;quot;, &amp;quot;p8,&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c10&amp;quot;, &amp;quot;p10,clientname&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c11&amp;quot;, &amp;quot;p11,2352723141&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c12&amp;quot;, &amp;quot;p12,Werbung&amp;quot;)&lt;br /&gt;
    .put(&amp;quot;nol_c17&amp;quot;, &amp;quot;p17,preroll&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
== Configure API Calls ==&lt;br /&gt;
=== Sample API Sequence ===&lt;br /&gt;
A Sample API sequence could follow this flow:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;[nielsenMeter play: channelName];&amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[nielsenMeter loadMetadata: contentMetadataObject];&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;[nielsenMeter playheadPosition: position];&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;[nielsenMeter end];&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Life cycle of SDK instance ===&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance processes playing information. [[play]] and [[loadMetadata]] calls move the SDK instance into this state. In this state, the SDK instance will be able to process the following calls.&lt;br /&gt;
## [[playheadPosition]] – Call this API every one second when playhead position timer is fired.&lt;br /&gt;
## [[stop]] – Call this API when the playback is paused, switches between content and ad (within the same content playback) or encounters interruptions.&lt;br /&gt;
## [[end]] – SDK instance exits from Processing state when this API is called.&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': In case of any interruptions during playback due to alarm, calendar, call, flight mode, Wi-Fi toggle, channel change, etc., call [[stop]] to pause the measurement.&lt;br /&gt;
* As soon as the playback resumes, call [[loadMetadata]] and  [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== API Call sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
'''[[#Example Content metadata|Example Content metadata]]'''&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the stream playback is interrupted or has ended.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Advertisements ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
'''[[#Example ChannelInfo metadata|Example ChannelInfo metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: ONLY for a preroll Ad , Call [[loadMetadata()]] for Content before calling it for preroll ad &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
'''[[#Example Ad metadata|Example Ad metadata]]'''&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until the Ad playback is interrupted or has ended for each single Ad. Playhead should be passed for the entire duration of ad pod, if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelName); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after the content is paused (ad starts)&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // App moves to background(midroll pauses) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // App moves to foreground (midroll resumes) &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // playheadPosition is position of the playhead while the midroll ad is being played &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content (Content resume) || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Always call stop irrespective of postroll is followed or not&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sequence of Calls ===&lt;br /&gt;
&lt;br /&gt;
=== play ===&lt;br /&gt;
Use [[play]] to pass the channel descriptor information through channelName parameter after the SDK has been initialized and the content starts playing. If the user is returning from a '''Pause/Stop''' interaction, call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;   - (void)play:(id)channelInfo;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;    public void play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;nielsenAppApi?.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== loadMetadata ===&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void)loadMetadata:(id)contentMetadata;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(contentMetadata)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== playheadPosition ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;playheadPosition&amp;quot; has to be called every second.&lt;br /&gt;
&lt;br /&gt;
* VOD : &lt;br /&gt;
** For Content and each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
*Live : &lt;br /&gt;
**For Content, pass the Unix timestamp (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... . &lt;br /&gt;
**For each single Ad, pass the current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3...&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
– (void) playheadPosition: (long long) playheadPos&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
AVPlayer *player;&lt;br /&gt;
CMTime curTime=[player currentTime];&lt;br /&gt;
int pos = CMTimeGetSeconds(curTime);&lt;br /&gt;
[nAppApiObject playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
        //Monitor the Playhead position of the AVPlayer&lt;br /&gt;
        let timeInterval: CMTime = CMTimeMakeWithSeconds(1.0,10)&lt;br /&gt;
        self.avPlayerViewController.player?.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) {(elapsedTime: CMTime) -&amp;gt; Void in&lt;br /&gt;
            if self.avPlayerViewController.player!.currentItem?.status == .readyToPlay {&lt;br /&gt;
                let time : Float64 = self.avPlayerViewController.player!.currentTime().seconds;&lt;br /&gt;
                let pos = Int64(time);&lt;br /&gt;
                NSLog(&amp;quot;New Elapse Time = \(time)&amp;quot;);&lt;br /&gt;
                self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void setPlayheadPosition(long position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== stop ===&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;– (void) stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== end ===&lt;br /&gt;
Call when the content asset completes playback. Stops measurement progress. &lt;br /&gt;
{{ExampleCode|&lt;br /&gt;
|Objective C = &amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;- (void) end;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Android = &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public void stop()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|Swift = &amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Interruptions during playback ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Call [[loadMetadata]] with the same metadata and continue sending [[playheadPosition]] once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending [[playheadPosition]] once the playback resumes (no [[loadMetadata]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional information:&lt;br /&gt;
* '''For type 'content': '''Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== App termination ===&lt;br /&gt;
If your app is executing a termination process and therefore ending the Content or Ad Playback, call [[end]] if the Content is playing or [[stop]] if an Ad is playing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
&lt;br /&gt;
The AppSDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen AppSDK measurement is utilizing a cookieless domain.&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
 &lt;br /&gt;
Please contact your Nielsen SDK support team directly for any related questions.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make one update to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
#* '''Example Production Initialization Call''' - Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;iOS Example:&amp;lt;/big&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
            &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;sfcode&amp;quot;: &amp;quot;eu&amp;quot;&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;big&amp;gt;Android Example:&amp;lt;/big&amp;gt;''' &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;  &lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;sfcode&amp;quot;, &amp;quot;eu&amp;quot;)&lt;br /&gt;
            // Remove Flag:   &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
mAppSdk = new AppSdk(appContext, appSdkConfig, appSdkListener);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e)&lt;br /&gt;
{&lt;br /&gt;
  Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live, you have to inform the Nielsen team - this is necessary because the Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7613</id>
		<title>DCR Germany Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7613"/>
		<updated>2026-04-02T11:44:00Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Ad metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK is the framework for browser developers to integrate Nielsen Measurement into their media player pages. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of pages like:&lt;br /&gt;
*Site launch events and how long page is viewed&lt;br /&gt;
*Time of viewing a sub-section / page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Please note:'''&lt;br /&gt;
The Browser SDK is intended to be used for native Browser implementations and cannot be used in a hybrid framework environment on Apps (Android, iOS) - e.g. for Cordova. Only native webview implementations may work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To get started, an AppID is needed. The AppID is a unique ID assigned to the player/site/app. This will be provided upon starting the integration from Nielsen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  apid: &amp;quot;XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot; // eg. PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* NLSQUEUE build v*/&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration files 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.&lt;br /&gt;
&lt;br /&gt;
===Create SDK Instance===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When creating an instance, pass the following three values:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/site ||	'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging. Only required for testing (not in production) || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;})&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example SDK Initialization ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on the apid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.eu.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Configuration ===&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique AppID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	// Add Static Queue Snippet&lt;br /&gt;
	!function(e,n){&lt;br /&gt;
		function t(e){&lt;br /&gt;
			return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
		}&lt;br /&gt;
		e[n]=e[n]||&lt;br /&gt;
		{&lt;br /&gt;
			nlsQ:function(o,r,c){&lt;br /&gt;
				var s=e.document,&lt;br /&gt;
				a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
				a.async=1,&lt;br /&gt;
				a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
				var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
				return i.parentNode.insertBefore(a,i),&lt;br /&gt;
				e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
				e[n][r]&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	// Created SDK Instance&lt;br /&gt;
	var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;, {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. Users will need to set up content and ad objects with the required Nielsen keys, as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Content Metadata ====&lt;br /&gt;
&lt;br /&gt;
===== Description of Content metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Example Content metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var content_metadata_object = {  &lt;br /&gt;
  type:     'content',&lt;br /&gt;
  assetid:  '88675545',&lt;br /&gt;
  program:  'Program Name',&lt;br /&gt;
  title:    'episode title',&lt;br /&gt;
  length:   '3600',&lt;br /&gt;
  nol_c0:  'p0,1',&lt;br /&gt;
  nol_c2:  'p2,Y',&lt;br /&gt;
  nol_c7:  'p7,videoid123',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c9:  'p9,VideoTitle123',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c12: 'p12,Content',&lt;br /&gt;
  nol_c18: 'p18,N'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ad Metadata ====&lt;br /&gt;
===== Description of Ad metadata =====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) &lt;br /&gt;
* Preroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Midroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
* Postroll: &amp;lt;c11&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Ad metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var ad_metadata_object = {  &lt;br /&gt;
  type:     'preroll',&lt;br /&gt;
  assetid:  'ad345-67483',&lt;br /&gt;
  title:    'ad_title',&lt;br /&gt;
  length:   '25',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c11: 'p11,2352723141',&lt;br /&gt;
  nol_c12: 'p12,Werbung',&lt;br /&gt;
  nol_c17: 'p17,preroll'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Pause Event ===&lt;br /&gt;
To indicate pause&lt;br /&gt;
&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Send '''loadMetadata''' with the same metadata and continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
&lt;br /&gt;
=== Other Interrupt Scenarios ===&lt;br /&gt;
The following possible browser interruption scenarios must be handled:&lt;br /&gt;
&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
&lt;br /&gt;
There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. midroll vs. content).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var stopped = false;&lt;br /&gt;
function closePlayer() {&lt;br /&gt;
	if (stopped) {return;}&lt;br /&gt;
	stopped = true;&lt;br /&gt;
	if (inMidroll) {    // Only inside a midroll indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
		nSdkInstance.ggPM('stop', playheadPositionMidroll);&lt;br /&gt;
	}&lt;br /&gt;
	nSdkInstance.ggPM('end', playheadPositionContent);    // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
};&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer or covering Safari on mobile browsers ... you may use &amp;quot;onpagehide&amp;quot; event as well).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Call Nielsen APIs ==&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad)&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
*&amp;quot;VOD (or ad ): || current position in seconds (integer) &amp;lt;br/&amp;gt;&lt;br /&gt;
*&amp;quot;Live: current UTC timestamp (seconds since January 1st 1970)&amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position in seconds	|| Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==  SDK Event Lifecycle ==&lt;br /&gt;
&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Examples|&lt;br /&gt;
without Ads|&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle without ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:even browser no ads.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example without ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);  // must be called as start of stream&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playheads every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|with Ads=&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle with ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:event browser.png|event browser.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example with ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); // must be called as start of stream (even if 1st asset is preroll)&lt;br /&gt;
 &lt;br /&gt;
// PREROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end pre-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 for the first segment (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
  &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end mid-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from where it left off before mid-roll (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); &lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// POSTROLL&lt;br /&gt;
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); // end post-roll stream&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
* 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.&lt;br /&gt;
&lt;br /&gt;
* after an 'end' in case there is a new content played, there is a need to have another 'loadmetadata' again.&lt;br /&gt;
&lt;br /&gt;
* For Ad, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&lt;br /&gt;
* For pre-roll ads you have to call the loadMetadata event for content at the start of stream and after the preroll&lt;br /&gt;
&lt;br /&gt;
* '''For type 'content' ''': Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
== Livestream ==&lt;br /&gt;
For '''Livestreams'''  please make sure playheadPosition is in UNIX-Timestamp for Content.&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
The Browser SDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Browser SDK measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make a couple of updates to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7612</id>
		<title>DCR Germany Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_Browser_SDK&amp;diff=7612"/>
		<updated>2026-04-02T11:42:19Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description of Content metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK is the framework for browser developers to integrate Nielsen Measurement into their media player pages. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings, Digital Content Ratings ([[DCR &amp;amp; DTVR]]), [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of pages like:&lt;br /&gt;
*Site launch events and how long page is viewed&lt;br /&gt;
*Time of viewing a sub-section / page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Please note:'''&lt;br /&gt;
The Browser SDK is intended to be used for native Browser implementations and cannot be used in a hybrid framework environment on Apps (Android, iOS) - e.g. for Cordova. Only native webview implementations may work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
To get started, an AppID is needed. The AppID is a unique ID assigned to the player/site/app. This will be provided upon starting the integration from Nielsen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  apid: &amp;quot;XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot; // eg. PDA7D5EE6-B1B8-XXXX-XXXX-2A788BCXXXCA&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-agf-v0.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-agf-ad-v0.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Static Queue Snippet ===&lt;br /&gt;
Add the following script tag to the website:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* NLSQUEUE build v*/&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The static queue snippet allows the SDK APIs to be called while the actual SDK and configuration files 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.&lt;br /&gt;
&lt;br /&gt;
===Create SDK Instance===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When creating an instance, pass the following three values:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/site ||	'PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging. Only required for testing (not in production) || &amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;})&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Example SDK Initialization ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;apid&amp;gt;.js, will be downloaded based on the apid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.eu.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
=== Example SDK Configuration ===&lt;br /&gt;
The configuration should include the Static Queue Snippet and an SDK Instance for an unique AppID as shown in the example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
	// Add Static Queue Snippet&lt;br /&gt;
	!function(e,n){&lt;br /&gt;
		function t(e){&lt;br /&gt;
			return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
		}&lt;br /&gt;
		e[n]=e[n]||&lt;br /&gt;
		{&lt;br /&gt;
			nlsQ:function(o,r,c){&lt;br /&gt;
				var s=e.document,&lt;br /&gt;
				a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
				a.async=1,&lt;br /&gt;
				a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
				var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
				return i.parentNode.insertBefore(a,i),&lt;br /&gt;
				e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
				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&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
				e[n][r]&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
	// Created SDK Instance&lt;br /&gt;
	var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;, {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata can be passed through key-values using the Nielsen reserved keys. Users will need to set up content and ad objects with the required Nielsen keys, as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Content Metadata ====&lt;br /&gt;
&lt;br /&gt;
===== Description of Content metadata =====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required/Obligatory&lt;br /&gt;
|-&lt;br /&gt;
| type || type of asset || &amp;lt;code&amp;gt;&amp;quot;content&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)&lt;br /&gt;
|| &lt;br /&gt;
* custom (no [[Special Characters]]) &lt;br /&gt;
* 24/7 livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Event livestream: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Video on demand: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
* Trailer: &amp;lt;c7_c0&amp;gt;&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| program ||(string) name of program (254 character limit) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| title ||(string) episode title (max 254 characters) || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| length || length of content in seconds || &amp;lt;code&amp;gt;seconds&amp;lt;/code&amp;gt; ('86400' for 24/7 Livestream. For Event-Livestreams planned length. For VoD video length) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided&amp;lt;br/&amp;gt;&lt;br /&gt;
App ID. In order to override the sub-brand configured to the App ID, value can &amp;lt;br/&amp;gt;&lt;br /&gt;
be passed here (e.g. multiple sub-brands in App)&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen	&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| nol_c0  || number of episode part (Sendungsteilenummer)              || number                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || page URL                     || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || Video ID                     || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || episode title                || custom - no backslash allowed in string (because of 3rd party data processing) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || type of asset                || 'Trailer' or 'Content'             || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c13 || custom variable              || custom ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c14 || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15 || format ID                    || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c18 || livestream                   || 'Y' or 'N' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c19 || custom variable              || custom                ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c20 || GfK-ID                     || custom                ||&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Example Content metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var content_metadata_object = {  &lt;br /&gt;
  type:     'content',&lt;br /&gt;
  assetid:  '88675545',&lt;br /&gt;
  program:  'Program Name',&lt;br /&gt;
  title:    'episode title',&lt;br /&gt;
  length:   '3600',&lt;br /&gt;
  nol_c0:  'p0,1',&lt;br /&gt;
  nol_c2:  'p2,Y',&lt;br /&gt;
  nol_c7:  'p7,videoid123',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c9:  'p9,VideoTitle123',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c12: 'p12,Content',&lt;br /&gt;
  nol_c18: 'p18,N'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ad Metadata ====&lt;br /&gt;
===== Description of Ad metadata =====&lt;br /&gt;
The ad metadata (if applicable) should be passed for each individual ad, if ads are available during or before the stream begins.&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type	|| type of ad	|| 'preroll', 'midroll', or 'postroll' ||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid || unique ID assigned to asset (64 character limit; only characters 0-9, a-z, A-Z underscore and minus are allowed - no special characters or vowel mutations)|| custom (no SPACE - no [https://engineeringportal.nielsen.com/docs/Special_Characters Special Characters]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand ID – value is automatically populated through provided App ID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands in App) || provided by Nielsen	||&lt;br /&gt;
|-&lt;br /&gt;
| title || only the AD-ID is necessary || custom, &amp;lt;AD-ID&amp;gt; without &amp;quot;VAST&amp;quot; Prefix or other, i.e.  '2352723141' ||	✓&lt;br /&gt;
|-	&lt;br /&gt;
| length || length of Ad in seconds || length of Ad in seconds || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c1 || universal AdID (Additional AD-ID to be used by second or third marketers) || custom, i.e. 'adgapid_022_800160_1601097_001_0_0' ||&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2  || web only                     || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)          || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c4 || form of advertising || 'preroll','midroll', 'postroll', 'pre-split', 'sponsor' ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c8  || not in use         		  || leave blank, reserved for AGF || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10 || publisher                    || custom                || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c11 || AD-ID (unique ID of an advertisement. Necessary if ads are being broadcasted) || custom, i.e. '2352723141' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c12 || content type (key distinction of content, advertising, and Trailer) || 'Werbung' ||  ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c16 || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads) || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes', etc ||	&lt;br /&gt;
|-&lt;br /&gt;
| nol_c17 || ad placement type (placement information of advertisement) || 'preroll', 'midroll', 'postroll' or 'other' ||	✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Ad metadata =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var ad_metadata_object = {  &lt;br /&gt;
  type:     'preroll',&lt;br /&gt;
  assetid:  'ad345-67483',&lt;br /&gt;
  title:    'ad_title',&lt;br /&gt;
  length:   '25',&lt;br /&gt;
  nol_c8:  'p8,',&lt;br /&gt;
  nol_c10: 'p10,clientname',&lt;br /&gt;
  nol_c11: 'p11,2352723141',&lt;br /&gt;
  nol_c12: 'p12,Werbung',&lt;br /&gt;
  nol_c17: 'p17,preroll'&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Pause Event ===&lt;br /&gt;
To indicate pause&lt;br /&gt;
&lt;br /&gt;
* Call [[stop]] immediately and withhold sending playhead position.&lt;br /&gt;
* '''For video content:'''&lt;br /&gt;
** Send '''loadMetadata''' with the same metadata and continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
* '''For ads:'''&lt;br /&gt;
** just continue sending '''setPlayheadPosition''' once the playback resumes.&lt;br /&gt;
&lt;br /&gt;
=== Other Interrupt Scenarios ===&lt;br /&gt;
The following possible browser interruption scenarios must be handled:&lt;br /&gt;
&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
&lt;br /&gt;
There are many cases where the player itself has the ability to detect such situations. If not, these interruption scenarios can be handled through JavaScript. The events that are called will depend on the asset being played (e.g. midroll vs. content).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var stopped = false;&lt;br /&gt;
function closePlayer() {&lt;br /&gt;
	if (stopped) {return;}&lt;br /&gt;
	stopped = true;&lt;br /&gt;
	if (inMidroll) {    // Only inside a midroll indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
		nSdkInstance.ggPM('stop', playheadPositionMidroll);&lt;br /&gt;
	}&lt;br /&gt;
	nSdkInstance.ggPM('end', playheadPositionContent);    // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
};&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
	closePlayer();   // call nielsensdk with end/stop&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' User may need to add code to support specific browser versions (e.g. older versions of Internet Explorer or covering Safari on mobile browsers ... you may use &amp;quot;onpagehide&amp;quot; event as well).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Call Nielsen APIs ==&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'	|| content/ad metadata object	|| Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad)&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
*&amp;quot;VOD (or ad ): || current position in seconds (integer) &amp;lt;br/&amp;gt;&lt;br /&gt;
*&amp;quot;Live: current UTC timestamp (seconds since January 1st 1970)&amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' ||	playhead position in seconds	|| Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
|-&lt;br /&gt;
| 'end'	|| playhead position in seconds	|| This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  nSdkInstance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==  SDK Event Lifecycle ==&lt;br /&gt;
&lt;br /&gt;
The sample event lifecycle can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Examples|&lt;br /&gt;
without Ads|&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle without ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:even browser no ads.png]]&lt;br /&gt;
&lt;br /&gt;
==== Example without ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);  // must be called as start of stream&lt;br /&gt;
&lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playheads every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|with Ads=&lt;br /&gt;
&lt;br /&gt;
==== Event Lifecycle with ads: ====&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:event browser.png|event browser.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example with ads: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject); // must be called as start of stream (even if 1st asset is preroll)&lt;br /&gt;
 &lt;br /&gt;
// PREROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', prerollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end pre-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0 for the first segment (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);&lt;br /&gt;
&lt;br /&gt;
// MIDROLL&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', midrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
  &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition);  // end mid-roll stream&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// CONTENT&lt;br /&gt;
nSdkInstance.ggPM('loadMetadata', contentMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition); // must be fired every second with playhead starting from where it left off before mid-roll (or with seconds since 1970-01-01 00:00:00 in case of livestream)&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); &lt;br /&gt;
nSdkInstance.ggPM('end', endPlayheadPosition);  // has to be called here at the end of the content&lt;br /&gt;
// endPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
 &lt;br /&gt;
// POSTROLL&lt;br /&gt;
nSdkInstance.ggPM('loadmetadata', postrollMetadataObject);&lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', playheadPosition);  // must be fired every second with playhead starting from 0&lt;br /&gt;
&lt;br /&gt;
... /*** pass playhead every second ***/&lt;br /&gt;
 &lt;br /&gt;
nSdkInstance.ggPM('setPlayheadPosition', lastPlayheadPosition); // end post-roll stream&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM('stop', stopPlayheadPosition);  // stopPlayheadPosition = lastPlayheadPosition&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
* 'setPlayheadPosition' is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling 'stop', 'end', or 'loadmetadata'.&lt;br /&gt;
&lt;br /&gt;
* after an 'end' in case there is a new content played, there is a need to have another 'loadmetadata' again.&lt;br /&gt;
&lt;br /&gt;
* For Ad, events must be called for each individual Ad. Each Ad playhead position should begin at ‘0’ when ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&lt;br /&gt;
* For pre-roll ads you have to call the loadMetadata event for content at the start of stream and after the preroll&lt;br /&gt;
&lt;br /&gt;
* '''For type 'content' ''': Sending a &amp;quot;loadMetadata&amp;quot; event after a &amp;quot;stop&amp;quot; event will be handled by the SDK as a &amp;quot;resume&amp;quot;, as long as the &amp;quot;assetid&amp;quot; and &amp;quot;type&amp;quot; are the same and not changed from the values before the &amp;quot;stop&amp;quot; event happened. Changing &amp;quot;assetid&amp;quot; value will lead into a new stream. Changing of &amp;quot;type&amp;quot; from &amp;quot;content&amp;quot; to &amp;quot;preroll&amp;quot; (&amp;quot;midroll&amp;quot;, &amp;quot;postroll&amp;quot;) will lead into a new object (ad) with that content stream. Changing any other parameter (eg. &amp;quot;program&amp;quot; or &amp;quot;title&amp;quot;) for the content will not affect the reported content data (will stay as in the very first &amp;quot;content&amp;quot; metadata)&lt;br /&gt;
&lt;br /&gt;
== Livestream ==&lt;br /&gt;
For '''Livestreams'''  please make sure playheadPosition is in UNIX-Timestamp for Content.&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
The Browser SDK measurement is working without cookies and other personal information. No user can be identified personally, therefore an opt-out functionality is not required. The Nielsen Browser SDK measurement is utilizing a cookieless domain.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research with anonymous data.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=de .&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, users need to make a couple of updates to the initialization call to ensure that the site is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;P14273221-CF5C-46BF-A832-994AEFB7XXXX&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7595</id>
		<title>DCR Sweden Domless SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7595"/>
		<updated>2026-03-18T10:54:50Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Nielsen SDK contains material that is protected by copyright laws, patent laws, trade secret laws, and by international treaty provisions and is Copyright © 2025 The Nielsen Company (US) LLC. All intellectual property rights and licenses therein are reserved by The Nielsen Company (US) LLC and its licensors. Please read the license agreement presented [https://engineeringportal.nielsen.com/wiki/Special:ClickThrough here], which must be accepted in order to download the Nielsen SDKs. For more information, reach out to your Nielsen Technical Account Manager(TAM).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK is a Javascript based cross-platform library that provides APIs that allows our clients to integrate the Nielsen SDK in DOM-less environments, e.g. ReactNative, NodeJS, etc. The new Amazon Vega/Kepler OS was certified by Nielsen for the DOM-less SDK Integration. &lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK can be used for '''Video''' and '''Static''' measurements.&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement on client mobile apps or webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more. This guide also includes a link to [[#Sample DOM-less SDK Implementation| github sample implementation]] with steps to implement the DCR Video product in a sample NodeJS app. It includes:&lt;br /&gt;
* DOM-less SDK Initialization&lt;br /&gt;
* DCR Video Metadata: information about the content being tracked&lt;br /&gt;
* DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
==DOM-less SDK Initialization==&lt;br /&gt;
&lt;br /&gt;
===Obtain the Nielsen Application ID (apid)===&lt;br /&gt;
The Nielsen &amp;lt;code&amp;gt;apid&amp;lt;/code&amp;gt; is required to enable SDK functionality. A Technical Account Manager(TAM) will provide an apid for each player configuration.DOM-less SDK can support URLs that use any of the protocols – HTTPS and HTTP.&lt;br /&gt;
&lt;br /&gt;
===Configure the DOM-less SDK===&lt;br /&gt;
&lt;br /&gt;
====Installation====&lt;br /&gt;
Install with &amp;lt;code&amp;gt;npm install &amp;lt;nowiki&amp;gt;https://github.com/NielsenDigitalSDK/bsdk-domless&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; and import the &amp;lt;code&amp;gt;BsdkInstance&amp;lt;/code&amp;gt; into video player component &amp;lt;code&amp;gt; import { BsdkInstance } from 'bsdk-domless' &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======status.ok()======&lt;br /&gt;
&lt;br /&gt;
Initialization of the instance can be done with &amp;lt;code&amp;gt;status.ok()&amp;lt;/code&amp;gt; function or use Promise handling approach&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = await new BsdkInstance(appID, instanceName, instanceMetadata, implementationHooks);&lt;br /&gt;
if (instance &amp;amp;&amp;amp; instance.status.ok()) {&lt;br /&gt;
      expect(instance).not.toBe(undefined);&lt;br /&gt;
      expect(instance.status.ok()).toBe(true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Implementation Hooks are mandatory for the DOM-less SDK instance. Please refer to the Implementation Hooks section below for details.&lt;br /&gt;
&lt;br /&gt;
====Exposed Interface====&lt;br /&gt;
The exposed interface is as follows:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;code&amp;gt;`ggPM`&amp;lt;/code&amp;gt; - method to send messages to the Nielsen SDK&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;code&amp;gt;`processEvent`&amp;lt;/code&amp;gt; - method to send app state to the Nielsen SDK, e.g., focus, blur, appclose&lt;br /&gt;
&lt;br /&gt;
===Initialization Global Parameters===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!'''Parameter'''&lt;br /&gt;
!'''Description'''&lt;br /&gt;
!'''Required'''&lt;br /&gt;
!'''Value'''&lt;br /&gt;
|-&lt;br /&gt;
|apid&lt;br /&gt;
|UniqueID assigned to player/site.&lt;br /&gt;
|Yes&lt;br /&gt;
|'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName&lt;br /&gt;
|Name of SDK instance&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|domlessEnv&lt;br /&gt;
|Type of DOM-less environment like ReactNative, Node, etc.&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;domlessEnv&amp;quot;: &amp;quot;1&amp;quot;, // For ReactNative&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;2&amp;quot;, // For Amazon&lt;br /&gt;
&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;3&amp;quot;, // For NodeJS&lt;br /&gt;
&lt;br /&gt;
“domlessEnv”: “4”, // For Custom&lt;br /&gt;
|-&lt;br /&gt;
|hem_unknown ||   Hashed email using SHA512. This email is used by the MMS reach model.|| Required if login feature ||  &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{hem_unknown: &amp;quot;924899b875ea6767ab790bd2f4852345fcfec5d203c49be8e8...&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|optout&lt;br /&gt;
|OptOut global parameter. This optout will be maintained through the session of the SDK instance&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid&lt;br /&gt;
|Optional:turn on or off the First Party ID&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|nol_sdkDebug&lt;br /&gt;
|Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementation Hooks ===&lt;br /&gt;
This object captures the required entities for the DOM-less SDK to operate correctly. These are normally platform dependent and are expected to be passed on to the DOM-less SDK as part of its initialization. See below for the descriptions of each key.&lt;br /&gt;
&lt;br /&gt;
==== '''log''' ====&lt;br /&gt;
Log the DOM-less SDK messages to an external stream, e.g. the browser console, stdout.&lt;br /&gt;
&lt;br /&gt;
e.g. Log.debug('debug', 'NIELSEN TAGS EXPECTED TO FIRE:')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;info()&lt;br /&gt;
&lt;br /&gt;
Log.info(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
debug()&lt;br /&gt;
&lt;br /&gt;
Log.debug(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
warn()&lt;br /&gt;
&lt;br /&gt;
Log.warn(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
error()&lt;br /&gt;
&lt;br /&gt;
Log.error(label: string, ...message: string[]): void&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;label Required&lt;br /&gt;
&lt;br /&gt;
● string - severity type, e.g. info, debug, warn, error or custom label&lt;br /&gt;
&lt;br /&gt;
message Required&lt;br /&gt;
&lt;br /&gt;
● string - message that will be output to the console&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== storage ====&lt;br /&gt;
Persistent storage of key/values, similar in behavior to browser localStorage.&lt;br /&gt;
&lt;br /&gt;
e.g. storage.set('nol_lsid', 'umy3w4ik9usw2ppqmw2vkecckxfob1697308388')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;set()&lt;br /&gt;
&lt;br /&gt;
storage.set(key: string, value: string)&lt;br /&gt;
&lt;br /&gt;
get()&lt;br /&gt;
&lt;br /&gt;
storage.get(key: string)&lt;br /&gt;
&lt;br /&gt;
remove()&lt;br /&gt;
&lt;br /&gt;
storage.remove(key: string)&lt;br /&gt;
&lt;br /&gt;
clear()&lt;br /&gt;
&lt;br /&gt;
storage.clear()&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== fetch ====&lt;br /&gt;
Function to fetch resources from the network. Required for the transmission of the DOM-less SDK requests (pings) to the Nielsen endpoints.&lt;br /&gt;
&lt;br /&gt;
e.g. Fetch(resource: string, options: object)&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;resource Required&lt;br /&gt;
&lt;br /&gt;
● A string that provides the URL of the resource to fetch&lt;br /&gt;
&lt;br /&gt;
options Optional Object containing settings to apply to the request:&lt;br /&gt;
&lt;br /&gt;
method&lt;br /&gt;
&lt;br /&gt;
● string - request method: &amp;quot;GET&amp;quot;, &amp;quot;POST&amp;quot;. If one is not provided SDK will default to &amp;quot;GET&amp;quot;&lt;br /&gt;
&lt;br /&gt;
headers&lt;br /&gt;
&lt;br /&gt;
● object - headers to add to the outgoing request, an object literal with String values&lt;br /&gt;
&lt;br /&gt;
body&lt;br /&gt;
&lt;br /&gt;
● string - body to add to the request; SDK will send out string&lt;br /&gt;
&lt;br /&gt;
mode&lt;br /&gt;
&lt;br /&gt;
● string - mode for request: cors, no-cors, same-origin&lt;br /&gt;
&lt;br /&gt;
referrer&lt;br /&gt;
&lt;br /&gt;
● string - a string specifying the referrer of the request&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====='''''&amp;lt;pre style=&amp;quot;color: green; font-weight: bold; font-size: 20px&amp;quot;&amp;gt;Note: Implementation Hooks are mandatory for the DOM-less SDK to function as expected.&amp;lt;/pre&amp;gt;'''''=====&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send app state to the Nielsen SDK, e.g., focus, blur, appclose==&lt;br /&gt;
&lt;br /&gt;
The method for calling events is &amp;lt;code&amp;gt;processEvent()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`blur`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the background.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'blur', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`focus`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the foreground.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'focus', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`appclose`&amp;lt;/code&amp;gt; - This event should be passed prior to closing the app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'appclose', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send messages to the Nielsen SDK==&lt;br /&gt;
&lt;br /&gt;
=== Video Measurement ===&lt;br /&gt;
&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description !!Event #&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'  || content/ad metadata object || Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad). ''[[DCR Sweden Video Browser SDK#Create Metadata Objects|See details on how to create MMS metadata for content and ad]]''&lt;br /&gt;
||15&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
||49&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' || playhead position in seconds  || Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
||7&lt;br /&gt;
|-&lt;br /&gt;
| 'end' || playhead position in seconds || This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
||57&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample DOM-less SDK Implementation ====&lt;br /&gt;
&lt;br /&gt;
* Sample Implementation on github [https://github.com/NielsenDigitalSDK/bsdk-domless here].&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Integration Architecture Diagram ====&lt;br /&gt;
&lt;br /&gt;
===== For Content Playback =====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
===== For Ad Playback =====&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Interrupt Scenarios ====&lt;br /&gt;
* [[DCR Sweden Video Browser SDK#Handle Video Playback Interruption|Handle Video Playback Interruption]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Event Lifecycle ====&lt;br /&gt;
* [[DCR Sweden Video Browser SDK#SDK Call Sequence |SDK Call Sequence ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out  ==&lt;br /&gt;
&lt;br /&gt;
The site must provide a means for the user to opt-out of, or opt back into, Nielsen Measurement. Users can opt out if they 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.&lt;br /&gt;
*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).&lt;br /&gt;
*A link to the Nielsen Digital Measurement Privacy Policy at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=sv (or for English: https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=en-se)&lt;br /&gt;
*We have two separate entities registered with the IAB TCF, Nielsen Marketing Cloud and Nielsen LLC.  The one that is relevant to Swedish measurement is Nielsen LLC (ID: 812) and not NMC. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
* Once users have opted out via this [https://priv-policy.imrworldwide.com/priv/browser/cookie-policy.html?optout=1 link], their browser cookies will contain the value '''TOTAL_OPTOUT'''. This will prevent a redirect to our data provider from occurring&lt;br /&gt;
* Users can opt back in via this [https://priv-policy.imrworldwide.com/priv/browser/cookie-policy.html?optout=0 link].  When a user selects that link, their opt-out cookie will be deleted and they will be able to be measured moving forward.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following paragraph is a template for a Privacy Statement.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The properties may feature Nielsen proprietary measurement software, allowing 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 concerning it, please see the Nielsen Digital Measurement Privacy Policy at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=sv&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== User Opt Back In ====&lt;br /&gt;
Once users have opted-out, they can choose to opt back into Nielsen Measurement at any time 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.&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initializazion ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). See [[#Initialization Global Parameters|SDK Initialization Global Parameters]].&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The optout Flag is set by default to &amp;quot;false&amp;quot; in the Browser SDK. For Opt-out users, the optout Flag can be set to &amp;quot;true&amp;quot; during the initialization of the SDK Instance, i.e. the parameter optout can be set to &amp;quot;true&amp;quot; (opted out) or &amp;quot;false&amp;quot; (opted in or NOT opted out). See [[#Initialization Global Parameters|SDK Initialization Global Parameters]].&lt;br /&gt;
&lt;br /&gt;
== Certification ==&lt;br /&gt;
&lt;br /&gt;
While Nielsen is working on adding Support to the Certification Tool for DOM-less SDK in the future, the Certification process for the DOM-less will require detailed SDK Logs from a MMS Client integrating Nielsen DOM-less SDK. In this regard, a client will execute test cases locally and share logs for each test case with a Nielsen Technical Account Manager in charge of the Certification. &lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, disable Nielsen SDK logging by adjusting the Nielsen SDK Initialization Call, this will ensure that the App or Website is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = new BsdkInstance(&lt;br /&gt;
        nsdkConfig.app_id,&lt;br /&gt;
        nsdkConfig.instance_name,&lt;br /&gt;
        {&lt;br /&gt;
            appName: 'BSDK RN Sample App',&lt;br /&gt;
            domlessEnv: '1'// &amp;quot;1&amp;quot; for React Native | &amp;quot;2&amp;quot; for Amazon | &amp;quot;3&amp;quot; for NodeJS | &amp;quot;4&amp;quot; for Custom&lt;br /&gt;
            // reference SDK interface documentation&lt;br /&gt;
            // for additional metadata properties&lt;br /&gt;
        },&lt;br /&gt;
    implementationHooks&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7594</id>
		<title>DCR Sweden Domless SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7594"/>
		<updated>2026-03-18T10:54:25Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: first Version uploaded&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
Nielsen SDK contains material that is protected by copyright laws, patent laws, trade secret laws, and by international treaty provisions and is Copyright © 2025 The Nielsen Company (US) LLC. All intellectual property rights and licenses therein are reserved by The Nielsen Company (US) LLC and its licensors. Please read the license agreement presented [https://engineeringportal.nielsen.com/wiki/Special:ClickThrough here], which must be accepted in order to download the Nielsen SDKs. For more information, reach out to your Nielsen Technical Account Manager(TAM).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK is a Javascript based cross-platform library that provides APIs that allows our clients to integrate the Nielsen SDK in DOM-less environments, e.g. ReactNative, NodeJS, etc. The new Amazon Vega/Kepler OS was certified by Nielsen for the DOM-less SDK Integration. &lt;br /&gt;
&lt;br /&gt;
The Nielsen DOM-less SDK can be used for '''Video''' and '''Static''' measurements.&lt;br /&gt;
&lt;br /&gt;
The Digital Content Ratings (DCR) Video product provides content consumption measurement on client mobile apps or webpages. This measurement includes insight into the total time a user spent watching the tracked content, video player events, and much more. This guide also includes a link to [[#Sample DOM-less SDK Implementation| github sample implementation]] with steps to implement the DCR Video product in a sample NodeJS app. It includes:&lt;br /&gt;
* DOM-less SDK Initialization&lt;br /&gt;
* DCR Video Metadata: information about the content being tracked&lt;br /&gt;
* DCR Video Events/API calls&lt;br /&gt;
&lt;br /&gt;
==DOM-less SDK Initialization==&lt;br /&gt;
&lt;br /&gt;
===Obtain the Nielsen Application ID (apid)===&lt;br /&gt;
The Nielsen &amp;lt;code&amp;gt;apid&amp;lt;/code&amp;gt; is required to enable SDK functionality. A Technical Account Manager(TAM) will provide an apid for each player configuration.DOM-less SDK can support URLs that use any of the protocols – HTTPS and HTTP.&lt;br /&gt;
&lt;br /&gt;
===Configure the DOM-less SDK===&lt;br /&gt;
&lt;br /&gt;
====Installation====&lt;br /&gt;
Install with &amp;lt;code&amp;gt;npm install &amp;lt;nowiki&amp;gt;https://github.com/NielsenDigitalSDK/bsdk-domless&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; and import the &amp;lt;code&amp;gt;BsdkInstance&amp;lt;/code&amp;gt; into video player component &amp;lt;code&amp;gt; import { BsdkInstance } from 'bsdk-domless' &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======status.ok()======&lt;br /&gt;
&lt;br /&gt;
Initialization of the instance can be done with &amp;lt;code&amp;gt;status.ok()&amp;lt;/code&amp;gt; function or use Promise handling approach&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = await new BsdkInstance(appID, instanceName, instanceMetadata, implementationHooks);&lt;br /&gt;
if (instance &amp;amp;&amp;amp; instance.status.ok()) {&lt;br /&gt;
      expect(instance).not.toBe(undefined);&lt;br /&gt;
      expect(instance.status.ok()).toBe(true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Implementation Hooks are mandatory for the DOM-less SDK instance. Please refer to the Implementation Hooks section below for details.&lt;br /&gt;
&lt;br /&gt;
====Exposed Interface====&lt;br /&gt;
The exposed interface is as follows:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;code&amp;gt;`ggPM`&amp;lt;/code&amp;gt; - method to send messages to the Nielsen SDK&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;code&amp;gt;`processEvent`&amp;lt;/code&amp;gt; - method to send app state to the Nielsen SDK, e.g., focus, blur, appclose&lt;br /&gt;
&lt;br /&gt;
===Initialization Global Parameters===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!'''Parameter'''&lt;br /&gt;
!'''Description'''&lt;br /&gt;
!'''Required'''&lt;br /&gt;
!'''Value'''&lt;br /&gt;
|-&lt;br /&gt;
|apid&lt;br /&gt;
|UniqueID assigned to player/site.&lt;br /&gt;
|Yes&lt;br /&gt;
|'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'&lt;br /&gt;
|-&lt;br /&gt;
|instanceName&lt;br /&gt;
|Name of SDK instance&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|domlessEnv&lt;br /&gt;
|Type of DOM-less environment like ReactNative, Node, etc.&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;domlessEnv&amp;quot;: &amp;quot;1&amp;quot;, // For ReactNative&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;2&amp;quot;, // For Amazon&lt;br /&gt;
&lt;br /&gt;
&amp;quot;domlessEnv&amp;quot;: &amp;quot;3&amp;quot;, // For NodeJS&lt;br /&gt;
&lt;br /&gt;
“domlessEnv”: “4”, // For Custom&lt;br /&gt;
|-&lt;br /&gt;
|hem_unknown ||   Hashed email using SHA512. This email is used by the MMS reach model.|| Required if login feature ||  &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{hem_unknown: &amp;quot;924899b875ea6767ab790bd2f4852345fcfec5d203c49be8e8...&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|optout&lt;br /&gt;
|OptOut global parameter. This optout will be maintained through the session of the SDK instance&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid&lt;br /&gt;
|Optional:turn on or off the First Party ID&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|nol_sdkDebug&lt;br /&gt;
|Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;{nol_sdkDebug: &amp;quot;debug&amp;quot;}&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Implementation Hooks ===&lt;br /&gt;
This object captures the required entities for the DOM-less SDK to operate correctly. These are normally platform dependent and are expected to be passed on to the DOM-less SDK as part of its initialization. See below for the descriptions of each key.&lt;br /&gt;
&lt;br /&gt;
==== '''log''' ====&lt;br /&gt;
Log the DOM-less SDK messages to an external stream, e.g. the browser console, stdout.&lt;br /&gt;
&lt;br /&gt;
e.g. Log.debug('debug', 'NIELSEN TAGS EXPECTED TO FIRE:')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;info()&lt;br /&gt;
&lt;br /&gt;
Log.info(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
debug()&lt;br /&gt;
&lt;br /&gt;
Log.debug(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
warn()&lt;br /&gt;
&lt;br /&gt;
Log.warn(label: string, ...message: string[]): void&lt;br /&gt;
&lt;br /&gt;
error()&lt;br /&gt;
&lt;br /&gt;
Log.error(label: string, ...message: string[]): void&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;label Required&lt;br /&gt;
&lt;br /&gt;
● string - severity type, e.g. info, debug, warn, error or custom label&lt;br /&gt;
&lt;br /&gt;
message Required&lt;br /&gt;
&lt;br /&gt;
● string - message that will be output to the console&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== storage ====&lt;br /&gt;
Persistent storage of key/values, similar in behavior to browser localStorage.&lt;br /&gt;
&lt;br /&gt;
e.g. storage.set('nol_lsid', 'umy3w4ik9usw2ppqmw2vkecckxfob1697308388')&lt;br /&gt;
&lt;br /&gt;
===== Methods =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;set()&lt;br /&gt;
&lt;br /&gt;
storage.set(key: string, value: string)&lt;br /&gt;
&lt;br /&gt;
get()&lt;br /&gt;
&lt;br /&gt;
storage.get(key: string)&lt;br /&gt;
&lt;br /&gt;
remove()&lt;br /&gt;
&lt;br /&gt;
storage.remove(key: string)&lt;br /&gt;
&lt;br /&gt;
clear()&lt;br /&gt;
&lt;br /&gt;
storage.clear()&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== fetch ====&lt;br /&gt;
Function to fetch resources from the network. Required for the transmission of the DOM-less SDK requests (pings) to the Nielsen endpoints.&lt;br /&gt;
&lt;br /&gt;
e.g. Fetch(resource: string, options: object)&lt;br /&gt;
&lt;br /&gt;
===== Parameters =====&lt;br /&gt;
&amp;lt;blockquote&amp;gt;resource Required&lt;br /&gt;
&lt;br /&gt;
● A string that provides the URL of the resource to fetch&lt;br /&gt;
&lt;br /&gt;
options Optional Object containing settings to apply to the request:&lt;br /&gt;
&lt;br /&gt;
method&lt;br /&gt;
&lt;br /&gt;
● string - request method: &amp;quot;GET&amp;quot;, &amp;quot;POST&amp;quot;. If one is not provided SDK will default to &amp;quot;GET&amp;quot;&lt;br /&gt;
&lt;br /&gt;
headers&lt;br /&gt;
&lt;br /&gt;
● object - headers to add to the outgoing request, an object literal with String values&lt;br /&gt;
&lt;br /&gt;
body&lt;br /&gt;
&lt;br /&gt;
● string - body to add to the request; SDK will send out string&lt;br /&gt;
&lt;br /&gt;
mode&lt;br /&gt;
&lt;br /&gt;
● string - mode for request: cors, no-cors, same-origin&lt;br /&gt;
&lt;br /&gt;
referrer&lt;br /&gt;
&lt;br /&gt;
● string - a string specifying the referrer of the request&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====='''''&amp;lt;pre style=&amp;quot;color: green; font-weight: bold; font-size: 20px&amp;quot;&amp;gt;Note: Implementation Hooks are mandatory for the DOM-less SDK to function as expected.&amp;lt;/pre&amp;gt;'''''=====&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send app state to the Nielsen SDK, e.g., focus, blur, appclose==&lt;br /&gt;
&lt;br /&gt;
The method for calling events is &amp;lt;code&amp;gt;processEvent()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`blur`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the background.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'blur', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`focus`&amp;lt;/code&amp;gt; - This event should be passed to processEvent when the app goes to the foreground.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'focus', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;`appclose`&amp;lt;/code&amp;gt; - This event should be passed prior to closing the app.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.processEvent({ type: 'appclose', timestamp: Date.now() });&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DOM-less SDK API to send messages to the Nielsen SDK==&lt;br /&gt;
&lt;br /&gt;
=== Video Measurement ===&lt;br /&gt;
&lt;br /&gt;
The method for calling events is ggPM().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
instance.ggPM('event', parameter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
The events are included in the table below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event name !! Values to pass !!  Description !!Event #&lt;br /&gt;
|-&lt;br /&gt;
| 'loadMetadata'  || content/ad metadata object || Needs to be called at the beginning of each content/ad metadata object and after stop event when resuming '''video content''' (not after pausing and resuming an ad). ''[[DCR Sweden Video Browser SDK#Create Metadata Objects|See details on how to create MMS metadata for content and ad]]''&lt;br /&gt;
||15&lt;br /&gt;
|-&lt;br /&gt;
| 'setPlayheadPosition'&lt;br /&gt;
||&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback&lt;br /&gt;
||49&lt;br /&gt;
|-&lt;br /&gt;
| 'stop' || playhead position in seconds  || Call when ads complete playing and on pause event (when resume will be available). The playhead position must be passed when calling stop&lt;br /&gt;
||7&lt;br /&gt;
|-&lt;br /&gt;
| 'end' || playhead position in seconds || This event has to be called once for the current video asset at the end of the playback.&lt;br /&gt;
At the end of the content stream, if the user switches to another piece of content or when the browser is refreshed or closed.&lt;br /&gt;
||57&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Playhead position as integer&lt;br /&gt;
&lt;br /&gt;
'''Note:''' 'setPlayheadPosition' has to be called every second&lt;br /&gt;
&lt;br /&gt;
==== Example Events ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass ( Object ):''' Content Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', contentMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' loadMetadata  |  '''Value Pass  ( Object ):''' Pre-roll AD Metadata Object&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('loadMetadata', prerollMetadataObject); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' setPlayheadPosition  |  '''Value Pass ( Integer ):''' playheadPosition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('setPlayheadPosition', playheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' stop  |  '''Value Pass ( Integer ):''' stopPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('stop', stopPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Event:''' end  |  '''Value Pass ( Integer ):''' endPlayheadPosition &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  instance.ggPM('end', endPlayheadPosition); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample DOM-less SDK Implementation ====&lt;br /&gt;
&lt;br /&gt;
* Sample Implementation on github [https://github.com/NielsenDigitalSDK/bsdk-domless here].&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Integration Architecture Diagram ====&lt;br /&gt;
&lt;br /&gt;
===== For Content Playback =====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
===== For Ad Playback =====&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Interrupt Scenarios ====&lt;br /&gt;
* [[DCR Sweden Video Browser SDK#Handle Video Playback Interruption|Handle Video Playback Interruption]]&lt;br /&gt;
&lt;br /&gt;
==== Review SDK Event Lifecycle ====&lt;br /&gt;
* [[DCR Sweden Video Browser SDK#SDK Call Sequence |SDK Call Sequence ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out  ==&lt;br /&gt;
&lt;br /&gt;
The site must provide a means for the user to opt-out of, or opt back into, Nielsen Measurement. Users can opt out if they 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.&lt;br /&gt;
*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).&lt;br /&gt;
*A link to the Nielsen Digital Measurement Privacy Policy at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=sv (or for English: https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=en-se)&lt;br /&gt;
*We have two separate entities registered with the IAB TCF, Nielsen Marketing Cloud and Nielsen LLC.  The one that is relevant to Swedish measurement is Nielsen LLC (ID: 812) and not NMC. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
* Once users have opted out via this [https://priv-policy.imrworldwide.com/priv/browser/cookie-policy.html?optout=1 link], their browser cookies will contain the value '''TOTAL_OPTOUT'''. This will prevent a redirect to our data provider from occurring&lt;br /&gt;
* Users can opt back in via this [https://priv-policy.imrworldwide.com/priv/browser/cookie-policy.html?optout=0 link].  When a user selects that link, their opt-out cookie will be deleted and they will be able to be measured moving forward.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The following paragraph is a template for a Privacy Statement.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The properties may feature Nielsen proprietary measurement software, allowing 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 concerning it, please see the Nielsen Digital Measurement Privacy Policy at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=sv&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== User Opt Back In ====&lt;br /&gt;
Once users have opted-out, they can choose to opt back into Nielsen Measurement at any time 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.&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initializazion ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). See [[#Initialization Global Parameters|SDK Initialization Global Parameters]].&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The optout Flag is set by default to &amp;quot;false&amp;quot; in the Browser SDK. For Opt-out users, the optout Flag can be set to &amp;quot;true&amp;quot; during the initialization of the SDK Instance, i.e. the parameter Optout can be set to &amp;quot;true&amp;quot; (opted out) or &amp;quot;false&amp;quot; (opted in or NOT opted out). See [[#Initialization Global Parameters|SDK Initialization Global Parameters]].&lt;br /&gt;
&lt;br /&gt;
== Certification ==&lt;br /&gt;
&lt;br /&gt;
While Nielsen is working on adding Support to the Certification Tool for DOM-less SDK in the future, the Certification process for the DOM-less will require detailed SDK Logs from a MMS Client integrating Nielsen DOM-less SDK. In this regard, a client will execute test cases locally and share logs for each test case with a Nielsen Technical Account Manager in charge of the Certification. &lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
Following Nielsen testing, disable Nielsen SDK logging by adjusting the Nielsen SDK Initialization Call, this will ensure that the App or Website is being measured properly.&lt;br /&gt;
# '''Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'debug'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
&lt;br /&gt;
====Example Production Initialization Call ====&lt;br /&gt;
Refer to the production initialization call below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
const instance = new BsdkInstance(&lt;br /&gt;
        nsdkConfig.app_id,&lt;br /&gt;
        nsdkConfig.instance_name,&lt;br /&gt;
        {&lt;br /&gt;
            appName: 'BSDK RN Sample App',&lt;br /&gt;
            domlessEnv: '1'// &amp;quot;1&amp;quot; for React Native | &amp;quot;2&amp;quot; for Amazon | &amp;quot;3&amp;quot; for NodeJS | &amp;quot;4&amp;quot; for Custom&lt;br /&gt;
            // reference SDK interface documentation&lt;br /&gt;
            // for additional metadata properties&lt;br /&gt;
        },&lt;br /&gt;
    implementationHooks&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note''': before going live you have to inform Nielsen - this is necessary, because Nielsen team has to adjust internal configuration parameters to enable data collection. Without that notification, no data will be collected, and no data will be reported.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Browser_SDK&amp;diff=7593</id>
		<title>DCR France Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Browser_SDK&amp;diff=7593"/>
		<updated>2026-03-18T10:52:53Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK (BSDK) is the framework for browser application developers to integrate Nielsen Measurement into their media players. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]) and Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]). Nielsen SDKs are also equipped to measure static content and can track key life cycle events.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Review SDK Integration Architecture Diagram ===&lt;br /&gt;
&lt;br /&gt;
==== For Content Playback ====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Add Static Queue Snippet ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following script tag to the website i.e. within the &amp;lt;head&amp;gt;&amp;lt;/head&amp;gt; tag :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      trackEvent:function(o){e[n][r].te=e[n][r].te||[];try{var c=t(o);e[n][r].te.push(c)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create SDK Instance ===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For creating an instance, pass the following values: (&amp;lt;code&amp;gt;nol_sdkDebug&amp;lt;/code&amp;gt; is optional)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Source !! Required !! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/website || Nielsen-specified || ✓  ||	&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance || Nielsen-specified || ✓ ||	&amp;quot;any string value&amp;quot; i.e. &amp;quot;TVnamevideoSdkInstance&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || ||	 i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified ||  || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging if desired. || Nielsen-specified || 	|| &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{nol_sdkDebug: &amp;quot;debug&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;appid&amp;gt;.js, will be downloaded based on the appid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Call ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
    hem_sha1: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    uid2: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    hem_sha256: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    optout: &amp;quot;false&amp;quot;,&lt;br /&gt;
    enableFpid: &amp;quot;true&amp;quot;,&lt;br /&gt;
    nol_sdkDebug: &amp;quot;debug&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
Before starting any measurement of an asset with the created SDK Instance, you need to create an asset metadata object in order to identify the asset. &lt;br /&gt;
There are two types of asset metadata but only one is used for Mediametrie:&lt;br /&gt;
*content: identify a video&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata are passed through key-values using the Nielsen reserved keys. You will need to set up content object with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Create Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; URL Character Limit: There is a URL character limit of 2K characters due to browser limitations. Exceeding this value could impair data delivery on particular browsers. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
Nielsen APIs calls are made by calling the function ggPM(&amp;quot;event&amp;quot;, parameter, ...) with &amp;quot;event&amp;quot; Parameter indicating the SDK API.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;event&amp;quot;, parameter, ...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;loadMetadata&amp;quot;	|| content metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;setPlayheadPosition&amp;quot;	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback, the value passed should match the broadcast time for live channel.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;stop&amp;quot; ||	playhead position in seconds	|| Call when content interrupted/paused and stop passing playhead position. Do the same also when an Ad Break starts during the Content Playback.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;end&amp;quot;	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the measurement by calling the &amp;quot;event&amp;quot; names &amp;quot;loadMetadata&amp;quot; followed by &amp;quot;setPlayheadPosition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM  (main content)&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stop and Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
&lt;br /&gt;
=== Handle Video Playback Interruption ===&lt;br /&gt;
The setPlayheadPostion event is used for handling playback interruption. To indicate that the video player is not playing (i.e. paused, buffering), stop passing the playhead position to the SDK. &lt;br /&gt;
Once the Playback resumes , begin sending the playhead position again with the correct playhead value.&lt;br /&gt;
&lt;br /&gt;
=== List of video Playback Interruptions ===&lt;br /&gt;
The following possible  video Playback Interruptions must be handled:&lt;br /&gt;
* Player PAUSED&lt;br /&gt;
* Player BUFFERING&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
* Network Loss&lt;br /&gt;
&lt;br /&gt;
=== Example for handling Playback Interruption: Browser/Tab close/Page Reload ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function(event) &lt;br /&gt;
{ &lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' additional code may be  needed in order to support specific browser versions (e.g. older versions of Internet Explorer).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK Call Sequence ==&lt;br /&gt;
The sample event lifecycles can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
=== Content Playback Call Sequence ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
//&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
* &amp;quot;setPlayheadPosition&amp;quot; is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling &amp;quot;stop&amp;quot; or &amp;quot;end&amp;quot;.&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. &lt;br /&gt;
* The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion) that should be ignored since No Ads are measured in France.&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;br&amp;gt;	&lt;br /&gt;
Make sure the country &amp;quot;France&amp;quot; is selected in the country dropdown list.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for Mediametrie [https://nielsenonlinesupport.com/mediametrie/sdkRefImpl/index.htm sdkRefImpl].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen SDK Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The Browser SDK video measurement does not set cross-domain cookies, therefore no centralized opt-out functionality is available. The Nielsen Browser SDK does not set cookies associated with the collection domain. The SDK sets specific cookie for the domain where the player is hosted (first party) and this cookie is not used across websites.&lt;br /&gt;
The only personal information collected with the SDK network pings is the IP address, which is  anonymized immediately after collection.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with enableFpid =====&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned on ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	enableFpid: &amp;quot;true&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned off ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	enableFpid: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The optout Flag is set by default to &amp;quot;false&amp;quot; in the Browser SDK. For Opt-out users, the optout Flag can be set to &amp;quot;true&amp;quot; during the initialization of the SDK Instance, i.e. the parameter optout can be set to &amp;quot;true&amp;quot; (opted out) or &amp;quot;false&amp;quot; (opted in or NOT opted out). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with the Ouptout Flag =====&lt;br /&gt;
&lt;br /&gt;
====== User opted out ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
    optout: &amp;quot;true&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== User opted in ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	optout: &amp;quot;false&amp;quot; &lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Run your player in the Browser, start a video&amp;lt;br /&amp;gt;&lt;br /&gt;
2. Open the Developer Network View in order to monitor network traffic&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Filter the network traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=xknspa6p3viv2medizzvw8tld2smg1682583576&amp;amp;fp_cr_tm=1682583576685&amp;amp;fp_acc_tm=1684322226258&amp;amp;fp_emm_tm=1684322226288&amp;amp;ve_id=&amp;amp;sessionId=c81tzsiqvhqm6zswkeftmjjyip3fe1684322243&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc,c77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20FR&amp;amp;c13=asid,P1D11AF9D-E3FE-438C-B861-ED47543FF0E2&amp;amp;c32=segA,NA&amp;amp;c33=segB,NA&amp;amp;c34=segC,NA&amp;amp;c15=apn,&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_D1_00000&amp;amp;c9=devid,&amp;amp;enc=true&amp;amp;c1=nuid,999&amp;amp;at=timer&amp;amp;rt=video&amp;amp;c16=sdkv,bj.6.0.0&amp;amp;c27=cln,6&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid,16843222430632178&amp;amp;c30=bldv,6.0.0.662&amp;amp;st=dcr&amp;amp;c7=osgrp,&amp;amp;c8=devgrp,&amp;amp;c10=plt,&amp;amp;c40=adbid,&amp;amp;c14=osver,NA&amp;amp;c26=dmap,1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid,&amp;amp;c36=cref1,&amp;amp;c37=cref2,&amp;amp;c11=agg,1&amp;amp;c12=apv,&amp;amp;c51=adl,15&amp;amp;c52=noad,0&amp;amp;sd=170&amp;amp;pc=NA&amp;amp;c53=fef,y&amp;amp;c54=oad,20200713%2010%3A22%3A00&amp;amp;c55=cref3,&amp;amp;c57=adldf,2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st,c&amp;amp;c64=starttm,1684322269&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive,false&amp;amp;c59=sesid,3dn2br9l4y9rr2iuxycsdnlh3zwvd1684322245&amp;amp;c61=createtm,1684322275&amp;amp;c63=pipMode,&amp;amp;c68=bndlid,&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype,&amp;amp;c74=dvcnm,&amp;amp;c76=adbsnid,&amp;amp;c77=adsuprt,2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg,0&amp;amp;c72=otttyp,none&amp;amp;c44=progen,&amp;amp;davty=1&amp;amp;si=https%3A%2F%2Fnielsenonlinesupport.com%2Fmichel%2Fmediametrie%2FsdkRefImpl%2Findex.htm&amp;amp;c66=mediaurl,assets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;sdd=&amp;amp;c62=sendTime,1684322275&amp;amp;rnd=582363&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;} from Initialization API Call.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Browser_SDK&amp;diff=7592</id>
		<title>DCR France Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Browser_SDK&amp;diff=7592"/>
		<updated>2026-03-18T10:44:22Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Turning off the First Party ID for Opt-out Users during the SDK Initializazion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK (BSDK) is the framework for browser application developers to integrate Nielsen Measurement into their media players. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]) and Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]). Nielsen SDKs are also equipped to measure static content and can track key life cycle events.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Review SDK Integration Architecture Diagram ===&lt;br /&gt;
&lt;br /&gt;
==== For Content Playback ====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Add Static Queue Snippet ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following script tag to the website i.e. within the &amp;lt;head&amp;gt;&amp;lt;/head&amp;gt; tag :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      trackEvent:function(o){e[n][r].te=e[n][r].te||[];try{var c=t(o);e[n][r].te.push(c)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create SDK Instance ===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For creating an instance, pass the following values: (&amp;lt;code&amp;gt;nol_sdkDebug&amp;lt;/code&amp;gt; is optional)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Source !! Required !! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/website || Nielsen-specified || ✓  ||	&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance || Nielsen-specified || ✓ ||	&amp;quot;any string value&amp;quot; i.e. &amp;quot;TVnamevideoSdkInstance&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || ||	 i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified ||  || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging if desired. || Nielsen-specified || 	|| &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{nol_sdkDebug: &amp;quot;debug&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;appid&amp;gt;.js, will be downloaded based on the appid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Call ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
    hem_sha1: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    uid2: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    hem_sha256: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    optout: &amp;quot;false&amp;quot;,&lt;br /&gt;
    enableFpid: &amp;quot;true&amp;quot;,&lt;br /&gt;
    nol_sdkDebug: &amp;quot;debug&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
Before starting any measurement of an asset with the created SDK Instance, you need to create an asset metadata object in order to identify the asset. &lt;br /&gt;
There are two types of asset metadata but only one is used for Mediametrie:&lt;br /&gt;
*content: identify a video&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata are passed through key-values using the Nielsen reserved keys. You will need to set up content object with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Create Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; URL Character Limit: There is a URL character limit of 2K characters due to browser limitations. Exceeding this value could impair data delivery on particular browsers. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
Nielsen APIs calls are made by calling the function ggPM(&amp;quot;event&amp;quot;, parameter, ...) with &amp;quot;event&amp;quot; Parameter indicating the SDK API.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;event&amp;quot;, parameter, ...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;loadMetadata&amp;quot;	|| content metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;setPlayheadPosition&amp;quot;	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback, the value passed should match the broadcast time for live channel.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;stop&amp;quot; ||	playhead position in seconds	|| Call when content interrupted/paused and stop passing playhead position. Do the same also when an Ad Break starts during the Content Playback.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;end&amp;quot;	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the measurement by calling the &amp;quot;event&amp;quot; names &amp;quot;loadMetadata&amp;quot; followed by &amp;quot;setPlayheadPosition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM  (main content)&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stop and Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
&lt;br /&gt;
=== Handle Video Playback Interruption ===&lt;br /&gt;
The setPlayheadPostion event is used for handling playback interruption. To indicate that the video player is not playing (i.e. paused, buffering), stop passing the playhead position to the SDK. &lt;br /&gt;
Once the Playback resumes , begin sending the playhead position again with the correct playhead value.&lt;br /&gt;
&lt;br /&gt;
=== List of video Playback Interruptions ===&lt;br /&gt;
The following possible  video Playback Interruptions must be handled:&lt;br /&gt;
* Player PAUSED&lt;br /&gt;
* Player BUFFERING&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
* Network Loss&lt;br /&gt;
&lt;br /&gt;
=== Example for handling Playback Interruption: Browser/Tab close/Page Reload ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function(event) &lt;br /&gt;
{ &lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' additional code may be  needed in order to support specific browser versions (e.g. older versions of Internet Explorer).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK Call Sequence ==&lt;br /&gt;
The sample event lifecycles can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
=== Content Playback Call Sequence ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
//&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
* &amp;quot;setPlayheadPosition&amp;quot; is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling &amp;quot;stop&amp;quot; or &amp;quot;end&amp;quot;.&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. &lt;br /&gt;
* The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion) that should be ignored since No Ads are measured in France.&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;br&amp;gt;	&lt;br /&gt;
Make sure the country &amp;quot;France&amp;quot; is selected in the country dropdown list.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for Mediametrie [https://nielsenonlinesupport.com/mediametrie/sdkRefImpl/index.htm sdkRefImpl].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen SDK Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The Browser SDK video measurement does not set cross-domain cookies, therefore no centralized opt-out functionality is available. The Nielsen Browser SDK does not set cookies associated with the collection domain. The SDK sets specific cookie for the domain where the player is hosted (first party) and this cookie is not used across websites.&lt;br /&gt;
The only personal information collected with the SDK network pings is the IP address, which is  anonymized immediately after collection.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with enableFpid =====&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned on ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	enableFpid: &amp;quot;true&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned off ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	enableFpid: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The optout Flag is set by default to &amp;quot;false&amp;quot; in the Browser SDK. For Opt-out users, the optout Flag can be set to &amp;quot;true&amp;quot; during the initialization of the SDK Instance, i.e. the parameter Optout can be set to &amp;quot;true&amp;quot; (opted out) or &amp;quot;false&amp;quot; (opted in or NOT opted out). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with the Ouptout Flag =====&lt;br /&gt;
&lt;br /&gt;
====== User opted out ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
    optout: &amp;quot;true&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== User opted in ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	optout: &amp;quot;false&amp;quot; &lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Run your player in the Browser, start a video&amp;lt;br /&amp;gt;&lt;br /&gt;
2. Open the Developer Network View in order to monitor network traffic&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Filter the network traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=xknspa6p3viv2medizzvw8tld2smg1682583576&amp;amp;fp_cr_tm=1682583576685&amp;amp;fp_acc_tm=1684322226258&amp;amp;fp_emm_tm=1684322226288&amp;amp;ve_id=&amp;amp;sessionId=c81tzsiqvhqm6zswkeftmjjyip3fe1684322243&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc,c77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20FR&amp;amp;c13=asid,P1D11AF9D-E3FE-438C-B861-ED47543FF0E2&amp;amp;c32=segA,NA&amp;amp;c33=segB,NA&amp;amp;c34=segC,NA&amp;amp;c15=apn,&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_D1_00000&amp;amp;c9=devid,&amp;amp;enc=true&amp;amp;c1=nuid,999&amp;amp;at=timer&amp;amp;rt=video&amp;amp;c16=sdkv,bj.6.0.0&amp;amp;c27=cln,6&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid,16843222430632178&amp;amp;c30=bldv,6.0.0.662&amp;amp;st=dcr&amp;amp;c7=osgrp,&amp;amp;c8=devgrp,&amp;amp;c10=plt,&amp;amp;c40=adbid,&amp;amp;c14=osver,NA&amp;amp;c26=dmap,1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid,&amp;amp;c36=cref1,&amp;amp;c37=cref2,&amp;amp;c11=agg,1&amp;amp;c12=apv,&amp;amp;c51=adl,15&amp;amp;c52=noad,0&amp;amp;sd=170&amp;amp;pc=NA&amp;amp;c53=fef,y&amp;amp;c54=oad,20200713%2010%3A22%3A00&amp;amp;c55=cref3,&amp;amp;c57=adldf,2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st,c&amp;amp;c64=starttm,1684322269&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive,false&amp;amp;c59=sesid,3dn2br9l4y9rr2iuxycsdnlh3zwvd1684322245&amp;amp;c61=createtm,1684322275&amp;amp;c63=pipMode,&amp;amp;c68=bndlid,&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype,&amp;amp;c74=dvcnm,&amp;amp;c76=adbsnid,&amp;amp;c77=adsuprt,2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg,0&amp;amp;c72=otttyp,none&amp;amp;c44=progen,&amp;amp;davty=1&amp;amp;si=https%3A%2F%2Fnielsenonlinesupport.com%2Fmichel%2Fmediametrie%2FsdkRefImpl%2Findex.htm&amp;amp;c66=mediaurl,assets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;sdd=&amp;amp;c62=sendTime,1684322275&amp;amp;rnd=582363&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;} from Initialization API Call.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Browser_SDK&amp;diff=7591</id>
		<title>DCR France Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Browser_SDK&amp;diff=7591"/>
		<updated>2026-03-18T10:43:45Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Setting the  SDK global optout Flag for Opt-out Users during the SDK Initializazion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK (BSDK) is the framework for browser application developers to integrate Nielsen Measurement into their media players. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]) and Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]). Nielsen SDKs are also equipped to measure static content and can track key life cycle events.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Review SDK Integration Architecture Diagram ===&lt;br /&gt;
&lt;br /&gt;
==== For Content Playback ====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Add Static Queue Snippet ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following script tag to the website i.e. within the &amp;lt;head&amp;gt;&amp;lt;/head&amp;gt; tag :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      trackEvent:function(o){e[n][r].te=e[n][r].te||[];try{var c=t(o);e[n][r].te.push(c)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create SDK Instance ===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;apid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For creating an instance, pass the following values: (&amp;lt;code&amp;gt;nol_sdkDebug&amp;lt;/code&amp;gt; is optional)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Source !! Required !! Values&lt;br /&gt;
|-&lt;br /&gt;
| apid	|| Unique ID assigned to player/website || Nielsen-specified || ✓  ||	&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance || Nielsen-specified || ✓ ||	&amp;quot;any string value&amp;quot; i.e. &amp;quot;TVnamevideoSdkInstance&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || ||	 i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified ||  || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging if desired. || Nielsen-specified || 	|| &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{nol_sdkDebug: &amp;quot;debug&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;appid&amp;gt;.js, will be downloaded based on the appid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Call ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
    hem_sha1: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    uid2: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    hem_sha256: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    optout: &amp;quot;false&amp;quot;,&lt;br /&gt;
    enableFpid: &amp;quot;true&amp;quot;,&lt;br /&gt;
    nol_sdkDebug: &amp;quot;debug&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
Before starting any measurement of an asset with the created SDK Instance, you need to create an asset metadata object in order to identify the asset. &lt;br /&gt;
There are two types of asset metadata but only one is used for Mediametrie:&lt;br /&gt;
*content: identify a video&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata are passed through key-values using the Nielsen reserved keys. You will need to set up content object with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Create Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; URL Character Limit: There is a URL character limit of 2K characters due to browser limitations. Exceeding this value could impair data delivery on particular browsers. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
Nielsen APIs calls are made by calling the function ggPM(&amp;quot;event&amp;quot;, parameter, ...) with &amp;quot;event&amp;quot; Parameter indicating the SDK API.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;event&amp;quot;, parameter, ...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;loadMetadata&amp;quot;	|| content metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|-&lt;br /&gt;
|&amp;quot;setPlayheadPosition&amp;quot;	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback, the value passed should match the broadcast time for live channel.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;stop&amp;quot; ||	playhead position in seconds	|| Call when content interrupted/paused and stop passing playhead position. Do the same also when an Ad Break starts during the Content Playback.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;end&amp;quot;	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the measurement by calling the &amp;quot;event&amp;quot; names &amp;quot;loadMetadata&amp;quot; followed by &amp;quot;setPlayheadPosition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM  (main content)&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stop and Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
&lt;br /&gt;
=== Handle Video Playback Interruption ===&lt;br /&gt;
The setPlayheadPostion event is used for handling playback interruption. To indicate that the video player is not playing (i.e. paused, buffering), stop passing the playhead position to the SDK. &lt;br /&gt;
Once the Playback resumes , begin sending the playhead position again with the correct playhead value.&lt;br /&gt;
&lt;br /&gt;
=== List of video Playback Interruptions ===&lt;br /&gt;
The following possible  video Playback Interruptions must be handled:&lt;br /&gt;
* Player PAUSED&lt;br /&gt;
* Player BUFFERING&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
* Network Loss&lt;br /&gt;
&lt;br /&gt;
=== Example for handling Playback Interruption: Browser/Tab close/Page Reload ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function(event) &lt;br /&gt;
{ &lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) {	// for iOS mobile &amp;quot;pagehide&amp;quot; recommended by apple&lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' additional code may be  needed in order to support specific browser versions (e.g. older versions of Internet Explorer).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK Call Sequence ==&lt;br /&gt;
The sample event lifecycles can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
=== Content Playback Call Sequence ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
//&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
* &amp;quot;setPlayheadPosition&amp;quot; is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling &amp;quot;stop&amp;quot; or &amp;quot;end&amp;quot;.&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. &lt;br /&gt;
* The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion) that should be ignored since No Ads are measured in France.&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;br&amp;gt;	&lt;br /&gt;
Make sure the country &amp;quot;France&amp;quot; is selected in the country dropdown list.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for Mediametrie [https://nielsenonlinesupport.com/mediametrie/sdkRefImpl/index.htm sdkRefImpl].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen SDK Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The Browser SDK video measurement does not set cross-domain cookies, therefore no centralized opt-out functionality is available. The Nielsen Browser SDK does not set cookies associated with the collection domain. The SDK sets specific cookie for the domain where the player is hosted (first party) and this cookie is not used across websites.&lt;br /&gt;
The only personal information collected with the SDK network pings is the IP address, which is  anonymized immediately after collection.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initializazion ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with enableFpid =====&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned on ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	enableFpid: &amp;quot;true&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned off ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	enableFpid: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The optout Flag is set by default to &amp;quot;false&amp;quot; in the Browser SDK. For Opt-out users, the optout Flag can be set to &amp;quot;true&amp;quot; during the initialization of the SDK Instance, i.e. the parameter Optout can be set to &amp;quot;true&amp;quot; (opted out) or &amp;quot;false&amp;quot; (opted in or NOT opted out). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with the Ouptout Flag =====&lt;br /&gt;
&lt;br /&gt;
====== User opted out ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
    optout: &amp;quot;true&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== User opted in ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;TVnamevideoSdkInstance&amp;quot;, {&lt;br /&gt;
	optout: &amp;quot;false&amp;quot; &lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Run your player in the Browser, start a video&amp;lt;br /&amp;gt;&lt;br /&gt;
2. Open the Developer Network View in order to monitor network traffic&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Filter the network traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=xknspa6p3viv2medizzvw8tld2smg1682583576&amp;amp;fp_cr_tm=1682583576685&amp;amp;fp_acc_tm=1684322226258&amp;amp;fp_emm_tm=1684322226288&amp;amp;ve_id=&amp;amp;sessionId=c81tzsiqvhqm6zswkeftmjjyip3fe1684322243&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc,c77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20FR&amp;amp;c13=asid,P1D11AF9D-E3FE-438C-B861-ED47543FF0E2&amp;amp;c32=segA,NA&amp;amp;c33=segB,NA&amp;amp;c34=segC,NA&amp;amp;c15=apn,&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_D1_00000&amp;amp;c9=devid,&amp;amp;enc=true&amp;amp;c1=nuid,999&amp;amp;at=timer&amp;amp;rt=video&amp;amp;c16=sdkv,bj.6.0.0&amp;amp;c27=cln,6&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid,16843222430632178&amp;amp;c30=bldv,6.0.0.662&amp;amp;st=dcr&amp;amp;c7=osgrp,&amp;amp;c8=devgrp,&amp;amp;c10=plt,&amp;amp;c40=adbid,&amp;amp;c14=osver,NA&amp;amp;c26=dmap,1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid,&amp;amp;c36=cref1,&amp;amp;c37=cref2,&amp;amp;c11=agg,1&amp;amp;c12=apv,&amp;amp;c51=adl,15&amp;amp;c52=noad,0&amp;amp;sd=170&amp;amp;pc=NA&amp;amp;c53=fef,y&amp;amp;c54=oad,20200713%2010%3A22%3A00&amp;amp;c55=cref3,&amp;amp;c57=adldf,2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st,c&amp;amp;c64=starttm,1684322269&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive,false&amp;amp;c59=sesid,3dn2br9l4y9rr2iuxycsdnlh3zwvd1684322245&amp;amp;c61=createtm,1684322275&amp;amp;c63=pipMode,&amp;amp;c68=bndlid,&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype,&amp;amp;c74=dvcnm,&amp;amp;c76=adbsnid,&amp;amp;c77=adsuprt,2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg,0&amp;amp;c72=otttyp,none&amp;amp;c44=progen,&amp;amp;davty=1&amp;amp;si=https%3A%2F%2Fnielsenonlinesupport.com%2Fmichel%2Fmediametrie%2FsdkRefImpl%2Findex.htm&amp;amp;c66=mediaurl,assets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;sdd=&amp;amp;c62=sendTime,1684322275&amp;amp;rnd=582363&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;} from Initialization API Call.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7590</id>
		<title>DCR Sweden Domless SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Domless_SDK&amp;diff=7590"/>
		<updated>2026-03-18T08:45:58Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: start&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TBD&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Video_Android_SDK&amp;diff=7589</id>
		<title>DCR Sweden Video Android SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Sweden_Video_Android_SDK&amp;diff=7589"/>
		<updated>2026-03-18T08:40:38Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Create SDK Instance */  YES added for optout as for other params&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of the multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like  It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
*Time of viewing a subsection/page in the application.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
This ''SDK Android integration guide'' is applicable for '''Android TV''' as well.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;App ID (appid)&amp;quot; || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;Nielsen SDK&amp;quot; || Includes SDK frameworks and &amp;quot;sample implementation&amp;quot;; &amp;quot;See [[Android SDK Release Notes]]&amp;quot; || [[Special:Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  Implementation ==&lt;br /&gt;
The Nielsen Android SDK comes in three flavors.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! SDK Flavor&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| '''Android Ad Version'''&lt;br /&gt;
|&lt;br /&gt;
* Opt-In and Opt-Out functionality managed by Opt out of Ads Personalization setting on the device.&lt;br /&gt;
* The Nielsen SDK will collect the [https://developer.android.com/training/articles/ad-id Google Advertising ID] unless the user Opts out.&lt;br /&gt;
* If the Google Play Service is unavailable (ie, Amazon and Huawei devices), the Nielsen SDK will secure the Android ID.&lt;br /&gt;
|-&lt;br /&gt;
| '''Android No Ad Framework'''&lt;br /&gt;
|&lt;br /&gt;
* Without the Google Play Services SDK, the Nielsen SDK cannot read the Google Advertising ID, so it will retrieve the Android ID.&lt;br /&gt;
* The Android ID is a 64-bit number (expressed as a hexadecimal string) unique to each combination of the app-signing key, user and device.&lt;br /&gt;
* The developer is required to present the User Choice Opt-Out page, which is described in the [[#Global_Android_SDK_No_Ad_Framework_Opt-out|Global Android SDK No Ad Framework Opt-out]].&lt;br /&gt;
|-&lt;br /&gt;
| '''Android SDK noID'''&lt;br /&gt;
|&lt;br /&gt;
* This version of the Nielsen SDK is perfect for Kid apps, or where no ID is required.&lt;br /&gt;
* For the requirement, please review the [[#Global_Android_SDK_No_ID_Opt-out|Global Android SDK No ID Opt-out]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== How to obtain the NielsenAppApi ===&lt;br /&gt;
The Nielsen AppSDK can either be downloaded directly or can be integrated directly within an application through the use of Gradle. We recommend using the Gradle-based integration whenever possible to ensure you maintain the most recent changes and enhancements to the Nielsen libraries.&lt;br /&gt;
* [[Digital_Measurement_Android_Artifactory_Guide|Select to obtain Gradle implementation guide]]&lt;br /&gt;
* [[Special:Downloads|Select to Download Directly]]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Setting up your Android Development Environment  ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
1) Ensure to unzip the Nielsen App SDK zip file and copy the &amp;quot;AppSdk.jar&amp;quot; into the app/libs folder on the App’s project. Add it as dependency.&amp;lt;br /&amp;gt;&lt;br /&gt;
2) Add the following permissions to the project’s &amp;quot;AndroidManifest.xml&amp;quot; file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) Add Google Play Services lib into dependencies as Nielsen AppSDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
Libraries:&lt;br /&gt;
* com.google.android.gms:play-services&lt;br /&gt;
Required Google Play Service Classes and Packages :&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient;&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
4) Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;import com.nielsen.app.sdk.*;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
*The Nielsen App SDK (located in the &amp;quot;com.nielsen.app.sdk&amp;quot; package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*Nielsen App SDK is compatible with Android OS versions 2.3+.&lt;br /&gt;
*Clients can control/configure the protocol to be used – HTTPS or HTTP to suit their needs.&lt;br /&gt;
*The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 4.0 will later support it natively).&lt;br /&gt;
*If the player application uses a 3rd party media player implementing its own HLS/MPEG-DASH stack, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work correctly.&lt;br /&gt;
&lt;br /&gt;
== Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required/Obligatory? !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || YES || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' || NO || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App Version included in the App Resource File''' || NO || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified || NO || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| hem_unknown ||  Hashed email using SHA512. This email is used by MMS reach model.&lt;br /&gt;
|| Client-defined || Required if login feature || &amp;quot;924899b875ea6767ab790bd2f4852345fcfec5d203c49be8e8...&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| enableFpid || true/false value is required to set collection of first-party ID.&lt;br /&gt;
|| Nielsen-specified || NO || &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; {enableFpid: &amp;quot;true&amp;quot;} //alternative: false &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || YES || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) AppSDK() is no longer a singleton object and should be created as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;appversion&amp;quot;, &amp;quot;1.0&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;appname&amp;quot;, &amp;quot;Sample App Name&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;) // only for debug builds&lt;br /&gt;
          .put(&amp;quot;hem_unknown&amp;quot;, &amp;quot;924899b875ea6767ab790bd2f4852345fcfec5d203c49be8e8...&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;); // alternative is false; &lt;br /&gt;
          .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
2) implement IAppNotifier into your activity like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public class MainActivity extends AppCompatActivity implements IAppNotifier&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) implement callback&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;@Override&lt;br /&gt;
public void onAppSdkEvent(long timestamp, int code, String description){&lt;br /&gt;
  Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So the whole Activity will look like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.example.josefvancura.nlsdemotmp;&lt;br /&gt;
&lt;br /&gt;
import android.content.Context;&lt;br /&gt;
import android.support.v7.app.AppCompatActivity;&lt;br /&gt;
import android.os.Bundle;&lt;br /&gt;
import android.util.Log;&lt;br /&gt;
&lt;br /&gt;
import com.nielsen.app.sdk.*;&lt;br /&gt;
&lt;br /&gt;
import org.json.JSONException;&lt;br /&gt;
import org.json.JSONObject;&lt;br /&gt;
&lt;br /&gt;
public class MainActivity extends AppCompatActivity implements IAppNotifier {&lt;br /&gt;
&lt;br /&gt;
    private AppSdk mAppSdk = null;&lt;br /&gt;
    private String TAG = &amp;quot;MainActivity&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void onCreate(Bundle savedInstanceState) {&lt;br /&gt;
        super.onCreate(savedInstanceState);&lt;br /&gt;
        setContentView(R.layout.activity_main);&lt;br /&gt;
&lt;br /&gt;
        Context context = getApplicationContext();&lt;br /&gt;
&lt;br /&gt;
        try{&lt;br /&gt;
            // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
            JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
                    .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;appversion&amp;quot;, &amp;quot;1.0&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;appname&amp;quot;, &amp;quot;Sample App Name&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;) // only for debug builds&lt;br /&gt;
                    .put(&amp;quot;hem_unknown&amp;quot;, &amp;quot;924899b875ea6767ab790bd2f4852345fcfec5d203c49be8e8...&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;) // alternative is false; &lt;br /&gt;
                    .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
            mAppSdk = new AppSdk(context, appSdkConfig, this ); // Notifier - activity implements IAppNotifier, callback in onAppSdkEvent()&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (JSONException e){&lt;br /&gt;
            Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onAppSdkEvent(long timestamp, int code, String description) {&lt;br /&gt;
        Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the &amp;quot;&amp;quot;Initial state&amp;quot;&amp;quot;.&lt;br /&gt;
# '''Idle state'''– The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance processes playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted string. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
&lt;br /&gt;
* JSON value must be a string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Create Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip, including when ads play.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Please see the [[Sweden_SDK_Metadata|Metadata link]] for the full list of content metadata.&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:'''  Program and title metadata values should be passed to SDK as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
==== Create Ad Metadata ====&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Please see the [[Sweden_SDK_Metadata|Metadata link]] for the full list of ad metadata.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; URL Character Limit: There is a URL character limit of 2K characters due to browser limitations. Exceeding this value could impair data delivery on particular browsers. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
   .put(&amp;quot;assetid&amp;quot;, &amp;quot;uniqueassetid&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;program&amp;quot;, &amp;quot;program name&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;length&amp;quot;, &amp;quot;2600&amp;quot;);&lt;br /&gt;
   //please see metadata link above for all content parameters&lt;br /&gt;
&lt;br /&gt;
JSONObject adMetadata = new JSONObject()&lt;br /&gt;
   .put(&amp;quot;assetid&amp;quot;, &amp;quot;uniquepostrolladid&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;type&amp;quot;, &amp;quot;postroll&amp;quot;);&lt;br /&gt;
    //please see metadata link above for all ad parameters&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the &amp;quot;&amp;quot;Play&amp;quot;&amp;quot; button on the player. Call play only when initially starting the video.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
It needs to be called at the beginning of each asset and pass JSON object for relevant content or ad. Make sure to pass as 1st loadMetadata for content at the beginning of the playlist - see below API call sequence examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
* VOD: current position in seconds for Content and Ad. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content and Ad (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;mAppSdk.setPlayheadPosition(long videoPositon);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* When a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see below chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.stop();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.end();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== API Call Sequence ===&lt;br /&gt;
==== Use Case 1: Content has no Ads ====&lt;br /&gt;
Call [[play()]] at start of stream&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for content as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
  &amp;quot;assetid&amp;quot;: &amp;quot;vid345-67483&amp;quot;,&lt;br /&gt;
  &amp;quot;program&amp;quot;: &amp;quot;ProgramName&amp;quot;,&lt;br /&gt;
  &amp;quot;title&amp;quot;: &amp;quot;Program S3, EP1&amp;quot;,&lt;br /&gt;
  &amp;quot;length&amp;quot;: &amp;quot;3600&amp;quot;,&lt;br /&gt;
  ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until a pause.&lt;br /&gt;
Use the sample API sequence below as a reference to identify the specific events that need to be called during content playback without ads.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(); &amp;lt;/code&amp;gt; || // Call at start of each new stream&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| Interruption || &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // call stop when content playback is interrupted&lt;br /&gt;
|-&lt;br /&gt;
| Resume Content || &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // continue pasing playhead position every second starting from position where content is resumed&lt;br /&gt;
|- &lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Use Case 2: Content has Ads ====&lt;br /&gt;
Call [[play()]] with channelName JSON as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Call [[loadMetadata()]] with JSON metadata for ad as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;{&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;preroll&amp;quot;,&lt;br /&gt;
   &amp;quot;assetid&amp;quot;: &amp;quot;ad-123&amp;quot;&lt;br /&gt;
   ...&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In case the individual ad details are not available, send ad pod (presence) details through the [[loadMetadata]] and playhead position through [[playheadPosition]].&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call [[setPlayheadPosition()]] every one second until a pause / another [[loadMetadata()]] is called. Playhead should be passed for the entire duration of the ad pod if the ad pod details are passed as part of [[loadMetadata()]].&lt;br /&gt;
&lt;br /&gt;
The sample API sequence can be used as a reference to identify the specific events that need to be called during content and ad playback.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Type !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Start of stream || &amp;lt;code&amp;gt;mAppSdk.play(channelInfo); &amp;lt;/code&amp;gt; || // channelName contains JSON metadata of channel name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Preroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(prerollMetadataObject);&amp;lt;/code&amp;gt; || // prerollMetadataObject contains the JSON metadata for the preroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the preroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after preroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Content || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // content paused before switching to midroll&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Midroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(midrollMetaDataObject);&amp;lt;/code&amp;gt; || // midroll starts, midrollMetadataObject contains the JSON metadata for the midroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the midroll ad is being played &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after midroll occurs&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Content (End of stream) || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(contentMetaDataObject);&amp;lt;/code&amp;gt; || // contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| End of Stream || &amp;lt;code&amp;gt;mAppSdk.end();&amp;lt;/code&amp;gt; || // Call end() at the end of content&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Postroll || &amp;lt;code&amp;gt;mAppSdk.loadMetadata(postrollMetaDataObject);&amp;lt;/code&amp;gt; || // postrollMetadataObject contains the JSON metadata for the postroll ad&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.setPlayheadPosition(playheadPosition);&amp;lt;/code&amp;gt; || // position is position of the playhead while the postroll ad is being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;mAppSdk.stop();&amp;lt;/code&amp;gt; || // Call stop after postroll occurs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: Each Ad playhead should reset or begin from 0 at ad start. When content has resumed following an ad break, playhead position must continue from where the previous content segment was left off.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Foreground and Background states ==&lt;br /&gt;
There are a few approaches to managing the Foreground and Background states of an app available to use for state measurement.&lt;br /&gt;
&lt;br /&gt;
*Utilizing the Androidx LifeCycleObserver (The recommended approach starting sdk version 7.1.0.0+)&lt;br /&gt;
*Utilizing the SdkBgFgDetectionUtility class&lt;br /&gt;
*Adding a tag to the Manifest XML&lt;br /&gt;
*Manual Management&lt;br /&gt;
=== The LifeCycleObserver ===&lt;br /&gt;
AndroidX replaces the original support library APIs with packages in the androidx namespace, and Android Studio 3.2 and higher provide an automated migration tool. (Select '''Refactor&amp;gt; Migrate to AndroidX''' from the menu bar.)&lt;br /&gt;
&lt;br /&gt;
Starting with version 7.1.0, with AndroidX support, an additional utility is provided in the AppSDK - application background/foreground state detection by the AppSdk leveraging the Android Architecture component &amp;quot;LifeCycleObserver&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The AppSdk is now capable of detecting the application UI visibility state transitions between background and foreground without forcing the applications to register for AppSdk's AppSdkApplication class, which is responsible for handling the detection of application background/foreground state transitions at present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Please note that if you already have an app designed that utilizes the depreciated SdkBgFgDetectionUtility Class, the AppSDK will ignore any calls to these methods if it can utilize the LifeCycleObserver. LifeCycleObserver based auto-detection will take precedence.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Adding the AndroidX dependency ====&lt;br /&gt;
In order to make use of the app background/foreground state transition auto detection feature of AndroidX AppSdk, the app gradle file needs the androidx dependency. The AppSdk API calls - &amp;lt;code&amp;gt;appInForeground()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;appInBackground()&amp;lt;/code&amp;gt; will still be respected by AppSdk by executing the old AppSdk flow of handling &amp;quot;app in foreground&amp;quot; and &amp;quot;app in background&amp;quot; states as is.&lt;br /&gt;
&lt;br /&gt;
==== Using the LifeCycle Extension ====&lt;br /&gt;
The following androidx dependency is required in the app gradle file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;implementation &amp;quot;androidx.lifecycle:lifecycle-extensions:2.1.0&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If you would like to take advantage of this auto-detection feature of AppSdk at the very initial stage (e.g. splash screen or at of app launch time), before the AppSdk is initialized, you can do so by calling the following newly introduced AppSdk public API, passing the application context :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public static void registerLifeCycleObserver(Context applicationContext)&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Log messages for the new auto detection ====&lt;br /&gt;
&lt;br /&gt;
*When the AppSdk app successfully registers for the LifeCycleObserver : &amp;lt;code&amp;gt;Registered LifeCycleObserver for App Background/Foreground auto-detection&amp;lt;/code&amp;gt;&lt;br /&gt;
*When the app enters the foreground state :&amp;lt;code&amp;gt;App is in foreground, auto-detected by AppSDK&amp;lt;/code&amp;gt;&lt;br /&gt;
*When the app enters the background state :&amp;lt;code&amp;gt;App is in background, auto-detected by AppSDK&amp;lt;/code&amp;gt;&lt;br /&gt;
*If the client app doesn't have the &amp;quot;androidx&amp;quot; gradle dependency and AppSdk fails to register LifeCycleObserver :&amp;lt;code&amp;gt;AndroidX LifecycleObserver can not be observed. Please use androidx dependency to activate SDK auto-detection of app background/foreground state.&amp;lt;/code&amp;gt;&lt;br /&gt;
*When the appInForeground() is explicitly called while LifeCycleObserver auto detection is active :&amp;lt;code&amp;gt;Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - foreground&amp;lt;/code&amp;gt;&lt;br /&gt;
*When the appInBackground() is explicitly called while LifeCycleObserver auto detection is active :&amp;lt;code&amp;gt;Ignoring the appInBackground() call, as the App Background/Foreground auto-detection is active. The current state is - background&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The SdkBgFgDetectionUtility class ===&lt;br /&gt;
Foreground/Background state measurement is a requirement of Nielsen AppSDK implementation which is especially crucial for static measurement. It may be implemented in multiple ways for Android. This includes&lt;br /&gt;
&lt;br /&gt;
*Enable the Nielsen SDK to measure background/foreground state by making the relevant update to the AndroidManifest.&lt;br /&gt;
*Integrate Nielsen’s SdkBgFgDetectionUtility class within your Custom Application Class.&lt;br /&gt;
*Custom implementation of the required methods within your application.&lt;br /&gt;
&lt;br /&gt;
==== ForeGround/Background Measurement via AndroidManifest ====&lt;br /&gt;
The simplest way to measure the app background/foreground state is to add the following application tag to the Manifest XML. Integrating this into the Manifest XML will enable the SDK to measure app state directly. This approach is supported for Android 4.0 and up only; it requires that the application class is not in use for some other purpose.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt; &amp;lt;application android:name=&amp;quot;com.nielsen.app.sdk.AppSdkApplication&amp;quot;&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using the Android SdkBgFbDetectionUtility Class ====&lt;br /&gt;
For developers who are already using the application class, it is recommended that the background/foreground state is implemented using the [[Android Background Foreground|SdkBgFgDetectionUtility class.]] The [[Android Background Foreground|SdkBgFgDetectionUtility class.]] is compatible with Android 4+ and has been made available to Nielsen clients. (You will need to copy/paste the code provided into a file).&lt;br /&gt;
&lt;br /&gt;
==== Manual Background/ForeGround State Management ====&lt;br /&gt;
In cases where the developer is not able to use the AndroidManifest.xml solution nor the Nielsen provided [[Android Background Foreground|SdkBgFgDetectionUtility class.]], the developer will need to manually identify the change of state through the application and call the respective API (appInForeground() or appInBackground()) to inform the SDK regarding the change of state from background to foreground or foreground to background.&lt;br /&gt;
&lt;br /&gt;
The SDK is informed about app state using the below methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;AppLaunchMeasurementManager.appInForeground(getApplicationContext());&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;AppLaunchMeasurementManager.appInBackground(getApplicationContext());&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Within the lifecycle of individual activities, onResume() and onPause() are best suited to provide an indication of the app state.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Correct foreground/background state measurement is crucial to Static App measurement within Nielsen Digital Content Ratings (DCR).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the current viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== Privacy and Opt-Out ==&lt;br /&gt;
There are currently three flavors of the Nielsen SDK:&lt;br /&gt;
# '''[[#Global_Android_SDK_Opt-out|Global Android SDK Opt-out]]''' - managed by ''Opt out of Ads Personalization'' setting on device.&lt;br /&gt;
# '''[[#Global_Android_SDK_No_Ad_Framework_Opt-out|Global Android SDK No Ad Framework Opt-out]]''' - Direct call to SDK. It can be used without Google Play Services or when using the No Ad version of the SDK.&lt;br /&gt;
# '''[[#Global_Android_SDK_No_ID_Opt-out|Global Android SDK No ID Opt-out]]''' - Direct call to SDK. It should be used for Kids Category.&lt;br /&gt;
&lt;br /&gt;
=== Global Android SDK Opt-out ===&lt;br /&gt;
''OS-level Opt-out'' method available on Nielsen Android when the [https://developers.google.com/android/guides/setup Google Play services APIs] have been setup in your project.&lt;br /&gt;
&lt;br /&gt;
The Nielsen SDK automatically leverages the Android's '''Opt out of Ads Personalization''' setting. The user is opted out of demographic measurement if the OS-level '''Opt out of Ads Personalization''' setting is ''enabled''. As a publisher, you cannot override this setting.&lt;br /&gt;
&lt;br /&gt;
==== Webview Element ====&lt;br /&gt;
It is a requirement to display a WebView element whose loadUrl is set to the value obtained from optOutURL.&lt;br /&gt;
If using the Global Android SDK, this optOutURL informs the user how to deactivate/activate “Out of Ads Personalization”.&lt;br /&gt;
&lt;br /&gt;
==== Retrieve current Opt-Out preference ====&lt;br /&gt;
Whether the user is opted out via OS-level Opt-out or via App-level Opt-out, the current Opt-Out status as detected by the SDK is available via the [[getOptOutStatus()]] property in the Nielsen Android SDK API. &amp;lt;code&amp;gt;appSdk.getOptOutStatus()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;span id=&amp;quot;Global OptOut Example&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;Global OptOut Example ===&lt;br /&gt;
The below code is an AndroidX example of displaying the Nielsen Privacy page to the user.  Please see the next section if using the No Ad Framework build&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class OptOutActivity extends AppCompatActivity implements IAppNotifier {&lt;br /&gt;
&lt;br /&gt;
    WebView webView;&lt;br /&gt;
    AppSdk appSdk;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onCreate(@Nullable Bundle savedInstanceState) {&lt;br /&gt;
        super.onCreate(savedInstanceState);&lt;br /&gt;
        setContentView(R.layout.activity_optout);&lt;br /&gt;
        webView = (WebView) findViewById(R.id.webView);&lt;br /&gt;
        webView.getSettings().setJavaScriptEnabled(true);&lt;br /&gt;
&lt;br /&gt;
        webView.setWebViewClient(new WebViewClient() {&lt;br /&gt;
            @SuppressWarnings(&amp;quot;deprecation&amp;quot;)&lt;br /&gt;
            @Override&lt;br /&gt;
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {&lt;br /&gt;
                Toast.makeText(OptOutActivity.this, description, Toast.LENGTH_SHORT).show();&lt;br /&gt;
            }&lt;br /&gt;
            @TargetApi(android.os.Build.VERSION_CODES.M)&lt;br /&gt;
            @Override&lt;br /&gt;
            public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {&lt;br /&gt;
                // Redirect to deprecated method, so you can use it in all SDK versions&lt;br /&gt;
                onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        });&lt;br /&gt;
        String url = appSdk.userOptOutURLString();   // Request Optout URL from NielsenSDK&lt;br /&gt;
        webView.loadUrl(url);                         //Display to the user in a Webview&lt;br /&gt;
    }&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onBackPressed() {&lt;br /&gt;
        super.onBackPressed();&lt;br /&gt;
        mSdkInterface.getSDK(appSdk);&lt;br /&gt;
    }&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void onDestroy() {&lt;br /&gt;
        super.onDestroy();&lt;br /&gt;
        if (appSdk != null)&lt;br /&gt;
        {&lt;br /&gt;
            appSdk.close();&lt;br /&gt;
            appSdk = null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Global Android SDK No Ad Framework Opt-out ===&lt;br /&gt;
The ''No Ad Framework Opt-out'' can be used when the host application does not leverage Google Play Services, such as when using the No Ad or No ID versions.&lt;br /&gt;
&lt;br /&gt;
==== The No Ad Framework Opt-out method works as follows: ====&lt;br /&gt;
* Get the current Nielsen opt-out URL via [[userOptOutURLString()]]&lt;br /&gt;
* Display a WebView element whose loadUrl is set to the value obtained from [[userOptOutURLString()]]&lt;br /&gt;
* Detect if the WebView URL changes to a special URL that indicates Opt-in, or Opt-out and closes the WebView&lt;br /&gt;
** Opt-out if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://1&amp;lt;/code&amp;gt;&lt;br /&gt;
** Opt-in if the WebView URL = &amp;lt;code&amp;gt;nielsenappsdk://0&amp;lt;/code&amp;gt;&lt;br /&gt;
* Pass the detected URL to the [[userOptOut()]] function&lt;br /&gt;
** Example: &amp;lt;syntaxhighlight lang=java&amp;gt;appSdk.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;);  // User opt-out&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===&amp;lt;span id=&amp;quot;No Ad Framework Optout Sample Code&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;No Ad Framework Optout Sample Code ===&lt;br /&gt;
The below code is an AndroidX example of displaying the Nielsen Privacy page to the user with the No Ad Framework SDK Build.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class OptOutActivity extends AppCompatActivity implements IAppNotifier {&lt;br /&gt;
&lt;br /&gt;
    WebView webView;&lt;br /&gt;
    AppSdk appSdk;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onCreate(@Nullable Bundle savedInstanceState) {&lt;br /&gt;
        super.onCreate(savedInstanceState);&lt;br /&gt;
        setContentView(R.layout.activity_optout);&lt;br /&gt;
        webView = (WebView) findViewById(R.id.webView);&lt;br /&gt;
        webView.getSettings().setJavaScriptEnabled(true);&lt;br /&gt;
&lt;br /&gt;
        webView.setWebViewClient(new WebViewClient() {&lt;br /&gt;
            @SuppressWarnings(&amp;quot;deprecation&amp;quot;)&lt;br /&gt;
            @Override&lt;br /&gt;
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {&lt;br /&gt;
                Toast.makeText(OptOutActivity.this, description, Toast.LENGTH_SHORT).show();&lt;br /&gt;
            }&lt;br /&gt;
            @TargetApi(android.os.Build.VERSION_CODES.M)&lt;br /&gt;
            @Override&lt;br /&gt;
            public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {&lt;br /&gt;
                // Redirect to deprecated method, so you can use it in all SDK versions&lt;br /&gt;
                onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
            @Override&lt;br /&gt;
            public boolean shouldOverrideUrlLoading(WebView view, String url) {&lt;br /&gt;
&lt;br /&gt;
                if(url.contains(&amp;quot;nielsen&amp;quot;)){&lt;br /&gt;
                    // If url value = &amp;quot;nielsenappsdk://1&amp;quot; it means the user selected Opt-out&lt;br /&gt;
                    // If url value = &amp;quot;nielsenappsdk://0&amp;quot; it means the user selected Opt-in&lt;br /&gt;
                    appSdk.userOptOut(url);&lt;br /&gt;
                }&lt;br /&gt;
                return true;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        });&lt;br /&gt;
        String url = appSdk.userOptOutURLString();   // Request Optout URL from NielsenSDK&lt;br /&gt;
        webView.loadUrl(url);                         //Display to the user in a Webview&lt;br /&gt;
    }&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onBackPressed() {&lt;br /&gt;
        super.onBackPressed();&lt;br /&gt;
        mSdkInterface.getSDK(appSdk);&lt;br /&gt;
    }&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void onDestroy() {&lt;br /&gt;
        super.onDestroy();&lt;br /&gt;
        if (appSdk != null)&lt;br /&gt;
        {&lt;br /&gt;
            appSdk.close();&lt;br /&gt;
            appSdk = null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Global Android SDK No ID Opt-out ===&lt;br /&gt;
If you are building an app that will be listed in the Kids Category:&lt;br /&gt;
#  Ensure that you are using the No ID version of the Nielsen SDK Framework.&lt;br /&gt;
#  Immediately following the initialization of the Nielsen SDK ensure you call the userOptOut API with Opt-out selection: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=java&amp;gt;appSdk.userOptOut(&amp;quot;nielsenappsdk://1&amp;quot;);  // User opt-out&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Required Privacy Links ===&lt;br /&gt;
Users must either have access to the &amp;quot;About Nielsen Measurement&amp;quot; page or have the similar text available within the native app. Include the &amp;quot;About Nielsen Measurement&amp;quot; and &amp;quot;Your Choices&amp;quot; link in the Privacy Policy / EULA or as a button near the link to the app's Privacy Policy.&lt;br /&gt;
&lt;br /&gt;
In addition, the following text must be included in your app store description.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''&amp;quot;Please note: This app features Nielsen’s proprietary measurement software, which contributes to market research, like Nielsen’s TV Ratings. Please see https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=sv for more information&amp;quot;'''&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== First Party ID (FPID)===&lt;br /&gt;
- The broadcaster must enableFPID in the initialization settings which is set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; depending on user consent. This is to be set by the broadcaster when initializing our SDK.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- The &amp;lt;code&amp;gt;enableFpid&amp;lt;/code&amp;gt; flag is needed to enable/disable FPID usage for the AppID. The default value for this flag is true. If this flag is changed from true to false, then the AppSDK should wipe out the stored FPID and use a blank value for FPID parameter in all the pings.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- Generated FPID value is stored in the persistent memory until the application is uninstalled from a device, when FPID is wiped out, or when it is expired.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- The default value for this parameter is 180 days. Once this timeout is reached, the FPID should be regenerated.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Optional Step for DCR Chromecast Android SDK ==&lt;br /&gt;
For the implementation of Chromecast SDK architecture. Please refer to this guide: [https://engineeringportal.nielsen.com/docs/DCR_Chromecast_Android_SDK DCR Chromecast Android SDK]&lt;br /&gt;
&lt;br /&gt;
== Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via the same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;imr&amp;quot; and confirm the presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-sw.imrworldwide.com/cgi-bin/gn?prd=dcr&amp;amp;ci=se-910684&amp;amp;ch=se-910684_c01_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=096ohdsc0jqkmct81qpxhmn19qx041630053963&amp;amp;fp_cr_tm=1630053963&amp;amp;fp_acc_tm=1630053963&amp;amp;fp_emm_tm=1630053963&amp;amp;ve_id=afc5d61a88b62672&amp;amp;sessionId=zc6gh3uhka7d2mtobb2b2m7sixygy1630053963&amp;amp;tl=Djuren%20p%C3%A5%20Djuris&amp;amp;prv=1&amp;amp;c6=vc,c01&amp;amp;ca=se-910684_c01_218531&amp;amp;cg=Hemligheter&amp;amp;c13=asid,T1194003B-797F-4896-A5C0-05914236146E&amp;amp;c32=segA,NA&amp;amp;c33=segB,NA&amp;amp;c34=segC,NA&amp;amp;c15=apn,&amp;amp;plugv=4.4.1&amp;amp;playerv=ExoPlayer&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=1&amp;amp;cr=4_00_99_D1_10000&amp;amp;c9=devid,c041ec5e50722cdf8cc5b4826c24ae54c5747a6570e900006c826b37ca01ce17&amp;amp;enc=true&amp;amp;c1=nuid,c041ec5e50722cdf8cc5b4826c24ae54c5747a6570e900006c826b37ca01ce17&amp;amp;at=timer&amp;amp;rt=video&amp;amp;c16=sdkv,aa.8.1.0&amp;amp;c27=cln,34&amp;amp;crs=0&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid,16300539624283525&amp;amp;c30=bldv,aa.8.1.0.0_gaxnons&amp;amp;st=dcr&amp;amp;c7=osgrp,&amp;amp;c8=devgrp,&amp;amp;c10=plt,&amp;amp;c40=adbid,&amp;amp;c14=osver,ANDROID.11&amp;amp;c26=dmap,1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid,&amp;amp;c36=cref1,&amp;amp;c37=cref2,&amp;amp;c11=agg,1&amp;amp;c12=apv,4.4.1.4004001&amp;amp;c51=adl,0&amp;amp;c52=noad,0&amp;amp;sd=578&amp;amp;pc=NA&amp;amp;c53=fef,n&amp;amp;c54=oad,&amp;amp;c55=cref3,&amp;amp;c57=adldf,2&amp;amp;ai=218531&amp;amp;c3=st,c&amp;amp;c64=starttm,1630053962&amp;amp;adid=218531&amp;amp;c58=isLive,false&amp;amp;c59=sesid,257f8bz854wmqa31gk3icyi7cmj131630053964&amp;amp;c61=createtm,1630053997&amp;amp;c63=pipMode,&amp;amp;ci_userid=&amp;amp;is_auto_play=no&amp;amp;pl_title=&amp;amp;is_prem=no&amp;amp;is_prog=&amp;amp;ad_origin=&amp;amp;adidx=&amp;amp;is_tpad=&amp;amp;ci_passthr=&amp;amp;c62=sendTime,1630053997&amp;amp;c68=bndlid,air.se.urplay.android_player.debug&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype,&amp;amp;c74=dvcnm,&amp;amp;c76=adbsnid,&amp;amp;c77=adsuprt,2&amp;amp;uoo=&amp;amp;evdata=PL%3A1630053964727%3A0&amp;amp;c71=ottflg,0&amp;amp;c72=otttyp,&amp;amp;c44=progen,&amp;amp;davty=1&amp;amp;si=&amp;amp;c66=mediaurl,&amp;amp;sdd=retry,0~~retryreason,~~devmodel,SM-G981B~~devtypid,samsung-SM-G981B~~sysname,Android~~sysversion,11~~manuf,samsung&amp;amp;cat_id=3398d8e4-e613-42c1-92aa-1a6fc52dcf5c&amp;amp;vtoff=0&amp;amp;rnd=1630053997971&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Provide your app for certification ==&lt;br /&gt;
Once ready please send your application to Nielsen local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Going Live ==&lt;br /&gt;
After the integration has been certified by Nielsen (but not prior to that), do the following:&lt;br /&gt;
&lt;br /&gt;
# '''Disable Debug Logging''': Disable logging by deleting &amp;lt;code&amp;gt;{nol_sdkDebug: 'DEBUG'}&amp;lt;/code&amp;gt; from initialization call.&lt;br /&gt;
# '''Notify Nielsen''': Once you are ready to go live, let us know so we can enable you for reporting. We will not be able to collect or report data prior to receiving notification from you.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_Android_SDK&amp;diff=7576</id>
		<title>DCR Denmark Video Android SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_Android_SDK&amp;diff=7576"/>
		<updated>2026-03-06T13:48:46Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Step 7 : Disclose Nielsen Privacy Statement */ add enableFPID API for compatibility with BSDK&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like  It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
*Time of viewing a sub section / page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;App ID (appid)&amp;quot; || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;Nielsen SDK&amp;quot; || Includes SDK frameworks and &amp;quot;sample implementation&amp;quot;; &amp;quot;See [[Android SDK Release Notes]]&amp;quot; || [[Special:Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 1: Setting up your Android Development Environment  ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
1) Ensure to unzip the Nielsen App SDK zip file and copy the &amp;quot;AppSdk.jar&amp;quot; into the app/libs folder on the App’s project. Add it as dependency.&amp;lt;br /&amp;gt;&lt;br /&gt;
2) Add the following permissions on the project’s &amp;quot;AndroidManifest.xml&amp;quot; file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) Add Google Play Services lib into dependencies as Nielsen AppSDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
Libraries:&lt;br /&gt;
* com.google.android.gms:play-services&lt;br /&gt;
Requiered Google Play Service CLasses and Packages :&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient;&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
4) Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;import com.nielsen.app.sdk.*;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
*The Nielsen App SDK (located in the &amp;quot;com.nielsen.app.sdk&amp;quot; package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*Nielsen App SDK is compatible with Android OS versions 2.3+.&lt;br /&gt;
*Clients can control / configure the protocol to be used – HTTPS or HTTP to suit their needs.&lt;br /&gt;
*The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 4.0 and later will support it natively).&lt;br /&gt;
*If the player application uses a 3rd party media player implementing its own HLS/MPEG-DASH stack, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' ||  || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App version included in the App Resource File''' ||  || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified ||  || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) AppSDK() is no longer a singleton object and should be created as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
2) implement IAppNotifier into your activity like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public class MainActivity extends AppCompatActivity implements IAppNotifier&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) implement callback&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;@Override&lt;br /&gt;
public void onAppSdkEvent(long timestamp, int code, String description){&lt;br /&gt;
  Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So whole Activity will look like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.example.josefvancura.nlsdemotmp;&lt;br /&gt;
&lt;br /&gt;
import android.content.Context;&lt;br /&gt;
import android.support.v7.app.AppCompatActivity;&lt;br /&gt;
import android.os.Bundle;&lt;br /&gt;
import android.util.Log;&lt;br /&gt;
&lt;br /&gt;
import com.nielsen.app.sdk.*;&lt;br /&gt;
&lt;br /&gt;
import org.json.JSONException;&lt;br /&gt;
import org.json.JSONObject;&lt;br /&gt;
&lt;br /&gt;
public class MainActivity extends AppCompatActivity implements IAppNotifier {&lt;br /&gt;
&lt;br /&gt;
    private AppSdk mAppSdk = null;&lt;br /&gt;
    private String TAG = &amp;quot;MainActivity&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void onCreate(Bundle savedInstanceState) {&lt;br /&gt;
        super.onCreate(savedInstanceState);&lt;br /&gt;
        setContentView(R.layout.activity_main);&lt;br /&gt;
&lt;br /&gt;
        Context context = getApplicationContext();&lt;br /&gt;
&lt;br /&gt;
        try{&lt;br /&gt;
            // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
            JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
                    .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
            // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
            mAppSdk = new AppSdk(context, appSdkConfig, this ); // Notifier - activity implements IAppNotifier, callback in onAppSdkEvent()&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (JSONException e){&lt;br /&gt;
            Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onAppSdkEvent(long timestamp, int code, String description) {&lt;br /&gt;
        Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# &amp;quot;&amp;quot;Initial state&amp;quot;&amp;quot; – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the &amp;quot;&amp;quot;Initial state&amp;quot;&amp;quot;.&lt;br /&gt;
# &amp;quot;&amp;quot;Idle state&amp;quot;&amp;quot; – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# &amp;quot;&amp;quot;Processing state&amp;quot;&amp;quot; – The SDK instance is processing playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# &amp;quot;&amp;quot;Disabled state&amp;quot;&amp;quot; – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type ||	type of asset	|| &amp;quot;content&amp;quot; for main content	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid	|| unique ID assigned to asset 	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| program	|| name of program 	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| title	|| episode name	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| length	|| length of content in seconds	|| Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||	✓&lt;br /&gt;
|-&lt;br /&gt;
| airdate	|| the original date (local time with hh:mm:ss as 24h time stamp) content became available. This date does not change if the content is rebroadcasted on linear TV. ||	YYYYMMDD HH:MI:SS (if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot;)	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode	|| full episode flag ||	&lt;br /&gt;
* &amp;quot;y&amp;quot; full episode (full content for a program)&lt;br /&gt;
* &amp;quot;n&amp;quot; non full episode (only one part of the entire content for a program , i.e. preview, sub-episodes)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
|adloadtype	|| type of Ad load&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;1&amp;quot; Linear - matches TV ad load &lt;br /&gt;
* &amp;quot;2&amp;quot; Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Ad Metadata (optional for DR) ===&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;&amp;quot;preroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;midroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;postroll&amp;quot;&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	|| provided by Nielsen || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
   .put(&amp;quot;assetid&amp;quot;, &amp;quot;unique_content_id&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;program&amp;quot;, &amp;quot;program name&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;length&amp;quot;, &amp;quot;length in seconds&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;airdate&amp;quot;, &amp;quot;20200713 10:22:00&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;isfullepisode&amp;quot;, &amp;quot;y&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;adloadtype&amp;quot;, &amp;quot;2&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;subbrand&amp;quot;, &amp;quot;c05&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;stationId&amp;quot;, &amp;quot;TESTXXYYSSWWLL&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;islivestn&amp;quot;, &amp;quot;y&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;pbstarttm&amp;quot;, &amp;quot;1631098029&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
JSONObject adMetadata = new JSONObject()&lt;br /&gt;
   .put(&amp;quot;assetid&amp;quot;, &amp;quot;unique_postroll_ad_id&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;type&amp;quot;, &amp;quot;postroll&amp;quot;&lt;br /&gt;
   .put(&amp;quot;subbrand&amp;quot;, &amp;quot;c05&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;stationId&amp;quot;, &amp;quot;TESTXXYYSSWWLL&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;islivestn&amp;quot;, &amp;quot;y&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;pbstarttm&amp;quot;, &amp;quot;1631098029&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the &amp;quot;&amp;quot;Play&amp;quot;&amp;quot; button on the player. Call play only when initially starting the video.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
Note: &amp;quot;setPlayheadPosition&amp;quot; has to be called every second and the value passed should match the broadcast time for live channel.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content and Ad (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;mAppSdk.setPlayheadPosition(long videoPositon);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== sendID3 ====&lt;br /&gt;
Needs to be called when ID3 Tags are included in the Video Stream.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;mAppSdk..sendID3(String id3);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
ID3 Tags are parsed from the Video Stream, refer to the DK Reference Implementation [http://nielsenonlinesupport.com/dk/index.htm sdkRefImplDK] on how to parse ID3 Tags included in a sample HLS Stream.&lt;br /&gt;
For further technical details, please contact your Technical Account Manager (TAM).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.stop();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.end();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
In order to start the measurement, follow the 3 first steps below for Content without Ads. When terminating the Content playback call &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; to terminate the Content Measurement for the given asset.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Playlist !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 1. Start of stream || &amp;lt;code&amp;gt;play(channelName)&amp;lt;/code&amp;gt; || channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;loadMetadata(contentMetadataObject)&amp;lt;/code&amp;gt; || contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| 2. Content is playing || &amp;lt;code&amp;gt;playheadPosition(position)&amp;lt;/code&amp;gt; || playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| || &amp;lt;code&amp;gt;sendID3(id3)&amp;lt;/code&amp;gt; || id3 is an ID3 Tag parsed from the Video Stream, pass ID3 Tag immediately to SDK when found&lt;br /&gt;
|-&lt;br /&gt;
| 3. End of Stream || &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; || Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 5: Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the current viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Step 6: Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== Step 7 : Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The App SDK uses Mobile Ad IDs (Android ID or IDFA) which are fully hashed on the device before being sent to Nielsen (Nielsen never receives un-hashed values).&lt;br /&gt;
Users retain the possibility to oppose the use of Mobile Ad IDs, or to reset them, by using the functionality provided by the mobile operating system (iOS or Android).&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=da .&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Android AppSDK. For Opt-out users, the First Party ID can be turned off during the initialization of the AppSDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with enableFpid =====&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned on ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned off ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 8 : Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers VoD and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll Ad.&lt;br /&gt;
&lt;br /&gt;
Download the Reference Implementation for Android [https://nielsenonlinesupport.com/dk/android/DKRefPLAYER.zip DKRefPLAYER].&lt;br /&gt;
Unzip and open the project in Android Studio, then run it i.e. in the simulator or on Android device and then filter the Logcat output with &amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;quot; in order to see only relevant Nielsen SDK API Calls, as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
2021-04-08 15:11:27.075  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : class NielsenInit :: Create new AppSdk() Instance.&lt;br /&gt;
2021-04-08 15:11:27.568  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK EVENT - onAppSdkEvent: Description = Nielsen App SDK is initiated. AppSdk.jar aa.8.0.0.0_gsxaon. App SDK was successfully initiatedCode l param : 1617887487Code i param 2000&lt;br /&gt;
2021-04-08 15:11:29.497  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK EVENT - onAppSdkEvent: Description = Nielsen App SDK has started up. AppSdk.jar aa.8.0.0.0_gsxaon. Config file successfully loaded and parsed.Code l param : 1617887489Code i param 2001&lt;br /&gt;
2021-04-08 15:11:42.736  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :  appSdk.play(sdkMethods.loadChannelInfo());&lt;br /&gt;
2021-04-08 15:11:42.738  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : onPrepared() : appSdk.loadMetadata(data)&lt;br /&gt;
2021-04-08 15:11:43.065  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Media Player Event : onInfo ();what = 3&lt;br /&gt;
2021-04-08 15:11:43.065  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Media Player Event :  first video frame pushed for rendering.&lt;br /&gt;
2021-04-08 15:11:43.747  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 0 / 224&lt;br /&gt;
2021-04-08 15:11:44.752  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 1 / 224&lt;br /&gt;
2021-04-08 15:11:45.759  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 2 / 224&lt;br /&gt;
2021-04-08 15:11:46.764  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 3 / 224&lt;br /&gt;
2021-04-08 15:11:47.767  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 4 / 224&lt;br /&gt;
2021-04-08 15:11:48.772  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 5 / 224&lt;br /&gt;
2021-04-08 15:11:49.777  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 6 / 224&lt;br /&gt;
2021-04-08 15:11:50.781  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 7 / 224&lt;br /&gt;
2021-04-08 15:11:51.819  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 8 / 224&lt;br /&gt;
2021-04-08 15:11:51.821  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Activity onPause()&lt;br /&gt;
2021-04-08 15:11:52.668  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt;: Activity onDestroy()&lt;br /&gt;
2021-04-08 15:11:52.668  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : terminateNielsenSDK () :appSdk.end();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-dmk.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Provide your app for certification ==&lt;br /&gt;
Once ready please send your application to Nielsen local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 11 :  Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_devDebug: &amp;quot;DEBUG&amp;quot;} from initialization call - see Step 2.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_Browser_SDK&amp;diff=7575</id>
		<title>DCR Denmark Video Browser SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_Browser_SDK&amp;diff=7575"/>
		<updated>2026-03-06T13:46:48Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Turning off the First Party ID for Opt-out Users */  title same for iOS and Android&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The Browser SDK (BSDK) is the framework for browser application developers to integrate Nielsen Measurement into their media players. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]) and Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]). Nielsen SDKs are also equipped to measure static content and can track key life cycle events.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Configure SDK ==&lt;br /&gt;
There are two steps required for configuring the SDK:&lt;br /&gt;
*Add Static Queue Snippet&lt;br /&gt;
*Create SDK Instance&lt;br /&gt;
&lt;br /&gt;
=== Add Static Queue Snippet ===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following script tag to the website i.e. within the &amp;lt;head&amp;gt;&amp;lt;/head&amp;gt; tag :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
!function(e,n){&lt;br /&gt;
  function t(e){&lt;br /&gt;
    return&amp;quot;object&amp;quot;==typeof e?JSON.parse(JSON.stringify(e)):e&lt;br /&gt;
  }&lt;br /&gt;
  e[n]=e[n]||&lt;br /&gt;
  {&lt;br /&gt;
    nlsQ:function(o,r,c){&lt;br /&gt;
      var s=e.document,&lt;br /&gt;
      a=s.createElement(&amp;quot;script&amp;quot;);&lt;br /&gt;
      a.async=1,&lt;br /&gt;
      a.src=(&amp;quot;http:&amp;quot;===e.location.protocol?&amp;quot;http:&amp;quot;:&amp;quot;https:&amp;quot;)+&amp;quot;//cdn-gl.nmrodam.com/conf/&amp;quot;+o+&amp;quot;.js#name=&amp;quot;+r+&amp;quot;&amp;amp;ns=&amp;quot;+n;&lt;br /&gt;
      var i=s.getElementsByTagName(&amp;quot;script&amp;quot;)[0];&lt;br /&gt;
      return i.parentNode.insertBefore(a,i),&lt;br /&gt;
      e[n][r]=e[n][r]||{g:c||{},&lt;br /&gt;
      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)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}},&lt;br /&gt;
      trackEvent:function(o){e[n][r].te=e[n][r].te||[];try{var c=t(o);e[n][r].te.push(c)}&lt;br /&gt;
catch(e){console&amp;amp;&amp;amp;console.log&amp;amp;&amp;amp;console.log(&amp;quot;Error: Cannot register event in Nielsen SDK queue.&amp;quot;)}}},&lt;br /&gt;
      e[n][r]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}(window,&amp;quot;NOLBUNDLE&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create SDK Instance ===&lt;br /&gt;
To initialize the SDK, create an SDK instance by making the initialization call:&lt;br /&gt;
&lt;br /&gt;
==== Initialization API Call ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
NOLBUNDLE.nlsQ(&amp;quot;&amp;lt;appid&amp;gt;&amp;quot;, &amp;quot;&amp;lt;instanceName&amp;gt;&amp;quot;,{nol_sdkDebug: &amp;quot;debug&amp;quot;});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For creating an instance, pass the following values: (&amp;lt;code&amp;gt;nol_sdkDebug&amp;lt;/code&amp;gt; is optional)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter	!! Description	!! Values&lt;br /&gt;
|-&lt;br /&gt;
| appid	|| Unique ID assigned to player/website ||	&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|instanceName ||	Name of SDK instance ||	&amp;quot;any string value&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_sdkDebug	|| Enables Nielsen console logging if desired. 	|| &amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{nol_sdkDebug: &amp;quot;debug&amp;quot;} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When the initialization call is made, a unique static configuration file, &amp;lt;appid&amp;gt;.js, will be downloaded based on the appid and will be cached on the user’s browser.&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Call ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var nSdkInstance = NOLBUNDLE.nlsQ(&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;, &amp;quot;nlsnInstance&amp;quot;, {&lt;br /&gt;
    nol_sdkDebug: &amp;quot;debug&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the configuration is downloaded, the SDK itself will be downloaded and initialized. All SDK modules are included in one file: “nlsSDK600.bundle.min.js”.&lt;br /&gt;
&lt;br /&gt;
=== Create Metadata Objects ===&lt;br /&gt;
Before starting any measurement of an asset(Content or Ad) with the created SDK Instance, you need to create an asset metadata object in order to identify the asset. &lt;br /&gt;
There are two types of asset metadata:&lt;br /&gt;
*content: identify a video&lt;br /&gt;
*ad: identify each ad&lt;br /&gt;
&lt;br /&gt;
The metadata received for each asset is used for classification and reporting.&lt;br /&gt;
&lt;br /&gt;
Metadata are passed through key-values using the Nielsen reserved keys. You will need to set up content and ad objects with the required Nielsen keys as shown in the sample code below.&lt;br /&gt;
&lt;br /&gt;
==== Create Content Metadata ====&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type ||	type of asset	|| &amp;quot;content&amp;quot; for main content	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid	|| unique ID assigned to asset 	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| program	|| name of program 	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| title	|| episode name	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| length	|| length of content in seconds	|| Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||	✓&lt;br /&gt;
|-&lt;br /&gt;
| airdate	|| the original date (local time with hh:mm:ss as 24h time stamp) content became available. This date does not change if the content is rebroadcasted on linear TV. ||	YYYYMMDD HH:MI:SS (if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot;)	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode	|| full episode flag ||	&lt;br /&gt;
* &amp;quot;y&amp;quot; full episode (full content for a program)&lt;br /&gt;
* &amp;quot;n&amp;quot; non full episode (only one part of the entire content for a program , i.e. preview, sub-episodes)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
|adloadtype	|| type of Ad load&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;1&amp;quot; Linear - matches TV ad load &lt;br /&gt;
* &amp;quot;2&amp;quot; Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|}&lt;br /&gt;
   &lt;br /&gt;
===== Example Content Object =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var contentMetadataObject =&lt;br /&gt;
{  &lt;br /&gt;
  type:           &amp;quot;content&amp;quot;,&lt;br /&gt;
  assetid:        &amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
  program:        &amp;quot;program name&amp;quot;,&lt;br /&gt;
  title:          &amp;quot;episode title&amp;quot;,&lt;br /&gt;
  length:         &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
  airdate:        &amp;quot;20200713 10:22:00&amp;quot;,&lt;br /&gt;
  isfullepisode:  &amp;quot;y&amp;quot;,&lt;br /&gt;
  adloadtype:     &amp;quot;2&amp;quot;,&lt;br /&gt;
  subbrand:       &amp;quot;c05&amp;quot;,&lt;br /&gt;
  stationId:      &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
  islivestn:      &amp;quot;y&amp;quot;,&lt;br /&gt;
  pbstarttm:    &amp;quot;1631098029&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Create Ad Metadata (optional for DR) ====&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;&amp;quot;preroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;midroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;postroll&amp;quot;&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	|| provided by Nielsen || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Example Ad Object =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var adMetadataObject = &lt;br /&gt;
{  &lt;br /&gt;
  type:           &amp;quot;preroll&amp;quot;,&lt;br /&gt;
  assetid:        &amp;quot;unique_preroll_ad_id&amp;quot;,&lt;br /&gt;
  subbrand:       &amp;quot;c05&amp;quot;,&lt;br /&gt;
  stationId:      &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
  islivestn:      &amp;quot;y&amp;quot;,&lt;br /&gt;
  pbstarttm:    &amp;quot;1631098029&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; URL Character Limit: There is a URL character limit of 2K characters due to browser limitations. Exceeding this value could impair data delivery on particular browsers. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
Nielsen APIs calls are made by calling the function ggPM(&amp;quot;event&amp;quot;, parameter, ...) with &amp;quot;event&amp;quot; Parameter indicating the SDK API.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;event&amp;quot;, parameter, ...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Event !!	Parameter	!! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;loadMetadata&amp;quot;	|| content/ad metadata object	|| Needs to be called at the beginning of each asset&lt;br /&gt;
|--style=&amp;quot;background-color:#d0f6f8;&lt;br /&gt;
|&amp;quot;setPlayheadPosition&amp;quot;	|| playhead position as integer&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content and Ad (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
||&lt;br /&gt;
Pass playhead position every second during playback, the value passed should match the broadcast time for live channel.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;sendID3&amp;quot; || ID3 tag payload retrieved from the stream	|| Call when the video player has read ID3 tag in the stream&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;stop&amp;quot; ||	playhead position in seconds	|| Call when content interrupted/paused or ads complete playing and pass playhead position&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;end&amp;quot;	|| playhead position in seconds	|| Call when the current video asset completes playback and pass the playhead position. &amp;lt;br/&amp;gt;&lt;br /&gt;
Example: At the end of the content stream, if the user switches to another piece of content, when the browser is refreshed or closed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Start the measurement by calling the &amp;quot;event&amp;quot; names &amp;quot;loadMetadata&amp;quot; followed by &amp;quot;setPlayheadPosition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM  (main content)&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
&lt;br /&gt;
=== Handle Video Playback Interruption ===&lt;br /&gt;
The setPlayheadPostion event is used for handling playback interruption. To indicate that the video player is not playing (i.e. paused, buffering), stop passing the playhead position to the SDK. &lt;br /&gt;
Once the Playback resumes , begin sending the playhead position again with the correct playhead value.&lt;br /&gt;
&lt;br /&gt;
=== List of video Playback Interruptions ===&lt;br /&gt;
The following possible  video Playback Interruptions must be handled:&lt;br /&gt;
* Player PAUSED&lt;br /&gt;
* Player BUFFERING&lt;br /&gt;
* Browser/Tab close&lt;br /&gt;
* Leaving the page to another destination&lt;br /&gt;
* Pressing the stop button&lt;br /&gt;
* Network Loss&lt;br /&gt;
&lt;br /&gt;
=== Example for handling Playback Interruption: Browser/Tab close/Page Reload ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function(event) &lt;br /&gt;
{&lt;br /&gt;
  // Only inside an Ad indicate &amp;lt;stop&amp;gt; for the ad&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition);&lt;br /&gt;
  &lt;br /&gt;
  // Indicate &amp;lt;end&amp;gt; for the content&lt;br /&gt;
  nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note:''' additional code may be  needed in order to support specific browser versions (e.g. older versions of Internet Explorer).&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==  Send ID3 Tags when available in the stream ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// ID3 Tag read from the stream (HLS or MPEG-DASH)&lt;br /&gt;
// pass ID3 Tag to SDK&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;sendID3&amp;quot;, id3);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
ID3 Tags are parsed from the Video Stream, refer to the DK Reference Implementation [http://nielsenonlinesupport.com/dk/index.htm sdkRefImplDK] on how to parse ID3 Tags included in a sample HLS Stream.&lt;br /&gt;
For further technical details, please contact your Technical Account Manager (TAM).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SDK Call Sequence ==&lt;br /&gt;
The sample event lifecycles can be used as a reference for identifying the order for calling events.&lt;br /&gt;
&lt;br /&gt;
=== Content Playback Call Sequence ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, contentMetadataObject); &lt;br /&gt;
// CONTENT plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
//&lt;br /&gt;
// pass ID3 Tag immediately when available in the Video Stream&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;sendID3&amp;quot;, id3);&lt;br /&gt;
//&lt;br /&gt;
// END OF STREAM&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;end&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ad Playback Call Sequence (Optional for DR) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// START OF Ad&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;loadMetadata&amp;quot;, adMetadataObject); &lt;br /&gt;
// Ad plays&lt;br /&gt;
// pass playhead every second&lt;br /&gt;
//   &lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;setPlayheadPosition&amp;quot;, playheadPosition);&lt;br /&gt;
// END OF Ad&lt;br /&gt;
nSdkInstance.ggPM(&amp;quot;stop&amp;quot;, playheadPosition);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
* &amp;quot;setPlayheadPosition&amp;quot; is used for calculating duration and must be passed every second. The final playhead position must be sent for the current asset being played before calling &amp;quot;stop&amp;quot; or &amp;quot;end&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* For Ad Pods, events must be called for each individual Ad. Each Ad playhead position should begin at &amp;quot;0&amp;quot; when an ad starts.&lt;br /&gt;
&lt;br /&gt;
* When content has resumed following an ad break, the playhead position update must continue where previous content segment left off. &lt;br /&gt;
* The playhead position should be passed as a rounded number with no decimals.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Review SDK Integration Architecture Diagram ===&lt;br /&gt;
&lt;br /&gt;
==== For Content Playback ====&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== For Ad Playback ====&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
==  Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers vod and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll and postroll Ads.&lt;br /&gt;
&lt;br /&gt;
In order to start live stream select the checkbox &amp;quot;isLive&amp;quot; below the video player.&lt;br /&gt;
&lt;br /&gt;
Start the Reference Implementation for DK [http://nielsenonlinesupport.com/dk/index.htm sdkRefImplDK].&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Review the Nielsen SDK Call Sequence below the Video Player.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The Browser SDK video measurement does not set cross-domain cookies, therefore no centralized opt-out functionality is available. The Nielsen Browser SDK does not set cookies associated with the collection domain. The SDK sets specific cookie for the domain where the player is hosted (first party) and this cookie is not used across websites.&lt;br /&gt;
The only personal information collected with the SDK network pings is the IP address, which is  anonymized immediately after collection.&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=da .&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with enableFpid =====&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned on ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
enableFpid: &amp;quot;true&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned off ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
nSdkInstance = NOLBUNDLE.nlsQ(appID, &amp;quot;videoSdkInstance&amp;quot;, {&lt;br /&gt;
enableFpid: &amp;quot;false&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Run your player in the Browser, start a video&amp;lt;br /&amp;gt;&lt;br /&gt;
2. Open the Developer Network View in order to monitor network traffic&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Filter the network traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-dmk.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Provide your app for certification ==&lt;br /&gt;
Once ready please send your application to Nielsen local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_sdkDebug: &amp;quot;DEBUG&amp;quot;} from Initialization API Call.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_iOS_SDK&amp;diff=7574</id>
		<title>DCR Denmark Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Denmark_Video_iOS_SDK&amp;diff=7574"/>
		<updated>2026-03-06T13:44:21Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Step 7 : Disclose Nielsen Privacy Statement */ add enableFPID API for compatibility with BSDK&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''Nielsen SDK''' || Includes SDK frameworks and '''sample implementation'''; &amp;quot;See [[iOS SDK Release Notes]]&amp;quot; || [[Special:Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Step 1: Setting up your iOS Development Environment ==&lt;br /&gt;
&lt;br /&gt;
=== Special Notes regarding iOS17 or TVOS17 ===&lt;br /&gt;
Beginning with iOS/TVOS 17, Apple is adding several requirements for App developers around tracking, use of Identifier For Advertisers (IDFA), and certain system APIs.&lt;br /&gt;
&lt;br /&gt;
This requirement entails users manually opting in to declare all domains employed for tracking purposes, which includes the collection of IDFAs (Identifier for Advertisers).&lt;br /&gt;
Currently, even if users choose not to opt in for tracking, it's essential to note that our Nielsen Digital SDKs continue to carry out measurements and transmit data without relying on IDFA. However, this new privacy measure introduced by Apple necessitates that we bring this development to your attention, as it could potentially impact your Nielsen measurement and tracking for iOS app usage.&lt;br /&gt;
&lt;br /&gt;
In order to minimize the impact, we are asking that clients do the following:&lt;br /&gt;
&lt;br /&gt;
* '''Do not declare the Nielsen imrworldwide.com domain in the privacy manifest.'''&lt;br /&gt;
* Update to the latest Nielsen SDK release &amp;gt;= 9.2.0.0 when compiling your app for iOS 17.&lt;br /&gt;
&lt;br /&gt;
For any additional information please refer to the Nielsen global page: [[DCR and DTVR with iOS17 or TVOS17]].&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, the SDK uses the WKWebView class instead of the deprecated UIWebView as per Apple guidelines. &lt;br /&gt;
&lt;br /&gt;
=== Importing Frameworks ===&lt;br /&gt;
&lt;br /&gt;
1) Extract “NielsenAppApi.Framework” from the Nielsen App SDK zip file and copy it to Frameworks folder of the Xcode project.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Import following frameworks and libraries into the Frameworks of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* AdSupport.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework makes use of a number of functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework&lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective-C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Include header file &amp;lt;code&amp;gt;NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller's header file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
* All communications between the SDK and the Census (Collection Facility) use HTTPS&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
Add the code&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified ||  ✓ || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' ||  || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App Version included in the App Resource File''' ||  || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified ||  || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
            &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted NSString or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt; program and title metadata values should be passed to SDK as UTF-8 strings. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type ||	type of asset	|| &amp;quot;content&amp;quot; for main content	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid	|| unique ID assigned to asset 	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| program	|| name of program 	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| title	|| episode name	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| length	|| length of content in seconds	|| Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||	✓&lt;br /&gt;
|-&lt;br /&gt;
| airdate	|| the original date (local time with hh:mm:ss as 24h time stamp) content became available. This date does not change if the content is rebroadcasted on linear TV. ||	YYYYMMDD HH:MI:SS (if not known set it to eg. &amp;quot;19700101 00:00:00&amp;quot;)	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| isfullepisode	|| full episode flag ||	&lt;br /&gt;
* &amp;quot;y&amp;quot; full episode (full content for a program)&lt;br /&gt;
* &amp;quot;n&amp;quot; non full episode (only one part of the entire content for a program , i.e. preview, sub-episodes)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
|adloadtype	|| type of Ad load&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;1&amp;quot; Linear - matches TV ad load &lt;br /&gt;
* &amp;quot;2&amp;quot; Dynamic - Dynamic Ad Insertion (DAI)&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Ad Metadata (optional for DR) ===&lt;br /&gt;
The Ad Metadata (if applicable) should be passed for each individual ad.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys	!! Description	!! Values	!! Required&lt;br /&gt;
|-&lt;br /&gt;
| type 	|| type of Ad	||  &amp;lt;code&amp;gt;&amp;quot;preroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;midroll&amp;quot;&amp;lt;/code&amp;gt;,  &amp;lt;code&amp;gt;&amp;quot;postroll&amp;quot;&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt; &amp;lt;code&amp;gt;&amp;quot;ad&amp;quot;&amp;lt;/code&amp;gt;  - If specific type can not be identified.||	✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid ||	unique ID assigned to Ad	|| custom&amp;lt;br&amp;gt;(no [[Special Characters]])	|| ✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|stationId	|| Unique Gracenote Station ID generated by Nielsen that uniquely identifies a live channel&lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|islivestn	|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|pbstarttm	|| Playback Start Time (UTC): Unix timestamp in seconds matching the broadcast time for Content and Ad when a user starts and joins a live stream (seconds since Jan-1-1970 UTC)&lt;br /&gt;
||&lt;br /&gt;
i.e. &amp;quot;1631098029&amp;quot; for live stream and &amp;quot;&amp;quot;(empty string) for a VoD.&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand	|| vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App) 	|| provided by Nielsen || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
  @&amp;quot;assetid&amp;quot; : &amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
  @&amp;quot;type&amp;quot; : &amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
  @&amp;quot;airdate&amp;quot; : &amp;quot;20161013 20:00:00&amp;quot;,&lt;br /&gt;
  @&amp;quot;isfullepisode&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
  @&amp;quot;adloadtype&amp;quot; : &amp;quot;2&amp;quot;,&lt;br /&gt;
  @&amp;quot;subbrand&amp;quot; : &amp;quot;c05&amp;quot;,&lt;br /&gt;
  @&amp;quot;stationId&amp;quot; : &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
  @&amp;quot;islivestn&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
  @&amp;quot;pbstarttm&amp;quot; : &amp;quot;1631098029&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary *adMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
  @&amp;quot;assetid&amp;quot; : &amp;quot;unique_postroll_ad_id&amp;quot;,&lt;br /&gt;
  @&amp;quot;type&amp;quot; : &amp;quot;postroll&amp;quot;,&lt;br /&gt;
  @&amp;quot;subbrand&amp;quot; : &amp;quot;c05&amp;quot;,&lt;br /&gt;
  @&amp;quot;stationId&amp;quot; : &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
  @&amp;quot;islivestn&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
  @&amp;quot;pbstarttm&amp;quot; : &amp;quot;1631098029&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
     let channelInfo = [&lt;br /&gt;
        &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
     let contentMetadata = [&lt;br /&gt;
       &amp;quot;assetid&amp;quot; : &amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot; : &amp;quot;content&amp;quot;,&lt;br /&gt;
        &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
        &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
        &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
        &amp;quot;airdate&amp;quot; : &amp;quot;20200713 10:22:00&amp;quot;,&lt;br /&gt;
        &amp;quot;isfullepisode&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
        &amp;quot;adloadtype&amp;quot; : &amp;quot;2&amp;quot;,&lt;br /&gt;
        &amp;quot;subbrand&amp;quot; : &amp;quot;c05&amp;quot;,&lt;br /&gt;
        &amp;quot;stationId&amp;quot; : &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
        &amp;quot;islivestn&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
        &amp;quot;pbstarttm&amp;quot; : &amp;quot;1631098029&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
    let adMetadata = [&lt;br /&gt;
        &amp;quot;assetid&amp;quot; : &amp;quot;unique_postroll_ad_id&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot; : &amp;quot;postroll&amp;quot;,&lt;br /&gt;
        &amp;quot;subbrand&amp;quot; : &amp;quot;c05&amp;quot;,&lt;br /&gt;
        &amp;quot;stationId&amp;quot; : &amp;quot;TESTXXYYSSWWLL&amp;quot;,&lt;br /&gt;
        &amp;quot;islivestn&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
        &amp;quot;pbstarttm&amp;quot; : &amp;quot;1631098029&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player. Call play only when initially starting the video.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi play:channelInfo];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.play(channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content or ad. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi loadMetadata:metadataDict];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(metadataDict)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
Note: &amp;quot;playheadPosition&amp;quot; has to be called every second and the value passed should match the broadcast time for live channel.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content and Ad (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
[self.nielsenAppApi playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== sendID3 ====&lt;br /&gt;
Needs to be called when ID3 Tags are included in the Video Stream.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi sendID3:id3];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.sendID3(id3)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
ID3 Tags are parsed from the Video Stream, refer to the DK Reference Implementation [http://nielsenonlinesupport.com/dk/index.htm sdkRefImplDK] on how to parse ID3 Tags included in a sample HLS Stream.&lt;br /&gt;
For further technical details, please contact your Technical Account Manager (TAM).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
In order to start the measurement, follow the 3 first steps below i.e. for Content without Ads. When terminating the Content playback call &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; to terminate the Content Measurement for the given asset.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Playlist !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 1. Start of stream || &amp;lt;code&amp;gt;play(channelName)&amp;lt;/code&amp;gt; || channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;loadMetadata(contentMetadataObject)&amp;lt;/code&amp;gt; || contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| 2. Content is playing|| &amp;lt;code&amp;gt;playheadPosition(position)&amp;lt;/code&amp;gt; || playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| || &amp;lt;code&amp;gt;sendID3(id3)&amp;lt;/code&amp;gt; || id3 is an ID3 Tag parsed from the Video Stream, pass ID3 Tag immediately to SDK when found&lt;br /&gt;
|-&lt;br /&gt;
| 3. End of Stream || &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; || Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 5: Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the current viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Step 6: Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-v1.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
=== For Ad Playback ===&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-ad-v1.png||SDK Integration Architecture Diagram - Ad]]&lt;br /&gt;
&lt;br /&gt;
== Step 7 : Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The App SDK uses Mobile Ad IDs (Android ID or IDFA) which are fully hashed on the device before being sent to Nielsen (Nielsen never receives un-hashed values).&lt;br /&gt;
Users retain the possibility to oppose the use of Mobile Ad IDs, or to reset them, by using the functionality provided by the mobile operating system (iOS or Android).&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=da .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the iOS AppSDK. For Opt-out users, the First Party ID can be turned off during the initialization of the AppSDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
==== Example of SDK Initialization with enableFpid ====&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned on =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;true&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned off =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;false&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;false&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 8 : Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers VoD and Live use cases. &lt;br /&gt;
It also covers DAI (Dynamic Ad Insertion) with  preroll Ad.&lt;br /&gt;
&lt;br /&gt;
Download the Reference Implementation for iOS [https://nielsenonlinesupport.com/dk/ios/DKRefImplSwift.zip DKRefImplSwift].&lt;br /&gt;
Unzip and open the project in Xcode, then run it i.e. in the simulator or on iOS device and then filter the Xcode output with &amp;quot;##&amp;quot; in order to see only relevant Nielsen SDK API Calls, as below:&lt;br /&gt;
&amp;lt;syntaxhighlight&lt;br /&gt;
==##&amp;gt; Nielsen SDK NielsenInit.getAppApi() - create Instance &lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
==##!!&amp;gt; LandingVC -- Nielsen SDK eventOccurred&lt;br /&gt;
==##&amp;gt; Nielsen SDK .play(sdkMethods.loadChannelInfo())&lt;br /&gt;
==##&amp;gt; Nielsen SDK nielsenApi.loadMetadata&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 0 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 1 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 2 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 3 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 4 / 378&lt;br /&gt;
==##&amp;gt; terminatePlaybackSession Nielsen SDK end()&lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-dmk.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Provide your app for certification ==&lt;br /&gt;
Once ready please send your application to Nielsen local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 11 :  Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_devDebug: &amp;quot;DEBUG&amp;quot;} from initialization call - see Step 2.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Android_SDK&amp;diff=7573</id>
		<title>DCR France Video Android SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Android_SDK&amp;diff=7573"/>
		<updated>2026-03-06T13:39:07Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Turning off the First Party ID for Opt-out Users during the SDK Initialization */ typo BSDK updated to AppSDK&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like  It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
*Time of viewing a sub section / page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;App ID (appid)&amp;quot; || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;Nielsen SDK&amp;quot; || The Nielsen Digital AppSDK which includes SDK frameworks and &amp;quot;sample implementation&amp;quot;; &amp;quot;See [[Android SDK Release Notes]]&amp;quot; || [[DCR France SDK Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market! The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 1: Setting up your Android Development Environment  ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
1) Ensure to unzip the Nielsen App SDK zip file and copy the &amp;quot;AppSdk.jar&amp;quot; into the app/libs folder on the App’s project. Add it as dependency.&amp;lt;br /&amp;gt;&lt;br /&gt;
2) Add the following permissions on the project’s &amp;quot;AndroidManifest.xml&amp;quot; file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) Add Google Play Services lib into dependencies as Nielsen AppSDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
Libraries:&lt;br /&gt;
* com.google.android.gms:play-services&lt;br /&gt;
Requiered Google Play Service CLasses and Packages :&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient;&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
4) Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;import com.nielsen.app.sdk.*;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
*The Nielsen App SDK (located in the &amp;quot;com.nielsen.app.sdk&amp;quot; package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*Nielsen App SDK is compatible with Android OS versions 2.3+.&lt;br /&gt;
*Clients can control / configure the protocol to be used – HTTPS or HTTP to suit their needs.&lt;br /&gt;
*The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 4.0 and later will support it natively).&lt;br /&gt;
*If the player application uses a 3rd party media player implementing its own HLS/MPEG-DASH stack, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' ||  || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App version included in the App Resource File''' ||  || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified || || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified ||  || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) AppSDK() is no longer a singleton object and should be created as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;hem_sha1&amp;quot;, &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;uid2&amp;quot;, &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;hem_sha256&amp;quot;, &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
2) implement IAppNotifier into your activity like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public class MainActivity extends AppCompatActivity implements IAppNotifier&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) implement callback&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;@Override&lt;br /&gt;
public void onAppSdkEvent(long timestamp, int code, String description){&lt;br /&gt;
  Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So whole Activity will look like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.example.josefvancura.nlsdemotmp;&lt;br /&gt;
&lt;br /&gt;
import android.content.Context;&lt;br /&gt;
import android.support.v7.app.AppCompatActivity;&lt;br /&gt;
import android.os.Bundle;&lt;br /&gt;
import android.util.Log;&lt;br /&gt;
&lt;br /&gt;
import com.nielsen.app.sdk.*;&lt;br /&gt;
&lt;br /&gt;
import org.json.JSONException;&lt;br /&gt;
import org.json.JSONObject;&lt;br /&gt;
&lt;br /&gt;
public class MainActivity extends AppCompatActivity implements IAppNotifier {&lt;br /&gt;
&lt;br /&gt;
    private AppSdk mAppSdk = null;&lt;br /&gt;
    private String TAG = &amp;quot;MainActivity&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void onCreate(Bundle savedInstanceState) {&lt;br /&gt;
        super.onCreate(savedInstanceState);&lt;br /&gt;
        setContentView(R.layout.activity_main);&lt;br /&gt;
&lt;br /&gt;
        Context context = getApplicationContext();&lt;br /&gt;
&lt;br /&gt;
        try{&lt;br /&gt;
            // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
            JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
                    .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
            // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
            mAppSdk = new AppSdk(context, appSdkConfig, this ); // Notifier - activity implements IAppNotifier, callback in onAppSdkEvent()&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (JSONException e){&lt;br /&gt;
            Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onAppSdkEvent(long timestamp, int code, String description) {&lt;br /&gt;
        Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# &amp;quot;&amp;quot;Initial state&amp;quot;&amp;quot; – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the &amp;quot;&amp;quot;Initial state&amp;quot;&amp;quot;.&lt;br /&gt;
# &amp;quot;&amp;quot;Idle state&amp;quot;&amp;quot; – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# &amp;quot;&amp;quot;Processing state&amp;quot;&amp;quot; – The SDK instance is processing playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# &amp;quot;&amp;quot;Disabled state&amp;quot;&amp;quot; – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
   .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;assetid&amp;quot;, &amp;quot;unique_content_id&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;program&amp;quot;, &amp;quot;program name&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;length&amp;quot;, &amp;quot;length in seconds&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;islivestn&amp;quot;, &amp;quot;y&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;subbrand&amp;quot;, &amp;quot;c05&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;cli_md&amp;quot;, &amp;quot;LIVE&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;cli_ch&amp;quot;, &amp;quot;860&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;cli_cn&amp;quot;, &amp;quot;customContentIdentifier&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;nol_p0&amp;quot;, &amp;quot;p0,optionalValueP0&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;nol_p1&amp;quot;, &amp;quot;p1,optionalValueP1&amp;quot;)&lt;br /&gt;
   // ...&lt;br /&gt;
   .put(&amp;quot;nol_p18&amp;quot;, &amp;quot;p18,optionalValueP18&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;nol_p19&amp;quot;, &amp;quot;p19,optionaValuelP19&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the &amp;quot;&amp;quot;Play&amp;quot;&amp;quot; button on the player. Call play only when initially starting the video.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
Note: &amp;quot;setPlayheadPosition&amp;quot; has to be called every second and the value passed should match the broadcast time for live channel.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;mAppSdk.setPlayheadPosition(long videoPositon);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* when an Ad Break starts during the Content Playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.stop();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.end();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
In order to start the measurement, follow the 3 first steps below for Content without Ads. When terminating the Content playback call &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; to terminate the Content Measurement for the given asset.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Playlist !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 1. Start of stream || &amp;lt;code&amp;gt;play(channelName)&amp;lt;/code&amp;gt; || channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;loadMetadata(contentMetadataObject)&amp;lt;/code&amp;gt; || contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| 2. Content is playing || &amp;lt;code&amp;gt;playheadPosition(position)&amp;lt;/code&amp;gt; || playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| 3. End of Stream || &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; || Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 5: Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the new viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Step 6: Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Step 7 : Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The App SDK uses Mobile Ad IDs (Android ID or IDFA) which are fully hashed on the device before being sent to Nielsen (Nielsen never receives un-hashed values).&lt;br /&gt;
Users retain the possibility to oppose the use of Mobile Ad IDs, or to reset them, by using the functionality provided by the mobile operating system (iOS or Android).&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Android AppSDK. For Opt-out users, the First Party ID can be turned off during the initialization of the AppSDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with enableFpid =====&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned on ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned off ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users  ===&lt;br /&gt;
&lt;br /&gt;
The Optout Flag is set by default to &amp;quot;false&amp;quot; in the AppSDK. &lt;br /&gt;
&lt;br /&gt;
For Opt-out users, the Optout Flag can be set accordingly while Initializing the SDK Instance.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Example the Ouptout Flag =====&lt;br /&gt;
&lt;br /&gt;
====== User opted out ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;optout&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== User opted in======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 8 : Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers VoD and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion)  that should be ignored since No Ads are measured in France.&lt;br /&gt;
&lt;br /&gt;
Download the Reference Implementation for Android [https://nielsenonlinesupport.com/dk/android/DKRefPLAYER.zip DKRefPLAYER].&lt;br /&gt;
Unzip and open the project in Android Studio, then run it i.e. in the simulator or on Android device and then filter the Logcat output with &amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;quot; in order to see only relevant Nielsen SDK API Calls, as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
2021-04-08 15:11:27.075  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : class NielsenInit :: Create new AppSdk() Instance.&lt;br /&gt;
2021-04-08 15:11:27.568  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK EVENT - onAppSdkEvent: Description = Nielsen App SDK is initiated. AppSdk.jar aa.8.0.0.0_gsxaon. App SDK was successfully initiatedCode l param : 1617887487Code i param 2000&lt;br /&gt;
2021-04-08 15:11:29.497  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK EVENT - onAppSdkEvent: Description = Nielsen App SDK has started up. AppSdk.jar aa.8.0.0.0_gsxaon. Config file successfully loaded and parsed.Code l param : 1617887489Code i param 2001&lt;br /&gt;
2021-04-08 15:11:42.736  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :  appSdk.play(sdkMethods.loadChannelInfo());&lt;br /&gt;
2021-04-08 15:11:42.738  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : onPrepared() : appSdk.loadMetadata(data)&lt;br /&gt;
2021-04-08 15:11:43.065  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Media Player Event : onInfo ();what = 3&lt;br /&gt;
2021-04-08 15:11:43.065  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Media Player Event :  first video frame pushed for rendering.&lt;br /&gt;
2021-04-08 15:11:43.747  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 0 / 224&lt;br /&gt;
2021-04-08 15:11:44.752  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 1 / 224&lt;br /&gt;
2021-04-08 15:11:45.759  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 2 / 224&lt;br /&gt;
2021-04-08 15:11:46.764  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 3 / 224&lt;br /&gt;
2021-04-08 15:11:47.767  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 4 / 224&lt;br /&gt;
2021-04-08 15:11:48.772  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 5 / 224&lt;br /&gt;
2021-04-08 15:11:49.777  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 6 / 224&lt;br /&gt;
2021-04-08 15:11:50.781  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 7 / 224&lt;br /&gt;
2021-04-08 15:11:51.819  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 8 / 224&lt;br /&gt;
2021-04-08 15:11:51.821  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Activity onPause()&lt;br /&gt;
2021-04-08 15:11:52.668  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt;: Activity onDestroy()&lt;br /&gt;
2021-04-08 15:11:52.668  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : terminateNielsenSDK () :appSdk.end();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 11 :  Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_devDebug: &amp;quot;DEBUG&amp;quot;} from initialization call - see Step 2.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_iOS_SDK&amp;diff=7572</id>
		<title>DCR France Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_iOS_SDK&amp;diff=7572"/>
		<updated>2026-03-06T13:36:14Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Turning off the First Party ID for Opt-out Users during the SDK Initializazion */ typo BSDK updated to AppSDK&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''Nielsen SDK''' || The Nielsen Digital AppSDK which includes SDK frameworks and '''sample implementation'''; &amp;quot;See [[iOS SDK Release Notes]]&amp;quot; || [[DCR France SDK Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 1: Setting up your iOS Development Environment ==&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, the SDK uses the WKWebView class instead of the deprecated UIWebView as per Apple guidelines. &lt;br /&gt;
&lt;br /&gt;
=== Importing Frameworks ===&lt;br /&gt;
&lt;br /&gt;
1) Extract “NielsenAppApi.Framework” from the Nielsen App SDK zip file and copy it to Frameworks folder of the Xcode project.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Import following frameworks and libraries into the Frameworks of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* AdSupport.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework makes use of a number of functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework&lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective-C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Include header file &amp;lt;code&amp;gt;NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller's header file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
* All communications between the SDK and the Census (Collection Facility) use HTTPS&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
Add the code&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified ||  ✓ || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' ||  || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App Version included in the App Resource File''' ||  || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified || || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified ||  || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;hem_sha1&amp;quot;: @&amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
            @&amp;quot;uid2&amp;quot;: @&amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
            @&amp;quot;hem_sha256&amp;quot;: @&amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;true&amp;quot;,&lt;br /&gt;
           @&amp;quot;optout&amp;quot;: @&amp;quot;false&amp;quot;,&lt;br /&gt;
           @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
           &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
           &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## appDisableApi is called&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted NSString or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
  @&amp;quot;assetid&amp;quot; : @&amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
  @&amp;quot;type&amp;quot; : @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot; : @&amp;quot;program name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot; : @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot; : @&amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
  @&amp;quot;islivestn&amp;quot; : @&amp;quot;y&amp;quot;,&lt;br /&gt;
  @&amp;quot;subbrand&amp;quot; : @&amp;quot;c05&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_md&amp;quot; : @&amp;quot;LIVE&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_ch&amp;quot; : @&amp;quot;860&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_cn&amp;quot; : @&amp;quot;customContentIdentifier&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p0&amp;quot; : @&amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p1&amp;quot; : @&amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
  // ...&lt;br /&gt;
  @&amp;quot;nol_p18&amp;quot; : @&amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p19&amp;quot; : @&amp;quot;p19,optionalValueP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
     let channelInfo = [&lt;br /&gt;
        &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
     let contentMetadata = [&lt;br /&gt;
       &amp;quot;assetid&amp;quot; : &amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot; : &amp;quot;content&amp;quot;,&lt;br /&gt;
        &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
        &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
        &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
        &amp;quot;islivestn&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
        &amp;quot;subbrand&amp;quot; : &amp;quot;c05&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_md&amp;quot; : &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_ch&amp;quot; : &amp;quot;860&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_cn&amp;quot; : &amp;quot;customContentIdentifier&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p0&amp;quot; : &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p1&amp;quot; : &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
        // ...&lt;br /&gt;
        &amp;quot;nol_p18&amp;quot; : &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p19&amp;quot; : &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player. Call play only when initially starting the video.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi play:channelInfo];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.play(channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi loadMetadata:metadataDict];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(metadataDict)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
Note: &amp;quot;playheadPosition&amp;quot; has to be called every second and the value passed should match the broadcast time for live channel.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
[self.nielsenAppApi playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* when an Ad Break starts during the Content Playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
In order to start the measurement, follow the 3 first steps below i.e. for Content without Ads. When terminating the Content playback call &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; to terminate the Content Measurement for the given asset.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Playlist !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 1. Start of stream || &amp;lt;code&amp;gt;play(channelName)&amp;lt;/code&amp;gt; || channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;loadMetadata(contentMetadataObject)&amp;lt;/code&amp;gt; || contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| 2. Content is playing|| &amp;lt;code&amp;gt;playheadPosition(position)&amp;lt;/code&amp;gt; || playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| 3. End of Stream || &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; || Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 5: Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* When an Ad Break starts during the Content Playback&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the current viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Step 6: Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
== Step 7 : Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The App SDK uses Mobile Ad IDs (Android ID or IDFA) which are fully hashed on the device before being sent to Nielsen (Nielsen never receives un-hashed values).&lt;br /&gt;
Users retain the possibility to oppose the use of Mobile Ad IDs, or to reset them, by using the functionality provided by the mobile operating system (iOS or Android).&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initialization ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the iOS AppSDK. For Opt-out users, the First Party ID can be turned off during the initialization of the AppSDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
==== Example of SDK Initialization with enableFpid ====&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned on =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;true&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned off =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;false&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;false&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Optout Flag is set by default to &amp;quot;false&amp;quot; in the AppSDK. &lt;br /&gt;
&lt;br /&gt;
For Opt-out users, the Optout Flag can be set accordingly while Initializing the SDK Instance.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example the Ouptout Flag ====&lt;br /&gt;
&lt;br /&gt;
===== User opted out =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
          @&amp;quot;optout&amp;quot;: @&amp;quot;true&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User opted in =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
          @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
          @&amp;quot;optout&amp;quot;: @&amp;quot;false&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;false&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 8 : Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers VoD and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion) that should be ignored since No Ads are measured in France.&lt;br /&gt;
&lt;br /&gt;
Download the Reference Implementation for iOS [https://nielsenonlinesupport.com/dk/ios/DKRefImplSwift.zip DKRefImplSwift].&lt;br /&gt;
Unzip and open the project in Xcode, then run it i.e. in the simulator or on iOS device and then filter the Xcode output with &amp;quot;##&amp;quot; in order to see only relevant Nielsen SDK API Calls, as below:&lt;br /&gt;
&amp;lt;syntaxhighlight&lt;br /&gt;
==##&amp;gt; Nielsen SDK NielsenInit.getAppApi() - create Instance &lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
==##!!&amp;gt; LandingVC -- Nielsen SDK eventOccurred&lt;br /&gt;
==##&amp;gt; Nielsen SDK .play(sdkMethods.loadChannelInfo())&lt;br /&gt;
==##&amp;gt; Nielsen SDK nielsenApi.loadMetadata&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 0 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 1 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 2 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 3 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 4 / 378&lt;br /&gt;
==##&amp;gt; terminatePlaybackSession Nielsen SDK end()&lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 11 :  Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_devDebug: &amp;quot;DEBUG&amp;quot;} from initialization call - see Step 2.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7522</id>
		<title>DCR France Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7522"/>
		<updated>2026-01-28T14:25:13Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* query param list */ ping examples updated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S(Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (apid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.) || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have it’s own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but latest within 3 hour of the start of that hourly&lt;br /&gt;
viewing file interval. For example files from 1:00 AM to 2:00 AM must be delivered latest before 4 AM.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicite request from Médiamétrie.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported format are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delived to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0000_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0001_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0002_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0003_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710154800&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710158399&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 15&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Note:''' ''' Do not include personal data '''in the content metadata.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname   || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || episode name || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen    || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand  || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|-&lt;br /&gt;
| cli_md || mode: allows to know the streaming type || possible values provided by Médiamétrie: &amp;quot;LIVE&amp;quot; &amp;quot;TIMESHIFTING&amp;quot; &amp;quot;TVOD&amp;quot; &amp;quot;VOD&amp;quot; &amp;quot;SVOD&amp;quot; &amp;quot;AOD&amp;quot;|| &lt;br /&gt;
|-&lt;br /&gt;
| cli_ch    || Channel identifier: values decided by Médiamétrie and provided to the broadcaster || sample value: &amp;quot;860&amp;quot; || &lt;br /&gt;
|-&lt;br /&gt;
| cli_cn    || content identifier as used / categorized by the publisher    || custom   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_p0    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character ) &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p1    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p2    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p3    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p4    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p5    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p6    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p7    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p8    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p9    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p10   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p11   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p12   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p13   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p14   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p15   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p16   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p17   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p18   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p19   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_md&amp;quot;: &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_ch&amp;quot;: &amp;quot;860&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_cn&amp;quot;: &amp;quot;customCuntentIdentifier&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p0&amp;quot;: &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p1&amp;quot;: &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
    // ... continued - 20 custom variables&lt;br /&gt;
    &amp;quot;nol_p18&amp;quot;: &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p19&amp;quot;: &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please do not include ZERO DURATION viewing portion in the Asset Viewing File.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''MANDATORY ONLY for android platform.''' Mobile Ad ID IDFA,ADID, Connected Device ID  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|-&lt;br /&gt;
| fpid || First Party ID || created using the UUID Generator code provided / validity time 180 days. || &lt;br /&gt;
|-&lt;br /&gt;
| fpcrtm || Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds) || custom || &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||    hashed (SHA256) value of member id || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||    hashed(SHA256) value of UID2 || i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is i.e. &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||  hashed(SHA256) value of the user email address  ||   i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uoo ||  device opt-out status  || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in.  ||  ✓&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    &amp;quot;device_id&amp;quot;: &amp;quot;8ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha1&amp;quot;: &amp;quot;9ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    &amp;quot;uoo&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
    &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
    &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Metadata based on User Consent in your App =====&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly accepts measurement ======&lt;br /&gt;
 All Device/User IDs are captured in the Nielsen S2S Metadata. The Opt-in Flag is set to &amp;quot;false&amp;quot; and all IDs have to be set accordingly:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly refuses measurement ======&lt;br /&gt;
The Nielsen S2S is NOT initiated and No Nielsen S2S measurement will occur.&lt;br /&gt;
&lt;br /&gt;
======The user did not explicitly give consent for the measurement(consent neither given nor refused) ======&lt;br /&gt;
 The Nielsen S2S is initiated and no IDs are captured. The Nielsen S2S Opt-out Flag is set to &amp;quot;true&amp;quot; and all Device/User IDs are empty:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || devid,  SHA-256 value of Device Id (IDFA, ADID) -  OPTIONAL is passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| uoo || device opt-out status  || &amp;quot;true&amp;quot; for opted out, &amp;quot;false&amp;quot; for NOT opted out or opted in.|| ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;intid=&amp;lt;Integration ID&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;uoo=&amp;lt;Optout Status &amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;Android ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;&amp;amp;intid=xxxxxxxx&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;uoo=false&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7519</id>
		<title>DCR France Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7519"/>
		<updated>2026-01-23T15:31:41Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* query param list */  missing uoo added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S(Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (apid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.) || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have it’s own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but latest within 3 hour of the start of that hourly&lt;br /&gt;
viewing file interval. For example files from 1:00 AM to 2:00 AM must be delivered latest before 4 AM.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicite request from Médiamétrie.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported format are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delived to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0000_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0001_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0002_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0003_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710154800&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710158399&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 15&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Note:''' ''' Do not include personal data '''in the content metadata.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname   || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || episode name || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen    || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand  || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|-&lt;br /&gt;
| cli_md || mode: allows to know the streaming type || possible values provided by Médiamétrie: &amp;quot;LIVE&amp;quot; &amp;quot;TIMESHIFTING&amp;quot; &amp;quot;TVOD&amp;quot; &amp;quot;VOD&amp;quot; &amp;quot;SVOD&amp;quot; &amp;quot;AOD&amp;quot;|| &lt;br /&gt;
|-&lt;br /&gt;
| cli_ch    || Channel identifier: values decided by Médiamétrie and provided to the broadcaster || sample value: &amp;quot;860&amp;quot; || &lt;br /&gt;
|-&lt;br /&gt;
| cli_cn    || content identifier as used / categorized by the publisher    || custom   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_p0    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character ) &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p1    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p2    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p3    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p4    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p5    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p6    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p7    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p8    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p9    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p10   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p11   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p12   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p13   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p14   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p15   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p16   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p17   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p18   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p19   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_md&amp;quot;: &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_ch&amp;quot;: &amp;quot;860&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_cn&amp;quot;: &amp;quot;customCuntentIdentifier&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p0&amp;quot;: &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p1&amp;quot;: &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
    // ... continued - 20 custom variables&lt;br /&gt;
    &amp;quot;nol_p18&amp;quot;: &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p19&amp;quot;: &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please do not include ZERO DURATION viewing portion in the Asset Viewing File.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''MANDATORY ONLY for android platform.''' Mobile Ad ID IDFA,ADID, Connected Device ID  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|-&lt;br /&gt;
| fpid || First Party ID || created using the UUID Generator code provided / validity time 180 days. || &lt;br /&gt;
|-&lt;br /&gt;
| fpcrtm || Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds) || custom || &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||    hashed (SHA256) value of member id || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||    hashed(SHA256) value of UID2 || i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is i.e. &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||  hashed(SHA256) value of the user email address  ||   i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uoo ||  device opt-out status  || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in.  ||  ✓&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    &amp;quot;device_id&amp;quot;: &amp;quot;8ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha1&amp;quot;: &amp;quot;9ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    &amp;quot;uoo&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
    &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
    &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Metadata based on User Consent in your App =====&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly accepts measurement ======&lt;br /&gt;
 All Device/User IDs are captured in the Nielsen S2S Metadata. The Opt-in Flag is set to &amp;quot;false&amp;quot; and all IDs have to be set accordingly:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly refuses measurement ======&lt;br /&gt;
The Nielsen S2S is NOT initiated and No Nielsen S2S measurement will occur.&lt;br /&gt;
&lt;br /&gt;
======The user did not explicitly give consent for the measurement(consent neither given nor refused) ======&lt;br /&gt;
 The Nielsen S2S is initiated and no IDs are captured. The Nielsen S2S Opt-out Flag is set to &amp;quot;true&amp;quot; and all Device/User IDs are empty:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || devid,  SHA-256 value of Device Id (IDFA, ADID) -  OPTIONAL is passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| uoo || device opt-out status  || &amp;quot;true&amp;quot; for opted out, &amp;quot;false&amp;quot; for NOT opted out or opted in.|| ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;sup=&amp;lt;suppress demo look-up&amp;gt;&amp;amp;uoo=&amp;lt;Optout Status &amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;IDFA/ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=false&amp;amp;product=dcr&amp;amp;sup=0&amp;amp;uoo=1&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8'&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Italy_Static_Google_AMP_Cloud_API&amp;diff=7518</id>
		<title>DCR Italy Static Google AMP Cloud API</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Italy_Static_Google_AMP_Cloud_API&amp;diff=7518"/>
		<updated>2026-01-22T10:08:54Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Metadata Keys */  ui minor fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|International DCR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
This guide will show you how to enable Digital Content Ratings (DCR) Static measurement on Google AMP.&lt;br /&gt;
&lt;br /&gt;
== Import AMP Analytics Javascript Library ==&lt;br /&gt;
If you have not already, you will need to import the AMP JS library in the &amp;lt;code&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/code&amp;gt; of your webpage in order to make an AMP page:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;script async src=&amp;quot;https://cdn.ampproject.org/v0.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next, please ensure that the following line is included in the &amp;lt;code&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/code&amp;gt; of the webpage:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;script async custom-element=&amp;quot;amp-analytics&amp;quot; src=&amp;quot;https://cdn.ampproject.org/v0/amp-analytics-0.1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': AMP pages require all traffic to be using HTTPS, including the webpage itself&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Specify the Analytics Provider ==&lt;br /&gt;
DCR measurement can be added to your AMP pages through the AMP-Analytics element:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;amp-analytics type=&amp;quot;nielsen&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;!-- Add Nielsen DCR Tags here --&amp;gt;&lt;br /&gt;
&amp;lt;/amp-analytics&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on the Analytics type, you can refer to the [https://www.ampproject.org/docs/analytics/analytics-vendors Analytics vendors] section of Google's AMP Developer Documentation.&lt;br /&gt;
&lt;br /&gt;
== Configure Metadata ==&lt;br /&gt;
You will need to match the metadata fields on your AMP page with those of your non-AMP page.&lt;br /&gt;
&lt;br /&gt;
=== Metadata Keys ===&lt;br /&gt;
The Nielsen reserved keys are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Example Value !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid || unique ID assigned by Nielsen || &amp;lt;code&amp;gt;XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| prefix  || URL prefix to allow EU data collection|| &amp;lt;code&amp;gt;eu-&amp;lt;/code&amp;gt;  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || current version of the Nielsen implementation || &amp;lt;code&amp;gt;1.0&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apn || name of the website || &amp;lt;code&amp;gt;My AMP Website&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| section || section of the site to be measured || &amp;lt;code&amp;gt;EntityName_AMP&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| segA || custom segment to be used to break out reporting || &amp;lt;code&amp;gt;NA&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| segB || custom segment to be used to break out reporting || &amp;lt;code&amp;gt;NA&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| segC || Reserved custom segment for Google AMP || &amp;lt;code&amp;gt;Google AMP&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| uoo || opt-out parameter, it must be set to true when the user does not explicitly give consent otherwise do not include this uoo parameter in the &amp;quot;vars &amp;quot; section || &amp;lt;code&amp;gt;&amp;quot;uoo&amp;quot;:&amp;quot;true&amp;quot;&amp;lt;/code&amp;gt; || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The values passed through the Nielsen keys will determine the breakouts you will see in reporting. If you decide not to use custom segments A and B, then you do not need to pass a value in these keys. It is suggested you use the same segments used in non-AMP pages.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': The value for the 'apid' you pass for AMP measurement should not include the 'P' prefix that is otherwise present on other SDK-related implementations&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Metadata for Reporting ===&lt;br /&gt;
You can reference the table to determine how the metadata you pass is used to define your reporting structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Reporting Level !! Key !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Brand/Sub-brand || apid || brand and sub-brand are determined by assigned App ID passed during initialization&lt;br /&gt;
|-&lt;br /&gt;
| Section || section || section or category for the AMP page&lt;br /&gt;
|-&lt;br /&gt;
| Custom Segment A || segA || available segment for custom reporting. Custom segments will roll into the sub-brand&lt;br /&gt;
|-&lt;br /&gt;
| Custom Segment B || segB || available segment for custom reporting. Custom segments will roll into the sub-brand&lt;br /&gt;
|-&lt;br /&gt;
| Custom Segment C || segC || Custom segment C is reserved for reporting ‘Google AMP’. The Google AMP custom segment will be available under sub-brand and will include the total metrics for all your AMP pages&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If you would like your AMP pages to report into the same reporting structure as your website, we recommend passing the same dynamic metadata in Section, Custom Segment A, and Custom Segment B as you are on your website. This way your AMP pageviews contribute to those aggregations.&lt;br /&gt;
&lt;br /&gt;
== Example Implementation ==&lt;br /&gt;
The below is an example implementation of Nielsen measurement on an AMP page:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;amp-analytics type=&amp;quot;nielsen&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;script type=&amp;quot;application/json&amp;quot;&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;vars&amp;quot;: {&lt;br /&gt;
        &amp;quot;apid&amp;quot;: &amp;quot;XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
        &amp;quot;prefix&amp;quot;: &amp;quot;eu-&amp;quot;,&lt;br /&gt;
        &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
        &amp;quot;apn&amp;quot;: &amp;quot;My AMP Website&amp;quot;,&lt;br /&gt;
        &amp;quot;section&amp;quot;: &amp;quot;EntityName_AMP&amp;quot;,&lt;br /&gt;
        &amp;quot;segA&amp;quot;: &amp;quot;NA&amp;quot;,&lt;br /&gt;
        &amp;quot;segB&amp;quot;: &amp;quot;NA&amp;quot;,&lt;br /&gt;
        &amp;quot;segC&amp;quot;: &amp;quot;Google AMP&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/amp-analytics&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can find more information about dynamic variables on [https://github.com/ampproject/amphtml/blob/master/spec/amp-var-substitutions.md#page-and-content Google's AMP documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Note''': append &amp;lt;code&amp;gt;#development=1&amp;lt;/code&amp;gt; at the end of your URL to see AMP debug logs in the console. This can be helpful when troubleshooting&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Static Measurement on Google AMP based on User Consent ===&lt;br /&gt;
&lt;br /&gt;
This document addresses the handling of personal data collected through the Google AMP Nielsen integration for Audicom in Italy. The document has a specific focus on the implementation of the user consent use cases to collect personal identifiers (IDs) through Google AMP Nielsen measurement based on the user's privacy choice.&lt;br /&gt;
&lt;br /&gt;
==== Consent granted: the user explicitly accepts ====&lt;br /&gt;
&lt;br /&gt;
====== User opted in ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;amp-analytics type=&amp;quot;nielsen&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;script type=&amp;quot;application/json&amp;quot;&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;vars&amp;quot;: {&lt;br /&gt;
        &amp;quot;apid&amp;quot;: &amp;quot;XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
        &amp;quot;prefix&amp;quot;: &amp;quot;eu-&amp;quot;,&lt;br /&gt;
        &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
        &amp;quot;apn&amp;quot;: &amp;quot;My AMP Website&amp;quot;,&lt;br /&gt;
        &amp;quot;section&amp;quot;: &amp;quot;EntityName_AMP&amp;quot;,&lt;br /&gt;
        &amp;quot;segA&amp;quot;: &amp;quot;NA&amp;quot;,&lt;br /&gt;
        &amp;quot;segB&amp;quot;: &amp;quot;NA&amp;quot;,&lt;br /&gt;
        &amp;quot;segC&amp;quot;: &amp;quot;Google AMP&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/amp-analytics&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Consent denied: the user does not explicitly give consent ====&lt;br /&gt;
Should a Nielsen third party cookie (IMRID) already exist, the browser will send that automatically with the ping; in such a case, the flags would instruct the Nielsen backend to drop the cookie information and make no use of it.&lt;br /&gt;
The client needs to add the '''''uoo''''' parameter with its value equal to '''''true''''' in the '''''&amp;quot;vars&amp;quot;''''' section and the request call in the '''''&amp;quot;requests&amp;quot;''''' section. Please do not modify the request call.&lt;br /&gt;
&lt;br /&gt;
'''Request call:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;requests&amp;quot;: {&lt;br /&gt;
      &amp;quot;cloudapi&amp;quot;: &amp;quot;https://${prefix}cloudapi.imrworldwide.com/nmapi/v2/${apid}/${sessionId}_${pageViewId}/a?b=%7B%22devInfo%22%3A%7B%22devId%22%3A%22${sessionId}_${pageViewId}%22%2C%22apn%22%3A%22${apn}%22%2C%22apv%22%3A%22${apv}%22%2C%22apid%22%3A%22${apid}%22%2C%22uoo%22%3A%22${uoo}%22%7D%2C%22metadata%22%3A%7B%22static%22%3A%7B%22type%22%3A%22static%22%2C%22section%22%3A%22${section}%22%2C%22assetid%22%3A%22${pageViewId}%22%2C%22segA%22%3A%22${segA}%22%2C%22segB%22%3A%22${segB}%22%2C%22segC%22%3A%22${segC}%22%2C%22adModel%22%3A%220%22%2C%22dataSrc%22%3A%22cms%22%7D%2C%22content%22%3A%7B%7D%2C%22ad%22%3A%7B%7D%7D%2C%22event%22%3A%22playhead%22%2C%22position%22%3A%22${timestamp}%22%2C%22data%22%3A%7B%22hidden%22%3A%22${backgroundState}%22%2C%22blur%22%3A%22${backgroundState}%22%2C%22position%22%3A%22${timestamp}%22%7D%2C%22type%22%3A%22static%22%2C%22utc%22%3A%22${timestamp}%22%2C%22index%22%3A%22${requestCount}%22%2C%22pageURL%22%3A%22${ampdocUrl}%22%7D&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== User opted out ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;amp-analytics type=&amp;quot;nielsen&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;script type=&amp;quot;application/json&amp;quot;&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
    &amp;quot;vars&amp;quot;: {&lt;br /&gt;
      &amp;quot;apid&amp;quot;: &amp;quot;XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
      &amp;quot;prefix&amp;quot;: &amp;quot;eu-&amp;quot;,&lt;br /&gt;
      &amp;quot;apv&amp;quot;: &amp;quot;1.0&amp;quot;,&lt;br /&gt;
      &amp;quot;apn&amp;quot;: &amp;quot;My site&amp;quot;,&lt;br /&gt;
      &amp;quot;section&amp;quot;: &amp;quot;EntityName_AMP&amp;quot;,&lt;br /&gt;
      &amp;quot;segA&amp;quot;: &amp;quot;NA&amp;quot;,&lt;br /&gt;
      &amp;quot;segB&amp;quot;: &amp;quot;NA&amp;quot;,&lt;br /&gt;
      &amp;quot;segC&amp;quot;: &amp;quot;Google AMP&amp;quot;,&lt;br /&gt;
      &amp;quot;uoo&amp;quot; : &amp;quot;true&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;requests&amp;quot;: {&lt;br /&gt;
      &amp;quot;cloudapi&amp;quot;: &amp;quot;https://${prefix}cloudapi.imrworldwide.com/nmapi/v2/${apid}/${sessionId}_${pageViewId}/a?b=%7B%22devInfo%22%3A%7B%22devId%22%3A%22${sessionId}_${pageViewId}%22%2C%22apn%22%3A%22${apn}%22%2C%22apv%22%3A%22${apv}%22%2C%22apid%22%3A%22${apid}%22%2C%22uoo%22%3A%22${uoo}%22%7D%2C%22metadata%22%3A%7B%22static%22%3A%7B%22type%22%3A%22static%22%2C%22section%22%3A%22${section}%22%2C%22assetid%22%3A%22${pageViewId}%22%2C%22segA%22%3A%22${segA}%22%2C%22segB%22%3A%22${segB}%22%2C%22segC%22%3A%22${segC}%22%2C%22adModel%22%3A%220%22%2C%22dataSrc%22%3A%22cms%22%7D%2C%22content%22%3A%7B%7D%2C%22ad%22%3A%7B%7D%7D%2C%22event%22%3A%22playhead%22%2C%22position%22%3A%22${timestamp}%22%2C%22data%22%3A%7B%22hidden%22%3A%22${backgroundState}%22%2C%22blur%22%3A%22${backgroundState}%22%2C%22position%22%3A%22${timestamp}%22%7D%2C%22type%22%3A%22static%22%2C%22utc%22%3A%22${timestamp}%22%2C%22index%22%3A%22${requestCount}%22%2C%22pageURL%22%3A%22${ampdocUrl}%22%7D&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/amp-analytics&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Sample Google AMP page ======&lt;br /&gt;
Here is a sample AMP page for Google AMP Nielsen implementation that uses the AMP Consent component.&lt;br /&gt;
&lt;br /&gt;
https://nielsenonlinesupport.com/wilson/ampstatic&lt;br /&gt;
&lt;br /&gt;
AMP Consent component:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&amp;lt;script async custom-element=&amp;quot;amp-consent&amp;quot; src=&amp;quot;https://cdn.ampproject.org/v0/amp-consent-0.1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Privacy Policy ==&lt;br /&gt;
Nielsen uses cookies for browser measurement. In order to comply with our privacy restrictions, we ask that you make a link to our Digital Privacy Policy available on your site. You can find our privacy policy here: https://global.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/?lang=it&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7514</id>
		<title>DCR France Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7514"/>
		<updated>2026-01-21T11:30:29Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* query param list */ missing &amp;quot;product&amp;quot; added as it was present only in the examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S(Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (apid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.) || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have it’s own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but latest within 3 hour of the start of that hourly&lt;br /&gt;
viewing file interval. For example files from 1:00 AM to 2:00 AM must be delivered latest before 4 AM.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicite request from Médiamétrie.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported format are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delived to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0000_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0001_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0002_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0003_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710154800&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710158399&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 15&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Note:''' ''' Do not include personal data '''in the content metadata.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname   || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || episode name || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen    || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand  || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|-&lt;br /&gt;
| cli_md || mode: allows to know the streaming type || possible values provided by Médiamétrie: &amp;quot;LIVE&amp;quot; &amp;quot;TIMESHIFTING&amp;quot; &amp;quot;TVOD&amp;quot; &amp;quot;VOD&amp;quot; &amp;quot;SVOD&amp;quot; &amp;quot;AOD&amp;quot;|| &lt;br /&gt;
|-&lt;br /&gt;
| cli_ch    || Channel identifier: values decided by Médiamétrie and provided to the broadcaster || sample value: &amp;quot;860&amp;quot; || &lt;br /&gt;
|-&lt;br /&gt;
| cli_cn    || content identifier as used / categorized by the publisher    || custom   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_p0    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character ) &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p1    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p2    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p3    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p4    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p5    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p6    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p7    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p8    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p9    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p10   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p11   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p12   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p13   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p14   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p15   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p16   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p17   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p18   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p19   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_md&amp;quot;: &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_ch&amp;quot;: &amp;quot;860&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_cn&amp;quot;: &amp;quot;customCuntentIdentifier&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p0&amp;quot;: &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p1&amp;quot;: &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
    // ... continued - 20 custom variables&lt;br /&gt;
    &amp;quot;nol_p18&amp;quot;: &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p19&amp;quot;: &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please do not include ZERO DURATION viewing portion in the Asset Viewing File.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''MANDATORY ONLY for android platform.''' Mobile Ad ID IDFA,ADID, Connected Device ID  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|-&lt;br /&gt;
| fpid || First Party ID || created using the UUID Generator code provided / validity time 180 days. || &lt;br /&gt;
|-&lt;br /&gt;
| fpcrtm || Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds) || custom || &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||    hashed (SHA256) value of member id || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||    hashed(SHA256) value of UID2 || i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is i.e. &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||  hashed(SHA256) value of the user email address  ||   i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uoo ||  device opt-out status  || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in.  ||  ✓&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    &amp;quot;device_id&amp;quot;: &amp;quot;8ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha1&amp;quot;: &amp;quot;9ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    &amp;quot;uoo&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
    &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
    &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Metadata based on User Consent in your App =====&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly accepts measurement ======&lt;br /&gt;
 All Device/User IDs are captured in the Nielsen S2S Metadata. The Opt-in Flag is set to &amp;quot;false&amp;quot; and all IDs have to be set accordingly:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly refuses measurement ======&lt;br /&gt;
The Nielsen S2S is NOT initiated and No Nielsen S2S measurement will occur.&lt;br /&gt;
&lt;br /&gt;
======The user did not explicitly give consent for the measurement(consent neither given nor refused) ======&lt;br /&gt;
 The Nielsen S2S is initiated and no IDs are captured. The Nielsen S2S Opt-out Flag is set to &amp;quot;true&amp;quot; and all Device/User IDs are empty:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || devid,  SHA-256 value of Device Id (IDFA, ADID) -  OPTIONAL is passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;sup=&amp;lt;suppress demo look-up&amp;gt;&amp;amp;uoo=&amp;lt;Optout Status &amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;IDFA/ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;sup=0&amp;amp;uoo=1&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8'&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7513</id>
		<title>DCR Germany Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_Germany_Video_S2S&amp;diff=7513"/>
		<updated>2026-01-21T11:27:55Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* query param list */  missing &amp;quot;product&amp;quot; field added , it was present in the examples but missing in the description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
Please contact AGF before you start working on a S2S Integration!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S (Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;; font-weight: bold;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (AppID)''' || Unique ID assigned to the player/site and configured by product. || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) || Provided by Nielsen&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Provided by Nielsen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have its own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but '''latest within 3 hours of the start of that hourly viewing file interval'''. For example, files from '''2:00 AM to 3:00 AM''' must be delivered latest before '''5 AM'''.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving an exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicit request from AGF.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported formats are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delivered to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''. Only for the Asset Metadata Optimization use case, '''all''' is used additionally, see [[#Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day|Optimization for all Platforms]]&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653476400&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| end_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1653479999&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
    &amp;quot;url&amp;quot;:&amp;quot;uploaded file url&amp;quot;, &lt;br /&gt;
    &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
  ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Asset Metadata Delivery Optimization===&lt;br /&gt;
&lt;br /&gt;
====Optimization when the Asset Metadata File remains unchanged during the whole day per platform====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged during the whole day per platform, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File  Location per platform.&lt;br /&gt;
&lt;br /&gt;
The File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced in the manifest file for the following 23 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the Asset Metadata File for HOUR 00'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the Asset Metadata File for HOUR 00):'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
 &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Optimization for all Platforms when the Asset Metadata File remains unchanged for all platforms during the whole day====&lt;br /&gt;
&lt;br /&gt;
When the Asset Metadata File remains unchanged for all platforms during the whole day, the hourly manifest File of the Asset Metadata File can be used to link to the Asset Metadata File Location for all platforms.&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File could then be delivered at the first hour of the day(00:00:00 AM UTC to 00:59:59 PM UTC) and it will be referenced hourly in the manifest file for all the 24 hours of the day.&lt;br /&gt;
&lt;br /&gt;
'''The Example below illustrates the use of the manifest file for HOUR 11 , referencing to the global Asset Metadata File'''&lt;br /&gt;
&lt;br /&gt;
=====Asset Metadata File for the hour 11:00:00 AM UTC to 11:59:59 PM UTC=====&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the Asset Metadata File (referencing to the global Asset Metadata File):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
   {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653476400&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653479999&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Global Asset Metadata File for the hour 00:00:00 AM UTC to 00:59:59 PM UTC for all Platforms=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File for the global Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501_manifest&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manifest File Content:'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;entries&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;url&amp;quot;:&amp;quot;euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_2022052500_2022052501.json&amp;quot;, &lt;br /&gt;
   &amp;quot;mandatory&amp;quot;:true&lt;br /&gt;
   }&lt;br /&gt;
 ],&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1653436800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1653440399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Success File for the Asset Metadata File:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/all/2022/05/25/00/_SUCCESS&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;NOTE:&amp;lt;/pre&amp;gt;'''&lt;br /&gt;
* All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
* '''For the correct filling of the metadata fields and custom variables, please make sure to follow the detailed information and specifications regarding the permitted characters and formats, field length and other limitations in the AGF metadata convention for video measurement, see:'''&lt;br /&gt;
** '''[[AGF Metadata Convention#Video Measurement|AGF Metadata Convention for Video Measurement]]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! AGF Metadata Convention Name - &amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Only for your Reference&lt;br /&gt;
&amp;lt;/pre&amp;gt;  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid  || assetid|| unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname  || program || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || title || episode name || custom -  no backslash allowed in string (because of 3rd party data processing)  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen   || length || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || N/A|| Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand ||  subbrand (vcid) || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
 &lt;br /&gt;
|-&lt;br /&gt;
| nol_c0   || nol_c0 || number of episode part (Sendungsteilenummer)   || custom, if a content is not divided into several episode parts, set &amp;quot;0&amp;quot; as value.  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c2   || nol_c2 || web only  || custom. The custom variable &amp;quot;web-only&amp;quot; specifies whether the streaming content is made available exclusively on the internet (web-only, &amp;quot;Y&amp;quot;) or also made available on linear TV (web-only, &amp;quot;N&amp;quot;)|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c5  || nol_c5   || page URL   || custom, The “Page URL” custom variable is reserved for sending the video’s server address.  ||  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c7  || nol_c7  || Video ID. This variable is applicable in case the video asset is broken into multiple files each with their own asset ID. If a client has a single asset for a given episode/program, the value here should be identical to the assetid already provided in the viewership file. &lt;br /&gt;
  || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
| nol_c9  || nol_c9  || episode title   || custom - no backslash allowed in string (because of 3rd party data processing). if no further differentiation, then use &amp;quot;episodetitle&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c10  || nol_c10  || publisher   || custom, used to differentiate different publishers   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c12  || nol_c12  || type of asset   || &amp;quot;Trailer&amp;quot; or &amp;quot;Content&amp;quot;   || ✓  &lt;br /&gt;
|-&lt;br /&gt;
| nol_c15  || nol_c15   || format ID   || If nol_c2 is always Yes, then it can stay blank &amp;quot;&amp;quot;   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c16  || nol_c16   || content-ID (Combines different videos to a common category, content-wise, a content-ID is available for content, trailer and ads)   || custom, i.e. 'dVxRcCpOqKyFz02fuss', 'dvrsowf_ten_rtlibes&amp;quot;, etc   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_c18  || nol_c18  || is a live stream    || &amp;quot;Y&amp;quot; for live stream otherwise &amp;quot;N&amp;quot;  || ✓  &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c8   || nol_c8 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c13   || nol_c13  || custom variable   || custom   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c14   || nol_c14 || not in use   || leave blank &amp;quot;&amp;quot;, reserved for AGF   || &lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
| nol_c19   || nol_c19  || custom variable   || custom   || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;programname&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;episodetitle&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c02&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c0&amp;quot;: &amp;quot;p0,3&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c2&amp;quot;: &amp;quot;p2,Y&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c7&amp;quot;: &amp;quot;p7,videoid123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c9&amp;quot;: &amp;quot;p9,VideoTitle123&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c10&amp;quot;: &amp;quot;p10,publisherName&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c12&amp;quot;: &amp;quot;p12,Content&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_c18&amp;quot;: &amp;quot;p18,N&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''ONLY for''' '''android''' platform, DO NOT pass device_id for '''ios''', '''browser''' and '''ott''' platforms.  Mobile Ad ID ,  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; - OPTIONAL if passed in the Audit Ping|| i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638655&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Android Platform : Example Metadata with &amp;quot;device_id&amp;quot;  =====&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &amp;quot;device_id&amp;quot; not available ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in the respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| product || Indicates which Nielsen product the audit ping corresponds to. || dcr || ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || '''ONLY for''' '''android''' platform, DO NOT pass devid for '''ios''', '''browser''' and '''ott''' platforms. devid,  SHA-256 value of Device Id (ADID) -  OPTIONAL if passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;intid=&amp;lt;Integration ID&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;Android ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;&amp;amp;intid=xxxxxxxx&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7481</id>
		<title>DCR France Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7481"/>
		<updated>2025-12-18T15:45:09Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Description */ fpid and fpcrtm are now  optional ; device_id is marked as mandatory only for Android as it is a current Nielsen requirement for all countries.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S(Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (apid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.) || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have it’s own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but latest within 3 hour of the start of that hourly&lt;br /&gt;
viewing file interval. For example files from 1:00 AM to 2:00 AM must be delivered latest before 4 AM.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicite request from Médiamétrie.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported format are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delived to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0000_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0001_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0002_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0003_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710154800&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710158399&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 15&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Note:''' ''' Do not include personal data '''in the content metadata.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname   || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || episode name || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen    || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand  || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|-&lt;br /&gt;
| cli_md || mode: allows to know the streaming type || possible values provided by Médiamétrie: &amp;quot;LIVE&amp;quot; &amp;quot;TIMESHIFTING&amp;quot; &amp;quot;TVOD&amp;quot; &amp;quot;VOD&amp;quot; &amp;quot;SVOD&amp;quot; &amp;quot;AOD&amp;quot;|| &lt;br /&gt;
|-&lt;br /&gt;
| cli_ch    || Channel identifier: values decided by Médiamétrie and provided to the broadcaster || sample value: &amp;quot;860&amp;quot; || &lt;br /&gt;
|-&lt;br /&gt;
| cli_cn    || content identifier as used / categorized by the publisher    || custom   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_p0    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character ) &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p1    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p2    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p3    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p4    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p5    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p6    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p7    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p8    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p9    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p10   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p11   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p12   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p13   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p14   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p15   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p16   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p17   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p18   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p19   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_md&amp;quot;: &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_ch&amp;quot;: &amp;quot;860&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_cn&amp;quot;: &amp;quot;customCuntentIdentifier&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p0&amp;quot;: &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p1&amp;quot;: &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
    // ... continued - 20 custom variables&lt;br /&gt;
    &amp;quot;nol_p18&amp;quot;: &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p19&amp;quot;: &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please do not include ZERO DURATION viewing portion in the Asset Viewing File.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || '''MANDATORY ONLY for android platform.''' Mobile Ad ID IDFA,ADID, Connected Device ID  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|-&lt;br /&gt;
| fpid || First Party ID || created using the UUID Generator code provided / validity time 180 days. || &lt;br /&gt;
|-&lt;br /&gt;
| fpcrtm || Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds) || custom || &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||    hashed (SHA256) value of member id || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||    hashed(SHA256) value of UID2 || i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is i.e. &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||  hashed(SHA256) value of the user email address  ||   i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uoo ||  device opt-out status  || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in.  ||  ✓&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    &amp;quot;device_id&amp;quot;: &amp;quot;8ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha1&amp;quot;: &amp;quot;9ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    &amp;quot;uoo&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
    &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
    &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Metadata based on User Consent in your App =====&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly accepts measurement ======&lt;br /&gt;
 All Device/User IDs are captured in the Nielsen S2S Metadata. The Opt-in Flag is set to &amp;quot;false&amp;quot; and all IDs have to be set accordingly:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly refuses measurement ======&lt;br /&gt;
The Nielsen S2S is NOT initiated and No Nielsen S2S measurement will occur.&lt;br /&gt;
&lt;br /&gt;
======The user did not explicitly give consent for the measurement(consent neither given nor refused) ======&lt;br /&gt;
 The Nielsen S2S is initiated and no IDs are captured. The Nielsen S2S Opt-out Flag is set to &amp;quot;true&amp;quot; and all Device/User IDs are empty:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || devid,  SHA-256 value of Device Id (IDFA, ADID) -  OPTIONAL is passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;sup=&amp;lt;suppress demo look-up&amp;gt;&amp;amp;uoo=&amp;lt;Optout Status &amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;IDFA/ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;sup=0&amp;amp;uoo=1&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8'&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7480</id>
		<title>DCR France Video S2S</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_S2S&amp;diff=7480"/>
		<updated>2025-12-18T11:38:06Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: improvements from AGF S2S Integration Guide added; additional IDs(i.e. memberid, uid2 and hashed email marked as optional as from today's request from MM; )&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
= DCR Integration Utilizing S2S =&lt;br /&gt;
This guide shows you how to integrate the Nielsen S2S(Server to Server) to enable Digital Content Ratings (DCR), and fuel other measurement products on your Apps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
PLease note that you have to use the Staging S2S Endpoint(&amp;lt;env&amp;gt;=stage)until you get the green light to move to Production, you will then get the Production S2S Endpoint!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
To get started, you will need a Nielsen App ID. The App ID is a unique ID assigned to your app. This will be provided to you by your assigned Technical Account Manager upon starting the integration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''App ID (apid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Integration ID (IntID)''' || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.) || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| '''Partner ID (PartnerID)''' || Partner id provided by Nielsen. Used for the client specific S3 bucket . &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that the sample PartnerID 'acme' used in all examples is a placeholder to be replaced with your PartnerID. &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|| Contact Médiamétrie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
This interface specification depicts the file format that needs to be used to supply Nielsen with&lt;br /&gt;
end-user viewing data captured by a “Server-to-Server” method for the Nielsen Digital Content&lt;br /&gt;
Ratings (DCR) product and Tuning data for the Digital Ads Rating (DAR) products.&lt;br /&gt;
* The specification is defined using a JSON schema, with each file ideally containing all the&lt;br /&gt;
viewing that has been captured within an hour.&lt;br /&gt;
* In the case of a stream that has one version with blackouts and one without, one with&lt;br /&gt;
mobile and one non-mobile, each stream would have it’s own unique asset id.&lt;br /&gt;
* The Asset Metadata file should arrive before the viewing data file for the same hour.&lt;br /&gt;
&lt;br /&gt;
==SLA==&lt;br /&gt;
The files must be delivered into the proper S3 bucket '''immediately after each hour of viewing on a device''', but latest within 3 hour of the start of that hourly&lt;br /&gt;
viewing file interval. For example files from 1:00 AM to 2:00 AM must be delivered latest before 4 AM.&lt;br /&gt;
&lt;br /&gt;
'''When SLA for receiving exposure file for date xx/xx, UTC hour xx has expired. The system will continue to wait for 60 min, after which it will skip the missing file and continue processing subsequent files. Any reprocessing of the missed SLA data will require an explicite request from Médiamétrie.'''&lt;br /&gt;
&lt;br /&gt;
==Accuracy of the Measurement==&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time (Video Player Events) At Least Each 10 Seconds To Your Backend====&lt;br /&gt;
Capture content viewing time each second and send the aggregated viewing time at least each 10 seconds to your backend:&lt;br /&gt;
* referencestart : Wall clock reference start time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* referenceend : Wall clock reference end time (In UTC time, 32-bit unsigned int in seconds)&lt;br /&gt;
* playheadstart : Content position start time in seconds&lt;br /&gt;
* playheadend : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
====Send Viewing Time When The Video Playback Is Interrupted====&lt;br /&gt;
 Send the aggregated viewing time to your backend when the video playback is interrupted, i.e. paused.&lt;br /&gt;
&lt;br /&gt;
====Capture Accurately Each Second The Viewing Time When The Network Is Lost And The Video Playback Continues====&lt;br /&gt;
Capture accurately each second the viewing time when the network is lost.&lt;br /&gt;
Send the aggregated viewing time to your backend when the network is back.&lt;br /&gt;
&lt;br /&gt;
====Send The Viewing Time Early On Browser Refreshed/Closed====&lt;br /&gt;
Capture and send the viewing time to your backend by implementing the 2 WINDOWS EVENTS:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Please include a logic to make sure that only one of the 2 following event handler is executed '''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEventListener(&amp;quot;pagehide&amp;quot;, function (e) { &lt;br /&gt;
   // SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
window.addEventListener(&amp;quot;beforeunload&amp;quot;, function (e) {&lt;br /&gt;
   // ONLY IF pagehide&amp;quot; was not triggered, SEND THE VIEWING TIME TO YOUR BACKEND&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==File Naming Convention and Delivery Specification==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Files should be delivered at a fixed cadence in a dedicated S3 bucket following the outlined in this spec prefix and object naming conventions and data formats. &lt;br /&gt;
&lt;br /&gt;
* All prefix labels and file names should be lowercase except for app ids. &lt;br /&gt;
* Supported format are:&lt;br /&gt;
** Uncompressed text files with utf-8 encoding in:&lt;br /&gt;
***  JSON format(.json);&lt;br /&gt;
***  PARQUET format(.parquet);&lt;br /&gt;
* All files should have extensions to indicate the file format (.json or .parquet)&lt;br /&gt;
* Data file can be partitioned into multiple parts with min size of 128MB - 256MB&lt;br /&gt;
* Data can be delivered separately in multiple splits(platforms), if needed due to organizational, technical or privacy requirements. This allows to permission s3 access separately, to process data independently and to persist data partitioned, within the limits of the S2S system;&lt;br /&gt;
&lt;br /&gt;
===The 4 Different Files to deliver to Nielsen each hour===&lt;br /&gt;
* [Asset Metadata File]&lt;br /&gt;
* [Asset Viewing  File]&lt;br /&gt;
* [Manifest File]&lt;br /&gt;
* [Success File: Indication of a data delivery for a particular hour]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nielsen will move files to indicate they are being processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====S3 bucket and prefix(S3BucketPrefix) for all 4 Files====&lt;br /&gt;
&lt;br /&gt;
All files should be delived to:&lt;br /&gt;
'''&amp;lt;S3BucketPrefix&amp;gt;:''' euwest1-nlsn-w-dig-sei-'''&amp;lt;PartnerID&amp;gt;'''-feeds-'''&amp;lt;env&amp;gt;'''/ProducType&amp;gt;/&amp;lt;Platform&amp;gt;/yyyy/mm/dd/hh/&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| env  || '''stage''' for Staging or '''prod''' for Production&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| Platform  || '''ios''', '''browser''', '''android''', '''ott'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyy/mm/dd/hh || UTC start of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023/02/12/05'''&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
=====Examples for the iOS platform=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Manifest File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
======Success File======&lt;br /&gt;
&amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====File Name(FileName) format for the Asset Metadata and Asset Viewing Files ====&lt;br /&gt;
&lt;br /&gt;
Asset Metadata and Asset Viewing Files should be delivered to:&lt;br /&gt;
* &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;&amp;lt;FileSuffix&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description''' &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| PartnerID || Publisher abbreviation provided by Nielsen for each Publisher or Provider&lt;br /&gt;
|-&lt;br /&gt;
| IntID  || Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewsership pipelines (dar, dtvr, dcr, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ProductType  || '''dcr-exposure''' for Asset Viewing  File, '''dcr-metadata''' for Asset Metadata File&lt;br /&gt;
|-&lt;br /&gt;
| AppID  || Nielsen provided server application identifier&lt;br /&gt;
|-&lt;br /&gt;
| StartTime  || start date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| EndTime  || end date and hour of the data in the file in GMT: '''yyyymmddhh'''&lt;br /&gt;
|-&lt;br /&gt;
| yyyymmddhh || UTC time of the period of the data in file&lt;br /&gt;
&lt;br /&gt;
* yyyy = Year&lt;br /&gt;
* mm = Month&lt;br /&gt;
* dd = Date padded with 0 example 01, 02,..., 31&lt;br /&gt;
* hh = Hour padded with 0 example 00, 02,..., 23&lt;br /&gt;
&lt;br /&gt;
example: '''2023021205'''&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| FileSuffix  || Uncompressed json lines (no extension) - splittable, ideal for medium size files, '''less than 5 GB''', preferred for metadata. &lt;br /&gt;
'''supported:'''&lt;br /&gt;
* '''.json''' json file &lt;br /&gt;
* '''.parquet''' parquet file &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Examples for  Asset Metadata and Asset Viewing Files=====&lt;br /&gt;
======Asset Metadata File======&lt;br /&gt;
Asset Metadata File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Asset Viewing  File======&lt;br /&gt;
Asset Viewing File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
* &amp;lt;code&amp;gt;euwest1-nlsn-w-dig-sei-acme-feeds-stage/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495BBBBA56DEBE9914758F92F034_2022052511_2022052512.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Manifest File for the Asset Metadata and Asset Viewing Files====&lt;br /&gt;
&lt;br /&gt;
The Manifest File should be delivered to: &amp;lt;S3BucketPrefix&amp;gt;'''&amp;lt;FileName&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;FileName&amp;gt;''' : &amp;lt;PartnerID&amp;gt;_&amp;lt;ProductType&amp;gt;_&amp;lt;IntID&amp;gt;_&amp;lt;AppID&amp;gt;_&amp;lt;StartTime&amp;gt;_&amp;lt;EndTime&amp;gt;'''_manifest'''&lt;br /&gt;
&lt;br /&gt;
A manifest contains metadata related to the uploaded file(s). It is a text file in json format that implements the AWS unload manifest file format. It follows the s3 objects naming notation, but has the _manifest suffix. Here’s an example of manifest file contents:&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0000_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0001_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0002_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true},&lt;br /&gt;
    {&amp;quot;url&amp;quot;:&amp;quot;s3://bucket/prefix/0003_object_00.snappy.parquet&amp;quot;, &amp;quot;mandatory&amp;quot;:true}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;meta&amp;quot;: {&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The manifest contains a complete list of all files provided for a given period and platform, as well as a meta data (a.k.a. header) which should include the following attributes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schema_version || Schema Version || String, i.e. &amp;quot;S2SV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data Start UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710154800&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| data_start_time || Data End UTC Time (max), 32-bit unsigned int Unix time in seconds || String, i.e. &amp;quot;1710158399&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| record_count || Records Count in data file || Number: i.e. 55 || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If ‘entries’ array is not specified, or manifest file is not available, the system will still attempt to load all data file(s) (.json or .parquet) from the prefix location. Optionally the manifest file can contain the full schema of the data files as shown in the [https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD_command_examples.html#unload-examples-manifest-verbose manifest file format document ].&lt;br /&gt;
&lt;br /&gt;
=====Example for the Manifest File=====&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Metadata File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 15&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
======Manifest File for the Asset Viewing File======&lt;br /&gt;
The Manifest File for 11:00:00 AM UTC to 11:59:59 PM UTC the file name would be:&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schema_version&amp;quot;: &amp;quot;S2SV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;accreditation_status&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
    &amp;quot;start_time&amp;quot;: &amp;quot;1710154800&amp;quot;,&lt;br /&gt;
    &amp;quot;end_time&amp;quot;: &amp;quot;1710158399&amp;quot;,&lt;br /&gt;
    &amp;quot;record_count&amp;quot;: 55&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Success File: Indication of a data delivery for a particular hour===&lt;br /&gt;
&lt;br /&gt;
An Empty _SUCCESS file should be provided to indicate that data delivery for a particular hour and platform is completed successfully. This file should be uploaded last (after all other files). If there is no data data for a particular hour and platform, the _SUCCESS file is still required to indicate that the delivery process for the hour is completed and no data files are expected. This file is only required for integrations that support data partitioned into multiple parts. The name of the file is configurable.&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Viewing Delivery Files====&lt;br /&gt;
&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Example for Asset Metadata Delivery Files====&lt;br /&gt;
'''For hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):'''&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
====Data Delivery Example for hour 11 (11:00:00 AM UTC to 11:59:59 PM UTC):====&lt;br /&gt;
=====Asset Metadata Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/acme_dcr-metadata_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-metadata/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=====Asset Viewing Delivery Files=====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0000.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0001.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0002.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_0003.json&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/acme_dcr-exposure_a9ddf15ea054ea415718767ea6_P47C2495B-BBBA-56DE-BE99-14758F92F034_2022052511_2022052512_manifest&lt;br /&gt;
&lt;br /&gt;
euwest1-nlsn-w-dig-sei-acme-feeds-prod/dcr-exposure/ios/2022/05/25/11/_SUCCESS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== S2S Metadata Specifications for the Asset Metadata and Asset Viewing Files ==&lt;br /&gt;
&lt;br /&gt;
=== Asset Metadata File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Metadata File contains 1 Header Record  followed by Body Records &lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| mvpdid || mvpd ID specified ny Nielsen || String, i.e. &amp;quot;NLSN&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| creationtime ||  File creation time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  ||String, i.e. &amp;quot;1&amp;quot; for only 1 Record || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SAssetMetaDataDCRV2.09&amp;quot;,&lt;br /&gt;
    &amp;quot;mvpdid&amp;quot;: &amp;quot;NLSN&amp;quot;,&lt;br /&gt;
    &amp;quot;creationtime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Note:''' ''' Do not include personal data '''in the content metadata.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys  !! Description  !! Values   !! Required&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| programname   || name of program  || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodetitle || episode name || custom   || ✓&lt;br /&gt;
|-&lt;br /&gt;
| episodelen    || length of content in seconds || Length of content in seconds (86400 seconds for live stream (24/7). For Event-Live streams planned length. For VoD video length)||   ✓&lt;br /&gt;
|-&lt;br /&gt;
|islivestn  || Indicates if a stream is playing on a live channel&lt;br /&gt;
||&lt;br /&gt;
:&lt;br /&gt;
* &amp;quot;y&amp;quot; playing on a live channel&lt;br /&gt;
* &amp;quot;n&amp;quot; otherwise i.e. VoD&lt;br /&gt;
||&lt;br /&gt;
✓&lt;br /&gt;
|-&lt;br /&gt;
| subbrand  || vcid/sub-brand/Channel  ID – value is automatically populated through provided AppID. In order to override the sub-brand configured to the App ID, value can be passed here (e.g. multiple sub-brands/Channels in the App)   &lt;br /&gt;
||&lt;br /&gt;
provided by Nielsen &lt;br /&gt;
||&lt;br /&gt;
✓ &lt;br /&gt;
|-&lt;br /&gt;
| cli_md || mode: allows to know the streaming type || possible values provided by Médiamétrie: &amp;quot;LIVE&amp;quot; &amp;quot;TIMESHIFTING&amp;quot; &amp;quot;TVOD&amp;quot; &amp;quot;VOD&amp;quot; &amp;quot;SVOD&amp;quot; &amp;quot;AOD&amp;quot;|| &lt;br /&gt;
|-&lt;br /&gt;
| cli_ch    || Channel identifier: values decided by Médiamétrie and provided to the broadcaster || sample value: &amp;quot;860&amp;quot; || &lt;br /&gt;
|-&lt;br /&gt;
| cli_cn    || content identifier as used / categorized by the publisher    || custom   || &lt;br /&gt;
|-&lt;br /&gt;
| nol_p0    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character ) &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p1    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p2    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p3    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p4    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p5    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p6    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p7    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p8    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p9    || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p10   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p11   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p12   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p13   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p14   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p15   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p16   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p17   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p18   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|-&lt;br /&gt;
| nol_p19   || optional custom field available to publishers to pass client-defined variable    || custom&amp;lt;br&amp;gt;The following characters are not allowed:&amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt;  ( bar character )&amp;lt;br&amp;gt;&lt;br /&gt;
* ~  ( tilde character )    &lt;br /&gt;
|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
    &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
    &amp;quot;islivestn&amp;quot;: &amp;quot;y&amp;quot;,&lt;br /&gt;
    &amp;quot;subbrand&amp;quot;: &amp;quot;c05&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_md&amp;quot;: &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_ch&amp;quot;: &amp;quot;860&amp;quot;,&lt;br /&gt;
    &amp;quot;cli_cn&amp;quot;: &amp;quot;customCuntentIdentifier&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p0&amp;quot;: &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p1&amp;quot;: &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
    // ... continued - 20 custom variables&lt;br /&gt;
    &amp;quot;nol_p18&amp;quot;: &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
    &amp;quot;nol_p19&amp;quot;: &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asset Viewing File ===&lt;br /&gt;
&lt;br /&gt;
The Asset Viewing File contains 1 Header Record  followed by Body Records &lt;br /&gt;
'''Note:''' All metadata values should be passed as '''UTF-8 strings'''.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please do not include ZERO DURATION viewing portion in the Asset Viewing File.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Header Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
&lt;br /&gt;
'''Parameter Description'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| schemaversion || Json Schema Version || String, &amp;quot;S2SViewingDataV1.7.0&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| appid || Nielsen provided server application identifier || String, i.e. &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| type || Type of the data || String, &amp;quot;content&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| producttype || Product Type || String, &amp;quot;DCR&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| starttime ||  Viewing Data Start Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473781507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| endtime ||  Viewing Data End Time (UTC time in 32-bit unsigned int UTC in seconds) || String, i.e. &amp;quot;1473791507&amp;quot;|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| recordcount || Records Count in body of file  || String, i.e. &amp;quot;100&amp;quot; for only 100 Records || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;schemaversion&amp;quot;: &amp;quot;S2SViewingDataV1.7.0&amp;quot;,&lt;br /&gt;
    &amp;quot;appid&amp;quot;: &amp;quot;P47C2495B-XXXX-56DE-BE99-14758F92F034&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;content&amp;quot;,&lt;br /&gt;
    &amp;quot;producttype&amp;quot;: &amp;quot;DCR&amp;quot;,&lt;br /&gt;
    &amp;quot;starttime&amp;quot;: &amp;quot;1473781507&amp;quot;,&lt;br /&gt;
    &amp;quot;endtime&amp;quot;: &amp;quot;1473791507&amp;quot;,&lt;br /&gt;
    &amp;quot;recordcount&amp;quot;: &amp;quot;100&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Body Record====&lt;br /&gt;
&lt;br /&gt;
=====Description=====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apn || app name || i.e. &amp;quot;BestAppIOS&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| apv || app build version || i.e. &amp;quot;1.3&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid || Unique, client generated value that represents the start of a user session. Must match sessionid in Audit Ping. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || streamid ID for every new instance of an asset || created using the UUID Generator code provided || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| streamended   || Stream is known to have ended in this file   || &lt;br /&gt;
* &amp;quot;1&amp;quot; (stream will continue in next file) &lt;br /&gt;
* &amp;quot;2&amp;quot; (stream closed) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| secondscr || Second Screen Indicator. For Mirroring &amp;amp; Extended Screen via OTT device scenarios  || &lt;br /&gt;
* &amp;quot;&amp;quot; (empty String if viewed directly on the device)&lt;br /&gt;
* &amp;quot;MIR&amp;quot; (Mirroring)&lt;br /&gt;
* &amp;quot;OTT&amp;quot; (Extended Screen via OTT device) &lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| assetid   || unique ID assigned to asset  || custom&amp;lt;br&amp;gt;(no [[Special Characters]]) || ✓&lt;br /&gt;
|-&lt;br /&gt;
| position  || Array of contiguous content viewing in utc (UTC time in 32-bit unsigned int in seconds)  ||&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[{&lt;br /&gt;
&amp;quot;referencestart&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;referenceend&amp;quot;:&amp;quot;utc time&amp;quot;,&lt;br /&gt;
&amp;quot;playheadstart&amp;quot;:&amp;quot;playhead start position&amp;quot;,&lt;br /&gt;
&amp;quot;playheadend&amp;quot;:&amp;quot;playhead end position&amp;quot;&lt;br /&gt;
}]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Description:'''&lt;br /&gt;
* '''referencestart''' : Wall clock reference start time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''referenceend''' : Wall clock reference end time (In UTC time,  32-bit unsigned int in seconds)&lt;br /&gt;
* '''playheadstart''' : Content position start time in seconds&lt;br /&gt;
* '''playheadend''' : Content position end time in seconds&lt;br /&gt;
&lt;br /&gt;
'''For Content position start and end time(playheadstart, playheadend):'''&lt;br /&gt;
* For VoD stream use the player position for Content as the playhead position in seconds.  At playback start of a content from the begin,  playheads will then be 0,1,2,3,....&lt;br /&gt;
* For Live streams, use Unix Time (in seconds) matching the broadcast time as the playhead position in seconds.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Additional Notes:'''&lt;br /&gt;
* For viewing gaps &amp;lt; than 1 second, the gap can be smoothed over&lt;br /&gt;
* For playouts that are abandoned before the first whole second of viewing is rendered, a position record of zero duration should be created. IF an audit ping has already been fired See below for additional details on position array parameters&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| device_id || Mobile Ad ID IDFA,ADID, Connected Device ID  unique Device ID of a user device (e.g. SHA-256 hashed value of i.e. Advertising ID, Roku Device ID). Please verify your implemented SHA-256 by passing &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot; which should return &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || i.e &amp;quot;12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8&amp;quot; || ✓&lt;br /&gt;
|-&lt;br /&gt;
| xdua || Device HTTP raw User Agent string  - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Example: &amp;quot;Apple-iPhone1C2/801.293&amp;quot; || ✓ &lt;br /&gt;
|-&lt;br /&gt;
| xff || IP address - OPTIONAL if passed in the Audit Ping to the Nielsen Server|| Format: &amp;quot;xxx.xxx.xxx.xxx&amp;quot; or &amp;quot;xxx.xxx.xxx.000&amp;quot; &lt;br /&gt;
Examples :&lt;br /&gt;
* IPV4:  &amp;quot;4.12.345.67&amp;quot;&lt;br /&gt;
* IPV6: &amp;quot;2600:6c58:7900:33f2:2505:42b9:5a34:0000&amp;quot;&lt;br /&gt;
|| ✓ &lt;br /&gt;
|-&lt;br /&gt;
| fpid || First Party ID || created using the UUID Generator code provided / validity time 180 days. || ✓&lt;br /&gt;
|-&lt;br /&gt;
| fpcrtm || Creation Time (UTC) of the First Party ID (Unix Timestamp in milliseconds) || custom || ✓&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||    hashed (SHA256) value of member id || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||    hashed(SHA256) value of UID2 || i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is i.e. &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||  hashed(SHA256) value of the user email address  ||   i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot; ||  &lt;br /&gt;
|-&lt;br /&gt;
|uoo ||  device opt-out status  || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in.  ||  ✓&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Example=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;apn&amp;quot;: &amp;quot;BestAppiOS&amp;quot;,&lt;br /&gt;
    &amp;quot;apv&amp;quot;: &amp;quot;1.3&amp;quot;,&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xxxjavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique sessid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xxxsavd6wzirm93xb95uxjy1ac5wu1627638609&amp;quot;, // create and pass a unique streamid for each video play using UUID Generator code provided&lt;br /&gt;
    &amp;quot;streamended&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;assetid&amp;quot;: &amp;quot;VA12345&amp;quot;,&lt;br /&gt;
    &amp;quot;secondscr&amp;quot;: &amp;quot;MIR&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;1628735452&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;1628736052&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
            &amp;quot;playheadend&amp;quot;: &amp;quot;600&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;xdua&amp;quot;: &amp;quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130Safari/537.36&amp;quot;,&lt;br /&gt;
    &amp;quot;xff&amp;quot;: &amp;quot;4.12.345.67&amp;quot;,&lt;br /&gt;
    &lt;br /&gt;
    &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
    &amp;quot;device_id&amp;quot;: &amp;quot;8ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha1&amp;quot;: &amp;quot;9ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
    &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
    &amp;quot;uoo&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
    &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
    &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Metadata based on User Consent in your App =====&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly accepts measurement ======&lt;br /&gt;
 All Device/User IDs are captured in the Nielsen S2S Metadata. The Opt-in Flag is set to &amp;quot;false&amp;quot; and all IDs have to be set accordingly:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;U4EDwDcpvWIbguYVyjlhzS1v0eaov1631180980&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;1631098029000&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== The user explicitly refuses measurement ======&lt;br /&gt;
The Nielsen S2S is NOT initiated and No Nielsen S2S measurement will occur.&lt;br /&gt;
&lt;br /&gt;
======The user did not explicitly give consent for the measurement(consent neither given nor refused) ======&lt;br /&gt;
 The Nielsen S2S is initiated and no IDs are captured. The Nielsen S2S Opt-out Flag is set to &amp;quot;true&amp;quot; and all Device/User IDs are empty:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;device_id&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha1&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uid2&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;hem_sha256&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;uoo&amp;quot;&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
  &amp;quot;fpid&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;fpcrtm&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==OTT, Mirroring, and Casting==&lt;br /&gt;
&lt;br /&gt;
For apps native to the OTT device (i.e. downloading and viewing a streaming app to an Apple&lt;br /&gt;
TV, audit ping should fire from OTT device, and Viewing data should reside in OTT Viewing file.&lt;br /&gt;
For mirroring, where video playback occurs on the mobile device and OTT device, only one&lt;br /&gt;
Viewing file row is necessary where, if possible to determine, set: &amp;quot;secondscr&amp;quot;:&amp;quot;MIR&amp;quot; and&lt;br /&gt;
include in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
For a casting scenario where content is controlled via the mobile device, but displayed only on&lt;br /&gt;
the OTT device such as an AppleTV or Chromecast, an audit ping must fire from the mobile&lt;br /&gt;
device before the casting occurs and at the end of playback from the mobile device only.&lt;br /&gt;
Viewing data resides in respective mobile platform Viewing file.&lt;br /&gt;
&lt;br /&gt;
Casting Viewing file example:&lt;br /&gt;
&lt;br /&gt;
[[File:France MM S2S casting example.png|France MM S2S casting example.png]]&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx123&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;0&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;60&amp;quot;'''&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx303&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;120&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;180&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{ // ...&lt;br /&gt;
    &amp;quot;sessionid&amp;quot;: &amp;quot;xx..xxxABC&amp;quot;,&lt;br /&gt;
    &amp;quot;streamid&amp;quot;: &amp;quot;xx..xxxDEF&amp;quot;,&lt;br /&gt;
    &amp;quot;position&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;referencestart&amp;quot;: &amp;quot;xxxxxxx183&amp;quot;,&lt;br /&gt;
            &amp;quot;referenceend&amp;quot;: &amp;quot;xxxxxxx243&amp;quot;,&lt;br /&gt;
            '''&amp;quot;playheadstart&amp;quot;: &amp;quot;60&amp;quot;,'''&lt;br /&gt;
            '''&amp;quot;playheadend&amp;quot;: &amp;quot;120&amp;quot;'''&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
    '''&amp;quot;secondscr&amp;quot;: &amp;quot;OTT&amp;quot;'''&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==S2S Audit Ping Specifications==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
The Nielsen server to server solution needs audit pings to validate audience reach and video viewing duration, one '''start''' and one '''end''' for each video stream playback. These pings will go from the end user device to Nielsen Collections servers. &lt;br /&gt;
&lt;br /&gt;
'''start audit ping(“Startstream = 1”)'''&lt;br /&gt;
* A start audit ping is sent when the stream starts(playback start).&lt;br /&gt;
* Also a new start audit ping is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping. &lt;br /&gt;
'''end audit ping(“Endstream = 3”)'''&lt;br /&gt;
* An end audit ping is sent when the stream ends(either playback completed or switch to another stream).&lt;br /&gt;
* Also an end audit ping is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ping Structure ===&lt;br /&gt;
Ping should be named with following convention structure:&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp; query param list (see table below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: orange&amp;quot;&amp;gt;&lt;br /&gt;
Please note that you have to send the Audit Ping in real time on the device running your App.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Please note that this URL could change as we respond to security upgrades in the market.)&lt;br /&gt;
The Start Audit Ping will carry all parameters in the matrix below. The End Audit Ping will carry a subset of the parameters in the matrix below as denoted in the mandatory column.  &lt;br /&gt;
Under normal operating circumstances, the Nielsen collection system will return return codes:&lt;br /&gt;
* For security reasons, downstream servers reject cross-origin HTTP requests with preflight. To ensure that audit ping requests are accepted, allowable Content-Types like &amp;quot;text/plain&amp;quot; in simple GET requests ensure that preflight requests are not invoked, which is the preferred behavior.&lt;br /&gt;
* 200: The ping was successfully received, inspect traffic to ensure no CORS errors&lt;br /&gt;
&lt;br /&gt;
=== Ping Session &amp;amp; Stream Details ===&lt;br /&gt;
&lt;br /&gt;
==== Sessions ====&lt;br /&gt;
* a) When a new player is created a session id is also created.&lt;br /&gt;
* b) If you have more than one video player within the same App (e.g. picture in picture) you must use a different session id for each.&lt;br /&gt;
&lt;br /&gt;
==== Streams ====&lt;br /&gt;
* a) The Distributor must generate a new UNIQUE stream id with every video stream playback.&lt;br /&gt;
* b)  If two people watch the same show, they would have different stream id's as Nielsen would expect the stream id(“streamid”) to be a random GUId generated by the client device.&lt;br /&gt;
* c) If one person watches a show, and FF, rewind, playout, pause, play, RW, play - they would keep the same stream id(“streamid”) throughout the entire playout of that video asset (stream).&lt;br /&gt;
* d) If a stream play out is suspended for 30 mins or more (paused or background):&lt;br /&gt;
** An end audit ping(“Endstream = 3”) is sent when the stream playback after a playback interruption for more than 30 minutes, typically playback  paused.&lt;br /&gt;
** A new start audit ping(“Startstream = 1”) is sent when the stream playback resumes after a playback interruption for more than 30 minutes, typically playback  paused. PLEASE note that a new “streamid” parameter has to be created before sending a new start audit ping.&lt;br /&gt;
* e) If the user reaches the very end of the stream (content complete), and then starts to play again (replay from anywhere in the stream), then a new “streamid” should be created and a start audit ping should be sent. Also an end audit should be sent when the stream replay  is completed or the user switches to another stream.&lt;br /&gt;
&lt;br /&gt;
====Audit Pings ====&lt;br /&gt;
* a) Audit pings should be fired at the '''beginning''' and '''end''' of a stream. These will be referred to as the Audit Start Ping and the Audit End Ping.&lt;br /&gt;
&lt;br /&gt;
==== query param list ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
'''Required S2S Audit Ping Query String Parameters - Note: All parameters are case sensitive'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Keys !! Description !! Values !! Required&lt;br /&gt;
|-&lt;br /&gt;
| apid  ||  Unique ID assigned to the player/site and configured by your Nielsen Technical Account Manager.&lt;br /&gt;
 || Example: '''FC984EC1-E044-B465-E040-070AAD3173A1''' || ✓&lt;br /&gt;
|-&lt;br /&gt;
| intid  ||  Integration id provided by Nielsen. Used to link different integration inputs, ex. associate single audit ping integration with different viewership pipelines (dar, dtvr, dcr, etc.) ||  || ✓&lt;br /&gt;
|-&lt;br /&gt;
| sessionid  || Unique, client-generated value that represents the start of a user browsing session. Must match sessionid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| streamid || Unique Id for every new instance of a client video asset playout.  Must match streamid in the Exposure file. || created using the UUID Generator code provided || ✓&lt;br /&gt;
|-&lt;br /&gt;
| pingtype || pingtype Indicator for state type: “start” or “end” audit ping &amp;amp; if the ping is for a stream  ||&lt;br /&gt;
* Startstream = 1&lt;br /&gt;
* Startsession=0&lt;br /&gt;
* Endstream = 3&lt;br /&gt;
* Endsession=2&lt;br /&gt;
|| ✓&lt;br /&gt;
|-&lt;br /&gt;
| createtm || Time the ping was fired: utc (in seconds) If server time available, use it instead of device time || || ✓&lt;br /&gt;
|-&lt;br /&gt;
| devid || devid,  SHA-256 value of Device Id (IDFA, ADID) -  OPTIONAL is passed in the Asset Viewing File  || || ✓&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Generic Ping Format:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=&amp;lt;App id&amp;gt;&amp;amp;sessionid=&amp;lt;Session Id&amp;gt;&amp;amp;streamid=&amp;lt;Stream Id&amp;gt;&amp;amp;pingtype=&amp;lt;Ping Type&amp;gt;&amp;amp;product=&amp;lt;dcr or dtvr&amp;gt;&amp;amp;sup=&amp;lt;suppress demo look-up&amp;gt;&amp;amp;uoo=&amp;lt;Optout Status &amp;gt;&amp;amp;createtm=&amp;lt;Session Start or End time&amp;gt;&amp;amp;devid=&amp;lt;IDFA/ADID&amp;gt;'''&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Audit Ping Examples:''' &lt;br /&gt;
&lt;br /&gt;
* '''End Audit Ping Example (Startsession)'''&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
https://audit.nmrodam.com/cgi-bin/gn?prd=audit&amp;amp;apid=FC984EC1-E044-B465-E040-070AAD3173A1&amp;amp;sessionid=2576459933726989&amp;amp;streamid=3679422587354472&amp;amp;pingtype=0&amp;amp;product=dcr&amp;amp;sup=0&amp;amp;uoo=1&amp;amp;createtm=1476459970&amp;amp;devid=12b9377cbe7e5c94e8a70d9d23929523d14afa954793130f8a3959c7b849aca8'&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UUID Generator Code ==&lt;br /&gt;
&lt;br /&gt;
/ ID example: LsTYTmZQPwdchsNZkdtJp9lErjgAp1632729088&lt;br /&gt;
&lt;br /&gt;
''' Create random GUID'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
function buildGUID() {&lt;br /&gt;
    var UAIDbase62Characters = &amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
    var UAIDpayloadLength = 29;&lt;br /&gt;
&lt;br /&gt;
    function UAIDgetRandom62() {&lt;br /&gt;
        var r1;&lt;br /&gt;
        do {&lt;br /&gt;
            r1 = Math.floor(Math.random() * (16 * 62));&lt;br /&gt;
        } while (r1 &amp;gt; 61); &lt;br /&gt;
        return r1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var uid = '';&lt;br /&gt;
    for (var a = 0; a &amp;lt; UAIDpayloadLength; a++) {&lt;br /&gt;
        uid += UAIDbase62Characters.charAt(UAIDgetRandom62());&lt;br /&gt;
    }&lt;br /&gt;
    var timestamp_ms = new Date().getTime();&lt;br /&gt;
    uid += String(timestamp_ms).substring(3);&lt;br /&gt;
    return uid;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=Mediametrie_Implementation_Documentation&amp;diff=7479</id>
		<title>Mediametrie Implementation Documentation</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=Mediametrie_Implementation_Documentation&amp;diff=7479"/>
		<updated>2025-12-17T13:56:18Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: new page DCR France Domless SDK added to the landing page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
{{CategoryIcon|DCR.png|Mediametrie Documentation}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;The following guides are specific for Mediametrie.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Mediametrie&lt;br /&gt;
! style=&amp;quot;width: 90px;&amp;quot; | Type&lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | &lt;br /&gt;
! style=&amp;quot;width: 45px;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;width: 40%;&amp;quot; | Guide&lt;br /&gt;
!| Links&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | {{SmallIcon|FRFlag.png}}&lt;br /&gt;
| rowspan=&amp;quot;5&amp;quot; | {{SmallIcon|SDKIcon.png}}&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; | {{OSIcon|VideoIcon.png}}&lt;br /&gt;
|-&lt;br /&gt;
|  {{OSIcon|macOSIcon.png}}&lt;br /&gt;
| '''[[DCR France Video iOS SDK]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|AndroidIcon.png}}&lt;br /&gt;
| '''[[DCR France Video Android SDK]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png}}&lt;br /&gt;
| '''[[DCR France Video Browser SDK]]'''&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{OSIcon|BrowserIcon.png}}&lt;br /&gt;
| '''[[DCR France Domless SDK|DCR France Video Domless SDK]]'''&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| {{SmallIcon|CloudAPIIcon.png}}&lt;br /&gt;
| {{OSIcon|APIIcon.png}}&lt;br /&gt;
| '''[[DCR France Video Cloud API]]'''&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_iOS_SDK&amp;diff=7477</id>
		<title>DCR France Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_iOS_SDK&amp;diff=7477"/>
		<updated>2025-12-08T13:40:08Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: /* Using Swift */  &amp;lt;/syntaxhighlight&amp;gt;&amp;gt; replaced with &amp;lt;/syntaxhighlight&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''Nielsen SDK''' || The Nielsen Digital AppSDK which includes SDK frameworks and '''sample implementation'''; &amp;quot;See [[iOS SDK Release Notes]]&amp;quot; || [[DCR France SDK Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 1: Setting up your iOS Development Environment ==&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, the SDK uses the WKWebView class instead of the deprecated UIWebView as per Apple guidelines. &lt;br /&gt;
&lt;br /&gt;
=== Importing Frameworks ===&lt;br /&gt;
&lt;br /&gt;
1) Extract “NielsenAppApi.Framework” from the Nielsen App SDK zip file and copy it to Frameworks folder of the Xcode project.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Import following frameworks and libraries into the Frameworks of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* AdSupport.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework makes use of a number of functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework&lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective-C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Include header file &amp;lt;code&amp;gt;NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller's header file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
* All communications between the SDK and the Census (Collection Facility) use HTTPS&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
Add the code&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified ||  ✓ || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' ||  || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App Version included in the App Resource File''' ||  || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified || || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified ||  || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;hem_sha1&amp;quot;: @&amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
            @&amp;quot;uid2&amp;quot;: @&amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
            @&amp;quot;hem_sha256&amp;quot;: @&amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;true&amp;quot;,&lt;br /&gt;
           @&amp;quot;optout&amp;quot;: @&amp;quot;false&amp;quot;,&lt;br /&gt;
           @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
           &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
           &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## appDisableApi is called&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted NSString or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
  @&amp;quot;assetid&amp;quot; : @&amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
  @&amp;quot;type&amp;quot; : @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot; : @&amp;quot;program name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot; : @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot; : @&amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
  @&amp;quot;islivestn&amp;quot; : @&amp;quot;y&amp;quot;,&lt;br /&gt;
  @&amp;quot;subbrand&amp;quot; : @&amp;quot;c05&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_md&amp;quot; : @&amp;quot;LIVE&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_ch&amp;quot; : @&amp;quot;860&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_cn&amp;quot; : @&amp;quot;customContentIdentifier&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p0&amp;quot; : @&amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p1&amp;quot; : @&amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
  // ...&lt;br /&gt;
  @&amp;quot;nol_p18&amp;quot; : @&amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p19&amp;quot; : @&amp;quot;p19,optionalValueP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
     let channelInfo = [&lt;br /&gt;
        &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
     let contentMetadata = [&lt;br /&gt;
       &amp;quot;assetid&amp;quot; : &amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot; : &amp;quot;content&amp;quot;,&lt;br /&gt;
        &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
        &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
        &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
        &amp;quot;islivestn&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
        &amp;quot;subbrand&amp;quot; : &amp;quot;c05&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_md&amp;quot; : &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_ch&amp;quot; : &amp;quot;860&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_cn&amp;quot; : &amp;quot;customContentIdentifier&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p0&amp;quot; : &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p1&amp;quot; : &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
        // ...&lt;br /&gt;
        &amp;quot;nol_p18&amp;quot; : &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p19&amp;quot; : &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player. Call play only when initially starting the video.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi play:channelInfo];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.play(channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi loadMetadata:metadataDict];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(metadataDict)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
Note: &amp;quot;playheadPosition&amp;quot; has to be called every second and the value passed should match the broadcast time for live channel.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
[self.nielsenAppApi playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* when an Ad Break starts during the Content Playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
In order to start the measurement, follow the 3 first steps below i.e. for Content without Ads. When terminating the Content playback call &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; to terminate the Content Measurement for the given asset.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Playlist !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 1. Start of stream || &amp;lt;code&amp;gt;play(channelName)&amp;lt;/code&amp;gt; || channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;loadMetadata(contentMetadataObject)&amp;lt;/code&amp;gt; || contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| 2. Content is playing|| &amp;lt;code&amp;gt;playheadPosition(position)&amp;lt;/code&amp;gt; || playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| 3. End of Stream || &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; || Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 5: Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* When an Ad Break starts during the Content Playback&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the current viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Step 6: Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
== Step 7 : Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The App SDK uses Mobile Ad IDs (Android ID or IDFA) which are fully hashed on the device before being sent to Nielsen (Nielsen never receives un-hashed values).&lt;br /&gt;
Users retain the possibility to oppose the use of Mobile Ad IDs, or to reset them, by using the functionality provided by the mobile operating system (iOS or Android).&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initializazion ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
==== Example of SDK Initialization with enableFpid ====&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned on =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;true&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned off =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;false&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;false&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Optout Flag is set by default to &amp;quot;false&amp;quot; in the AppSDK. &lt;br /&gt;
&lt;br /&gt;
For Opt-out users, the Optout Flag can be set accordingly while Initializing the SDK Instance.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example the Ouptout Flag ====&lt;br /&gt;
&lt;br /&gt;
===== User opted out =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
          @&amp;quot;optout&amp;quot;: @&amp;quot;true&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User opted in =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
          @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
          @&amp;quot;optout&amp;quot;: @&amp;quot;false&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;false&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 8 : Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers VoD and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion) that should be ignored since No Ads are measured in France.&lt;br /&gt;
&lt;br /&gt;
Download the Reference Implementation for iOS [https://nielsenonlinesupport.com/dk/ios/DKRefImplSwift.zip DKRefImplSwift].&lt;br /&gt;
Unzip and open the project in Xcode, then run it i.e. in the simulator or on iOS device and then filter the Xcode output with &amp;quot;##&amp;quot; in order to see only relevant Nielsen SDK API Calls, as below:&lt;br /&gt;
&amp;lt;syntaxhighlight&lt;br /&gt;
==##&amp;gt; Nielsen SDK NielsenInit.getAppApi() - create Instance &lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
==##!!&amp;gt; LandingVC -- Nielsen SDK eventOccurred&lt;br /&gt;
==##&amp;gt; Nielsen SDK .play(sdkMethods.loadChannelInfo())&lt;br /&gt;
==##&amp;gt; Nielsen SDK nielsenApi.loadMetadata&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 0 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 1 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 2 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 3 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 4 / 378&lt;br /&gt;
==##&amp;gt; terminatePlaybackSession Nielsen SDK end()&lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 11 :  Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_devDebug: &amp;quot;DEBUG&amp;quot;} from initialization call - see Step 2.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_iOS_SDK&amp;diff=7476</id>
		<title>DCR France Video iOS SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_iOS_SDK&amp;diff=7476"/>
		<updated>2025-12-08T13:35:54Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: update minimum AppSDK version from 9.4 to 10.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''App ID (appid)''' || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || '''Nielsen SDK''' || The Nielsen Digital AppSDK which includes SDK frameworks and '''sample implementation'''; &amp;quot;See [[iOS SDK Release Notes]]&amp;quot; || [[DCR France SDK Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 1: Setting up your iOS Development Environment ==&lt;br /&gt;
&lt;br /&gt;
=== Configuring Xcode Development Environment ===&lt;br /&gt;
Starting with SDK version 6.0.0.0, the Nielsen App SDK is compatible with Apple iOS versions 8.0 and above.  In addition, the SDK uses the WKWebView class instead of the deprecated UIWebView as per Apple guidelines. &lt;br /&gt;
&lt;br /&gt;
=== Importing Frameworks ===&lt;br /&gt;
&lt;br /&gt;
1) Extract “NielsenAppApi.Framework” from the Nielsen App SDK zip file and copy it to Frameworks folder of the Xcode project.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) Import following frameworks and libraries into the Frameworks of the Xcode project before creating an instance of the Nielsen App SDK object.&lt;br /&gt;
* UIKit.framework&lt;br /&gt;
* Foundation.framework&lt;br /&gt;
* AdSupport.framework&lt;br /&gt;
* SystemConfiguration.framework&lt;br /&gt;
* Security.framework&lt;br /&gt;
** Nielsen Analytics framework makes use of a number of functions in this library.&lt;br /&gt;
* AVFoundation.framework&lt;br /&gt;
** This framework is mandatory for the iOS SDK version 5.1.1 to work.&lt;br /&gt;
* CoreLocation.framework&lt;br /&gt;
* CoreMedia.framework&lt;br /&gt;
* NielsenAppApi.framework&lt;br /&gt;
* libc++.tbd (as SDK contains Objective-C++ source file)&lt;br /&gt;
** Alternatively, include -lstdc++ in Build Settings → Other Linker Flag of the Xcode project&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3) Include header file &amp;lt;code&amp;gt;NielsenAppApi/NielsenAppApi.h&amp;lt;/code&amp;gt; to the View Controller's header file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* The SDK uses the NSURLSession instead of the deprecated NSURLConnection.&lt;br /&gt;
* All communications between the SDK and the Census (Collection Facility) use HTTPS&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.&lt;br /&gt;
&lt;br /&gt;
Select File/New File/Objective-C File  &amp;lt;br /&amp;gt;&lt;br /&gt;
Xcode will prompt you to create a bridging header.&lt;br /&gt;
[[File:bridgingheader 2x.png|600px|center|link=]] &amp;lt;br /&amp;gt;&lt;br /&gt;
Once this file has been created, you need to add the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
Add the code&lt;br /&gt;
&amp;lt;syntaxhighlight lang =&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 to the View Controller’s header file.&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified ||  ✓ || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' ||  || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App Version included in the App Resource File''' ||  || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified || || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified ||  || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Sample SDK Initialization Code ====&lt;br /&gt;
&lt;br /&gt;
Initialize the Nielsen App object within the viewDidLoad view controller delegate method using initWithAppInfo:delegate:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;If App SDK is initialized using init or new methods, it will ignore the API calls resulting in no measurement. The SDK will not return any errors.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
                                     @&amp;quot;hem_sha1&amp;quot;: @&amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
            @&amp;quot;uid2&amp;quot;: @&amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
            @&amp;quot;hem_sha256&amp;quot;: @&amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;true&amp;quot;,&lt;br /&gt;
           @&amp;quot;optout&amp;quot;: @&amp;quot;false&amp;quot;,&lt;br /&gt;
           @&amp;quot;nol_devDebug&amp;quot;: @&amp;quot;DEBUG&amp;quot;&lt;br /&gt;
                };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;hem_sha1&amp;quot;: &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;,&lt;br /&gt;
           &amp;quot;uid2&amp;quot;: &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;,&lt;br /&gt;
           &amp;quot;hem_sha256&amp;quot;: &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;true&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;false&amp;quot;,&lt;br /&gt;
           &amp;quot;nol_devDebug&amp;quot;: &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample code using AVPlayer.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ViewController.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class ViewController: UIViewController, NielsenAppApiDelegate, AVPictureInPictureControllerDelegate, CLLocationManagerDelegate  {&lt;br /&gt;
&lt;br /&gt;
    let avPlayerViewController = AVPlayerViewController()&lt;br /&gt;
    var avPlayer:AVPlayer?&lt;br /&gt;
    var nielsenAppApi: NielsenAppApi!&lt;br /&gt;
&lt;br /&gt;
  override func viewDidLoad() {&lt;br /&gt;
        super.viewDidLoad()&lt;br /&gt;
&lt;br /&gt;
        self.nielsenAppApi = NielsenInit.createNielsenAppApi(delegate: self)&lt;br /&gt;
        NSLog(&amp;quot;Nielsen SDK initialized&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# '''Initial state''' – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the '''Initial state'''.&lt;br /&gt;
# '''Idle state''' – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# '''Processing state''' – The SDK instance is processing playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# '''Disabled state''' – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## appDisableApi is called&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted NSString or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&lt;br /&gt;
==== Using Objective-C ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary  *channelInfo = @&lt;br /&gt;
{&lt;br /&gt;
  @&amp;quot;channelName&amp;quot;:@&amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NSDictionary *contentMetadata = @&lt;br /&gt;
  {&lt;br /&gt;
  @&amp;quot;assetid&amp;quot; : @&amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
  @&amp;quot;type&amp;quot; : @&amp;quot;content&amp;quot;,&lt;br /&gt;
  @&amp;quot;program&amp;quot; : @&amp;quot;program name&amp;quot;,&lt;br /&gt;
  @&amp;quot;title&amp;quot; : @&amp;quot;episode title&amp;quot;,&lt;br /&gt;
  @&amp;quot;length&amp;quot; : @&amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
  @&amp;quot;islivestn&amp;quot; : @&amp;quot;y&amp;quot;,&lt;br /&gt;
  @&amp;quot;subbrand&amp;quot; : @&amp;quot;c05&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_md&amp;quot; : @&amp;quot;LIVE&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_ch&amp;quot; : @&amp;quot;860&amp;quot;,&lt;br /&gt;
  @&amp;quot;cli_cn&amp;quot; : @&amp;quot;customContentIdentifier&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p0&amp;quot; : @&amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p1&amp;quot; : @&amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
  // ...&lt;br /&gt;
  @&amp;quot;nol_p18&amp;quot; : @&amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
  @&amp;quot;nol_p19&amp;quot; : @&amp;quot;p19,optionalValueP19&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using Swift ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
     let channelInfo = [&lt;br /&gt;
        &amp;quot;channelName&amp;quot;: &amp;quot;My Channel Name 1&amp;quot;,&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
     let contentMetadata = [&lt;br /&gt;
       &amp;quot;assetid&amp;quot; : &amp;quot;unique_content_id&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot; : &amp;quot;content&amp;quot;,&lt;br /&gt;
        &amp;quot;program&amp;quot; : &amp;quot;program name&amp;quot;,&lt;br /&gt;
        &amp;quot;title&amp;quot; : &amp;quot;episode title&amp;quot;,&lt;br /&gt;
        &amp;quot;length&amp;quot; : &amp;quot;length in seconds&amp;quot;,&lt;br /&gt;
        &amp;quot;islivestn&amp;quot; : &amp;quot;y&amp;quot;,&lt;br /&gt;
        &amp;quot;subbrand&amp;quot; : &amp;quot;c05&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_md&amp;quot; : &amp;quot;LIVE&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_ch&amp;quot; : &amp;quot;860&amp;quot;,&lt;br /&gt;
        &amp;quot;cli_cn&amp;quot; : &amp;quot;customContentIdentifier&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p0&amp;quot; : &amp;quot;p0,optionalValueP0&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p1&amp;quot; : &amp;quot;p1,optionalValueP1&amp;quot;,&lt;br /&gt;
        // ...&lt;br /&gt;
        &amp;quot;nol_p18&amp;quot; : &amp;quot;p18,optionalValueP18&amp;quot;,&lt;br /&gt;
        &amp;quot;nol_p19&amp;quot; : &amp;quot;p19,optionaValuelP19&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the '''Play''' button on the player. Call play only when initially starting the video.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi play:channelInfo];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.play(channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi loadMetadata:metadataDict];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.loadMetadata(metadataDict)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
Note: &amp;quot;playheadPosition&amp;quot; has to be called every second and the value passed should match the broadcast time for live channel.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
[self.nielsenAppApi playheadPosition:pos];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
self.nielsenAppApi?.playheadPosition(pos);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* ads complete playing&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* when an Ad Break starts during the Content Playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi stop];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.stop;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
===== Using Objective-C =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;[self.nielsenAppApi end];&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===== Using Swift =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;self.nielsenAppApi?.end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
In order to start the measurement, follow the 3 first steps below i.e. for Content without Ads. When terminating the Content playback call &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; to terminate the Content Measurement for the given asset.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Playlist !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 1. Start of stream || &amp;lt;code&amp;gt;play(channelName)&amp;lt;/code&amp;gt; || channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;loadMetadata(contentMetadataObject)&amp;lt;/code&amp;gt; || contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| 2. Content is playing|| &amp;lt;code&amp;gt;playheadPosition(position)&amp;lt;/code&amp;gt; || playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| 3. End of Stream || &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; || Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 5: Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* When an Ad Break starts during the Content Playback&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the current viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Step 6: Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
== Step 7 : Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The App SDK uses Mobile Ad IDs (Android ID or IDFA) which are fully hashed on the device before being sent to Nielsen (Nielsen never receives un-hashed values).&lt;br /&gt;
Users retain the possibility to oppose the use of Mobile Ad IDs, or to reset them, by using the functionality provided by the mobile operating system (iOS or Android).&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initializazion ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
==== Example of SDK Initialization with enableFpid ====&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned on =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;true&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== First Party ID turned off =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           @&amp;quot;enableFpid&amp;quot;: @&amp;quot;false&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;enableFpid&amp;quot;: &amp;quot;false&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users  ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Optout Flag is set by default to &amp;quot;false&amp;quot; in the AppSDK. &lt;br /&gt;
&lt;br /&gt;
For Opt-out users, the Optout Flag can be set accordingly while Initializing the SDK Instance.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Example the Ouptout Flag ====&lt;br /&gt;
&lt;br /&gt;
===== User opted out =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
                                     @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
          @&amp;quot;optout&amp;quot;: @&amp;quot;true&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;true&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== User opted in =====&lt;br /&gt;
====== Using Objective-C ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;quot;NlsAppApiFactory.h&amp;quot;&lt;br /&gt;
#import &amp;lt;NielsenAppApi/NielsenAppApi.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@implementation NlsAppApiFactory&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppApi *)createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
{&lt;br /&gt;
    NSDictionary *appInformation = @{&lt;br /&gt;
          @&amp;quot;appid&amp;quot;: @&amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
          @&amp;quot;optout&amp;quot;: @&amp;quot;false&amp;quot;&lt;br /&gt;
                                     };&lt;br /&gt;
    return [[NielsenAppApi alloc] initWithAppInfo:appInformation delegate:delegate];&lt;br /&gt;
}&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following would be the &amp;lt;code&amp;gt;NlsAppApiFactory.h&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
#import &amp;lt;Foundation/Foundation.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@class NielsenAppApi;&lt;br /&gt;
@protocol NielsenAppApiDeligate;&lt;br /&gt;
&lt;br /&gt;
@interface NlsAppApiFactory : NSObject&lt;br /&gt;
&lt;br /&gt;
+ (NielsenAppAPI *) createNielsenAppApiWithDelegate:(id&amp;lt;NielsenAppApiDelegate&amp;gt;)delegate;&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Using Swift ======&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;NielsenInit.swift&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;swift&amp;quot;&amp;gt;&lt;br /&gt;
class NielsenInit: NSObject {&lt;br /&gt;
    class func createNielsenAppApi(delegate: NielsenAppApiDelegate) -&amp;gt; NielsenAppApi?{&lt;br /&gt;
    let appInformation:[String: String] = [&lt;br /&gt;
           &amp;quot;appid&amp;quot;: &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;,&lt;br /&gt;
           &amp;quot;optout&amp;quot;: &amp;quot;false&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
        return NielsenAppApi(appInfo:appInformation, delegate:delegate)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 8 : Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers VoD and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion) that should be ignored since No Ads are measured in France.&lt;br /&gt;
&lt;br /&gt;
Download the Reference Implementation for iOS [https://nielsenonlinesupport.com/dk/ios/DKRefImplSwift.zip DKRefImplSwift].&lt;br /&gt;
Unzip and open the project in Xcode, then run it i.e. in the simulator or on iOS device and then filter the Xcode output with &amp;quot;##&amp;quot; in order to see only relevant Nielsen SDK API Calls, as below:&lt;br /&gt;
&amp;lt;syntaxhighlight&lt;br /&gt;
==##&amp;gt; Nielsen SDK NielsenInit.getAppApi() - create Instance &lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
==##!!&amp;gt; LandingVC -- Nielsen SDK eventOccurred&lt;br /&gt;
==##&amp;gt; Nielsen SDK .play(sdkMethods.loadChannelInfo())&lt;br /&gt;
==##&amp;gt; Nielsen SDK nielsenApi.loadMetadata&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 0 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 1 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 2 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 3 / 378&lt;br /&gt;
==##&amp;gt; Nielsen SDK updatePlayheadPosition, pos = 4 / 378&lt;br /&gt;
==##&amp;gt; terminatePlaybackSession Nielsen SDK end()&lt;br /&gt;
==##!!&amp;gt; LandingVC -- viewDidAppear&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 11 :  Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_devDebug: &amp;quot;DEBUG&amp;quot;} from initialization call - see Step 2.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Android_SDK&amp;diff=7475</id>
		<title>DCR France Video Android SDK</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=DCR_France_Video_Android_SDK&amp;diff=7475"/>
		<updated>2025-12-08T13:34:57Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: update minimum AppSDK version from 9.4 to 10.1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|Mediametrie Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Nielsen SDK is one of multiple framework SDKs that Nielsen provides to enable measuring linear (live) and on-demand TV viewing using TVs, mobile devices, etc.&lt;br /&gt;
The App SDK is the framework for mobile application developers to integrate Nielsen Measurement into their media player applications. It supports a variety of Nielsen Measurement Products like  It supports a variety of Nielsen Measurement Products like Digital in TV Ratings ([[DCR &amp;amp; DTVR|DTVR]]), Digital Content Ratings ([[DCR &amp;amp; DTVR|DCR]]), and [[Digital Ad Ratings]] (DAR). Nielsen SDKs are also equipped to measure static content and can track key life cycle events of an application like:&lt;br /&gt;
*Application launch events and how long app was running&lt;br /&gt;
*Time of viewing a sub section / page in the application.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
Before you start the integration, you will need:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 30px;&amp;quot; |&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Item&lt;br /&gt;
! Description&lt;br /&gt;
! Source&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;App ID (appid)&amp;quot; || Unique ID assigned to the player/site and configured by product. || Contact Médiamétrie&lt;br /&gt;
|-style=&amp;quot;background-color:#d0f6f8;&amp;quot;&lt;br /&gt;
|| ☑ || &amp;quot;Nielsen SDK&amp;quot; || The Nielsen Digital AppSDK which includes SDK frameworks and &amp;quot;sample implementation&amp;quot;; &amp;quot;See [[Android SDK Release Notes]]&amp;quot; || [[DCR France SDK Downloads|Download]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market! The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 1: Setting up your Android Development Environment  ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
1) Ensure to unzip the Nielsen App SDK zip file and copy the &amp;quot;AppSdk.jar&amp;quot; into the app/libs folder on the App’s project. Add it as dependency.&amp;lt;br /&amp;gt;&lt;br /&gt;
2) Add the following permissions on the project’s &amp;quot;AndroidManifest.xml&amp;quot; file.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.ACCESS_NETWORK_STATE&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;uses-permission android:name=&amp;quot;android.permission.INTERNET&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) Add Google Play Services lib into dependencies as Nielsen AppSDK uses the following packages/classes from the Google Play service.&lt;br /&gt;
Libraries:&lt;br /&gt;
* com.google.android.gms:play-services&lt;br /&gt;
Requiered Google Play Service CLasses and Packages :&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient;&lt;br /&gt;
* com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;&lt;br /&gt;
* com.google.android.gms.common.ConnectionResult;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesUtil;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesRepairableException;&lt;br /&gt;
* com.google.android.gms.common.GooglePlayServicesNotAvailableException;&lt;br /&gt;
&lt;br /&gt;
4) Once the files are in place, import com.nielsen.app.sdk to the java source code and start accessing the public interface.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;import com.nielsen.app.sdk.*;&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
*The Nielsen App SDK (located in the &amp;quot;com.nielsen.app.sdk&amp;quot; package) class is the primary application interface to the Nielsen App SDK on Android.&lt;br /&gt;
*The Nielsen App SDK class is defined as the only public class belonging to the com.nielsen.app.sdk package.&lt;br /&gt;
*Nielsen App SDK is compatible with Android OS versions 2.3+.&lt;br /&gt;
*Clients can control / configure the protocol to be used – HTTPS or HTTP to suit their needs.&lt;br /&gt;
*The Android OS hosting the App SDK should use a media player supporting HLS streaming (Android 4.0 and later will support it natively).&lt;br /&gt;
*If the player application uses a 3rd party media player implementing its own HLS/MPEG-DASH stack, then the minimum Android version will be limited to version 2.3, since the SDK depends on Google Play support to work properly.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Create SDK Instance ==&lt;br /&gt;
The latest version of the Nielsen App SDK allows instantiating multiple instances of the SDK object when needed, which can then be used simultaneously. '''For the general use case where only one video is played at the same time in the App, a single instance of SDK object can then be used to play back and measure all watched streams one after another.'''&lt;br /&gt;
&lt;br /&gt;
The following table contains the list of arguments that can be passed via the AppInfo JSON schema.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter / Argument !! Description !! Source !! Required !! Example&lt;br /&gt;
|-&lt;br /&gt;
| appid || Unique id for the application assigned by Nielsen. It is GUID data type.|| Nielsen-specified || ✓ || &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appname || Name of the application || '''value is automatically populated through App Name included in the App Resource File''' ||  || &amp;quot;Nielsen Sample App&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| appversion || Current version of the app used || '''value is automatically populated through App version included in the App Resource File''' ||  || &amp;quot;1.0.2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha1 ||	hashed (SHA256) value of member id || Nielsen-specified || || i.e. for the sample memberID &amp;quot;userMemberID123&amp;quot;, the value to pass is &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|uid2 ||	hashed(SHA256) value of UID2 || Nielsen-specified || ||	 i.e. for the sample UID2 &amp;quot;userUID2&amp;quot;, the value to pass is &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|hem_sha256 ||	hashed(SHA256) value of the user email address || Nielsen-specified || ||	 i.e. for the sample email address &amp;quot;useremail@company.com&amp;quot;, the value to pass is &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|enableFpid ||	Optional:turn on or off the First Party ID || Nielsen-specified || || &amp;quot;true&amp;quot; for turn on,  &amp;quot;false&amp;quot; for turn off. The default value is &amp;quot;true&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|optout ||	OptOut global parameter. This optout will be maintained through the session of the SDK instance || Nielsen-specified || ✓ || &amp;quot;true&amp;quot; for opted out,  &amp;quot;false&amp;quot; for NOT opted out or opted in. The default value is &amp;quot;false&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| nol_devDebug || Enables Nielsen console logging. Only required for testing&lt;br /&gt;
|| Nielsen-specified ||  || &amp;quot;DEBUG&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt; If the User consent changes while using the App, you have to delete the current SDK instance and create a new instance with the updated optout and enableFpid values. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1) AppSDK() is no longer a singleton object and should be created as below.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;hem_sha1&amp;quot;, &amp;quot;7ed2155ee9964d69ca425b0aceccda25d5462e06228a40d0da4dce5a4eb3e826&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;uid2&amp;quot;, &amp;quot;7b733f363eb756046bf72bf476d24611e931e763222a7e89537477261f7bae05&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;hem_sha256&amp;quot;, &amp;quot;0da83f9ab3bf59e3638f96d83409878fb507d3edd4d3637ca5eae4ddda5bb969&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
2) implement IAppNotifier into your activity like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public class MainActivity extends AppCompatActivity implements IAppNotifier&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3) implement callback&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;@Override&lt;br /&gt;
public void onAppSdkEvent(long timestamp, int code, String description){&lt;br /&gt;
  Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So whole Activity will look like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.example.josefvancura.nlsdemotmp;&lt;br /&gt;
&lt;br /&gt;
import android.content.Context;&lt;br /&gt;
import android.support.v7.app.AppCompatActivity;&lt;br /&gt;
import android.os.Bundle;&lt;br /&gt;
import android.util.Log;&lt;br /&gt;
&lt;br /&gt;
import com.nielsen.app.sdk.*;&lt;br /&gt;
&lt;br /&gt;
import org.json.JSONException;&lt;br /&gt;
import org.json.JSONObject;&lt;br /&gt;
&lt;br /&gt;
public class MainActivity extends AppCompatActivity implements IAppNotifier {&lt;br /&gt;
&lt;br /&gt;
    private AppSdk mAppSdk = null;&lt;br /&gt;
    private String TAG = &amp;quot;MainActivity&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void onCreate(Bundle savedInstanceState) {&lt;br /&gt;
        super.onCreate(savedInstanceState);&lt;br /&gt;
        setContentView(R.layout.activity_main);&lt;br /&gt;
&lt;br /&gt;
        Context context = getApplicationContext();&lt;br /&gt;
&lt;br /&gt;
        try{&lt;br /&gt;
            // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
            JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
                    .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
                    .put(&amp;quot;nol_devDebug&amp;quot;, &amp;quot;DEBUG&amp;quot;); // only for debug builds&lt;br /&gt;
&lt;br /&gt;
            // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
            mAppSdk = new AppSdk(context, appSdkConfig, this ); // Notifier - activity implements IAppNotifier, callback in onAppSdkEvent()&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (JSONException e){&lt;br /&gt;
            Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void onAppSdkEvent(long timestamp, int code, String description) {&lt;br /&gt;
        Log.d(TAG, &amp;quot;SDK callback onAppSdkEvent &amp;quot; + description);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== APP SDK Error &amp;amp; Event Codes ====&lt;br /&gt;
To view the Error and Event codes for iOS and Android, please review the [[APP SDK Event Codes|App SDK Event Code]] Reference page.&lt;br /&gt;
&lt;br /&gt;
==== Life cycle of SDK instance ====&lt;br /&gt;
Life cycle of SDK instance includes four general states:&lt;br /&gt;
# &amp;quot;&amp;quot;Initial state&amp;quot;&amp;quot; – The SDK is not initialized and hence, not ready to process playing information. Once the SDK is moved out of this state, it needs instantiation of the new SDK instance in order to get the instance in the &amp;quot;&amp;quot;Initial state&amp;quot;&amp;quot;.&lt;br /&gt;
# &amp;quot;&amp;quot;Idle state&amp;quot;&amp;quot; – The SDK is initialized and is ready to process playing information. Once Initialized, the SDK instance is not processing any data, but is listening for the play event to occur.&lt;br /&gt;
# &amp;quot;&amp;quot;Processing state&amp;quot;&amp;quot; – The SDK instance is processing playing information. API calls &amp;quot;play&amp;quot; and &amp;quot;loadMetadata&amp;quot; move the SDK instance into this state. In this state, the SDK instance will be able to process the API calls (see below)&lt;br /&gt;
# &amp;quot;&amp;quot;Disabled state&amp;quot;&amp;quot; – The SDK instance is disabled and is not processing playing information. SDK instance moves into this state in one of the following scenarios.&lt;br /&gt;
## Initialization fails&lt;br /&gt;
## &amp;lt;code&amp;gt;appDisableApi&amp;lt;/code&amp;gt; is called&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objective-c&amp;quot;&amp;gt;&lt;br /&gt;
@property (assign) BOOL appDisableApi;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create Metadata Objects ==&lt;br /&gt;
The parameters passed must be either a JSON formatted string or a NSDictionary object. The JSON passed in the SDK must be well-formed.&lt;br /&gt;
* NSDictionary object&lt;br /&gt;
** If an object of unexpected type is passed to the method, the error message will be logged.&lt;br /&gt;
** If string has invalid JSON format, the error message will be logged.&lt;br /&gt;
* JSON value must be string value.&lt;br /&gt;
** This includes boolean and numeric values. For example, a value of true should be represented with &amp;quot;true&amp;quot;, number value 123 should be &amp;quot;123&amp;quot;.&lt;br /&gt;
** All the Variable Names like appid, appname, dataSrc, title, type etc. are case-sensitive. Use the correct variable name as specified in the documentation.&lt;br /&gt;
* JSON string can be prepared using either raw NSString or serialized NSDictionary.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create channelName Metadata ===&lt;br /&gt;
channelName should remain constant throughout the completion of an episode or live stream.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !!	Values	 !! Required&lt;br /&gt;
|-&lt;br /&gt;
| channelName	|| Any string representing the channel/stream	|| custom	|| ✓&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Create Content Metadata ===&lt;br /&gt;
Content metadata should remain constant throughout the entirety of an episode/clip including when ads play.&lt;br /&gt;
&lt;br /&gt;
Note: All metadata values should be passed as UTF-8 strings.&lt;br /&gt;
&lt;br /&gt;
Please see the [[France SDK Metadata#Content Metadata|Mediametrie Content Metadata]] for the complete list of content metadata.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MetaData Example ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
JSONObject channelInfo = new JSONObject()&lt;br /&gt;
    .put(&amp;quot;channelName&amp;quot;,&amp;quot;My Channel Name 1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
JSONObject contentMetadata = new JSONObject()&lt;br /&gt;
   .put(&amp;quot;type&amp;quot;, &amp;quot;content&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;assetid&amp;quot;, &amp;quot;unique_content_id&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;program&amp;quot;, &amp;quot;program name&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;title&amp;quot;, &amp;quot;episode title&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;length&amp;quot;, &amp;quot;length in seconds&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;islivestn&amp;quot;, &amp;quot;y&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;subbrand&amp;quot;, &amp;quot;c05&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;cli_md&amp;quot;, &amp;quot;LIVE&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;cli_ch&amp;quot;, &amp;quot;860&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;cli_cn&amp;quot;, &amp;quot;customContentIdentifier&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;nol_p0&amp;quot;, &amp;quot;p0,optionalValueP0&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;nol_p1&amp;quot;, &amp;quot;p1,optionalValueP1&amp;quot;)&lt;br /&gt;
   // ...&lt;br /&gt;
   .put(&amp;quot;nol_p18&amp;quot;, &amp;quot;p18,optionalValueP18&amp;quot;)&lt;br /&gt;
   .put(&amp;quot;nol_p19&amp;quot;, &amp;quot;p19,optionaValuelP19&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Start the Measurement ==&lt;br /&gt;
&lt;br /&gt;
=== Overview of SDK API Calls ===&lt;br /&gt;
&lt;br /&gt;
==== play ====&lt;br /&gt;
The play method prepares the SDK for reporting once an asset has loaded and playback has begun. Use play to pass the channel descriptor information through channelName parameter when the user taps the &amp;quot;&amp;quot;Play&amp;quot;&amp;quot; button on the player. Call play only when initially starting the video.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.play(JSONObject channelInfo);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadMetadata ====&lt;br /&gt;
Needs to be called at the beginning of each asset, pass JSON object for relevant content. Make sure to pass as 1st loadMetadata for content at the begining of playlist - see below API call sequence examples.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.loadMetadata(JSONObject contentMetadata);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== playheadPosition ====&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#d0f6f8&amp;quot;&amp;gt;&lt;br /&gt;
Note: &amp;quot;setPlayheadPosition&amp;quot; has to be called every second and the value passed should match the broadcast time for live channel.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* VOD: current position in seconds. Pass whole number that increments only by 1 like 0,1,2,3... &amp;lt;br/&amp;gt;&lt;br /&gt;
* Live: Unix timestamp matching the broadcast time for Content (seconds since Jan-1-1970 UTC). Pass whole number that increments only by 1 like 1631098029,1631098030,1631098031,1631098032,... &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;mAppSdk.setPlayheadPosition(long videoPositon);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== stop ====&lt;br /&gt;
Call when&lt;br /&gt;
* when a user pauses playback&lt;br /&gt;
* when an Ad Break starts during the Content Playback&lt;br /&gt;
* upon any user interruption scenario - see bellow chapter Interruption scenario&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.stop();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== end ====&lt;br /&gt;
Call when the content asset completes playback.  Stops measurement progress.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;mAppSdk.end();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Start the Measurement ===&lt;br /&gt;
In order to start the measurement, follow the 3 first steps below for Content without Ads. When terminating the Content playback call &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; to terminate the Content Measurement for the given asset.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Playlist !! Sample code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 1. Start of stream || &amp;lt;code&amp;gt;play(channelName)&amp;lt;/code&amp;gt; || channelName contains JSON metadata of channel/video name being played&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;loadMetadata(contentMetadataObject)&amp;lt;/code&amp;gt; || contentMetadataObject contains the JSON metadata for the content being played&lt;br /&gt;
|-&lt;br /&gt;
| 2. Content is playing || &amp;lt;code&amp;gt;playheadPosition(position)&amp;lt;/code&amp;gt; || playheadPosition is position of the playhead while the content is being played&lt;br /&gt;
|-&lt;br /&gt;
| 3. End of Stream || &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; || Content playback is completed.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Step 5: Stop/Resume the Measurement for video Playback Interruptions ==&lt;br /&gt;
As part of integrating Nielsen App SDK with the player application, the Audio / Video app developer needs to handle the following possible interruption scenarios:&lt;br /&gt;
* Pause / Play&lt;br /&gt;
* Network Loss (Wi-Fi / Airplane / Cellular)&lt;br /&gt;
* Call Interrupt (SIM or Third party Skype / Hangout call)&lt;br /&gt;
* Alarm Interrupt&lt;br /&gt;
* Content Buffering&lt;br /&gt;
* Device Lock / Unlock (Video players only, not for Audio players)&lt;br /&gt;
* App going in the Background/Foreground (Video players only, not for Audio players)&lt;br /&gt;
* Channel / Station Change Scenario&lt;br /&gt;
* Unplugging of headphone&lt;br /&gt;
In case of encountering one of the above interruptions, the player application needs to&lt;br /&gt;
* Call &amp;lt;code&amp;gt;stop&amp;lt;/code&amp;gt; immediately (except when content is buffering) and withhold sending playhead position.&lt;br /&gt;
* Once the playback resumes, start sending pings &amp;lt;code&amp;gt;playheadPosition&amp;lt;/code&amp;gt; for the new viewing session.&lt;br /&gt;
Please see the [[Digital Measurement FAQ]] for more details&lt;br /&gt;
&lt;br /&gt;
== Step 6: Review SDK Integration Architecture Diagram ==&lt;br /&gt;
&lt;br /&gt;
=== For Content Playback ===&lt;br /&gt;
&lt;br /&gt;
[[File:nlsn-sdk-achitecture-diagram-content-fr.png||SDK Integration Architecture Diagram - Content]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Step 7 : Disclose Nielsen Privacy Statement ==&lt;br /&gt;
The App SDK uses Mobile Ad IDs (Android ID or IDFA) which are fully hashed on the device before being sent to Nielsen (Nielsen never receives un-hashed values).&lt;br /&gt;
Users retain the possibility to oppose the use of Mobile Ad IDs, or to reset them, by using the functionality provided by the mobile operating system (iOS or Android).&lt;br /&gt;
&lt;br /&gt;
In order to disclose Nielsen measurement privacy statement, please include the following items in your privacy policy:&lt;br /&gt;
* A notice that the player includes third party measurement software that allows users to contribute to market research.&lt;br /&gt;
* A link to the Nielsen Digital Measurement Privacy Policy located at https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/ .&lt;br /&gt;
&lt;br /&gt;
=== Initialization of the SDK based on User Consent in your App ===&lt;br /&gt;
&lt;br /&gt;
In collaboration with Mediametrie, the following user consent use cases need to be implemented in your App.&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly accepts measurement ====&lt;br /&gt;
 The SDK is initialized and all IDs are captured. The SDK Opt-in Flags have to be set accordingly, see:&lt;br /&gt;
&lt;br /&gt;
* [[#User opted in|User opted in]]&lt;br /&gt;
* [[#First Party ID turned on|First Party ID turned on]]&lt;br /&gt;
&lt;br /&gt;
==== The user explicitly refuses measurement ====&lt;br /&gt;
The SDK is NOT initialized and No Nielsen SDK measurement will occur.&lt;br /&gt;
&lt;br /&gt;
==== The user did not explicitly give consent for the measurement(consent neither given nor refused) ====&lt;br /&gt;
 The SDK is initialized and no IDs are captured. The SDK Opt-out Flags have to be set accordingly, see:&lt;br /&gt;
* [[#User opted out|User opted out]]&lt;br /&gt;
* [[#First Party ID turned off|First Party ID turned off]]&lt;br /&gt;
&lt;br /&gt;
=== Turning off the First Party ID for Opt-out Users during the SDK Initializazion ===&lt;br /&gt;
The First Party ID(FPID) is enabled by default in the Browser SDK. For Opt-out users, the First Party ID can be turned off during the initialization of the SDK Instance, i.e. the parameter enableFpid can be set to &amp;quot;false&amp;quot; (FPID disabled) or &amp;quot;true&amp;quot; (FPID enabled). &lt;br /&gt;
&lt;br /&gt;
===== Example of SDK Initialization with enableFpid =====&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned on ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== First Party ID turned off ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;enableFpid&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Setting the  SDK global optout Flag for Opt-out Users  ===&lt;br /&gt;
&lt;br /&gt;
The Optout Flag is set by default to &amp;quot;false&amp;quot; in the AppSDK. &lt;br /&gt;
&lt;br /&gt;
For Opt-out users, the Optout Flag can be set accordingly while Initializing the SDK Instance.&lt;br /&gt;
* &amp;lt;blockquote&amp;gt;'''Ad flavour of AppSDK''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;The Ad flavour of AppSDK should be downloaded for the french market!  The AppSDK Version 10.1.0.0 or higher must be downloaded&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Example the Ouptout Flag =====&lt;br /&gt;
&lt;br /&gt;
====== User opted out ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;optout&amp;quot;, &amp;quot;true&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== User opted in======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try{&lt;br /&gt;
  // Prepare AppSdk configuration object (JSONObject)&lt;br /&gt;
  JSONObject appSdkConfig = new JSONObject()&lt;br /&gt;
          .put(&amp;quot;appid&amp;quot;, &amp;quot;PXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&amp;quot;)&lt;br /&gt;
          .put(&amp;quot;optout&amp;quot;, &amp;quot;false&amp;quot;)&lt;br /&gt;
          // ...&lt;br /&gt;
         // Pass appSdkConfig to the AppSdk constructor&lt;br /&gt;
         mAppSdk = new AppSdk(appContext, appSdkConfig, this);&lt;br /&gt;
}&lt;br /&gt;
catch (JSONException e){&lt;br /&gt;
         Log.e(TAG, &amp;quot;Couldn’t prepare JSONObject for appSdkConfig&amp;quot;, e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 8 : Review the Reference Implementation for VoD and Live Streams ==&lt;br /&gt;
&lt;br /&gt;
The Reference Implementation covers VoD and Live use cases. &lt;br /&gt;
The code also covers also DAI (Dynamic Ad Insertion)  that should be ignored since No Ads are measured in France.&lt;br /&gt;
&lt;br /&gt;
Download the Reference Implementation for Android [https://nielsenonlinesupport.com/dk/android/DKRefPLAYER.zip DKRefPLAYER].&lt;br /&gt;
Unzip and open the project in Android Studio, then run it i.e. in the simulator or on Android device and then filter the Logcat output with &amp;quot;&amp;gt;&amp;gt;&amp;gt;&amp;quot; in order to see only relevant Nielsen SDK API Calls, as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
2021-04-08 15:11:27.075  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : class NielsenInit :: Create new AppSdk() Instance.&lt;br /&gt;
2021-04-08 15:11:27.568  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK EVENT - onAppSdkEvent: Description = Nielsen App SDK is initiated. AppSdk.jar aa.8.0.0.0_gsxaon. App SDK was successfully initiatedCode l param : 1617887487Code i param 2000&lt;br /&gt;
2021-04-08 15:11:29.497  D/NielsenInit: ====&amp;gt;&amp;gt;&amp;gt; SDK EVENT - onAppSdkEvent: Description = Nielsen App SDK has started up. AppSdk.jar aa.8.0.0.0_gsxaon. Config file successfully loaded and parsed.Code l param : 1617887489Code i param 2001&lt;br /&gt;
2021-04-08 15:11:42.736  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :  appSdk.play(sdkMethods.loadChannelInfo());&lt;br /&gt;
2021-04-08 15:11:42.738  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : onPrepared() : appSdk.loadMetadata(data)&lt;br /&gt;
2021-04-08 15:11:43.065  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Media Player Event : onInfo ();what = 3&lt;br /&gt;
2021-04-08 15:11:43.065  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Media Player Event :  first video frame pushed for rendering.&lt;br /&gt;
2021-04-08 15:11:43.747  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 0 / 224&lt;br /&gt;
2021-04-08 15:11:44.752  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 1 / 224&lt;br /&gt;
2021-04-08 15:11:45.759  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 2 / 224&lt;br /&gt;
2021-04-08 15:11:46.764  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 3 / 224&lt;br /&gt;
2021-04-08 15:11:47.767  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 4 / 224&lt;br /&gt;
2021-04-08 15:11:48.772  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 5 / 224&lt;br /&gt;
2021-04-08 15:11:49.777  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 6 / 224&lt;br /&gt;
2021-04-08 15:11:50.781  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 7 / 224&lt;br /&gt;
2021-04-08 15:11:51.819  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL :   appSdk.setPlayheadPosition(mCurrentPosition): @ 8 / 224&lt;br /&gt;
2021-04-08 15:11:51.821  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; Activity onPause()&lt;br /&gt;
2021-04-08 15:11:52.668  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt;: Activity onDestroy()&lt;br /&gt;
2021-04-08 15:11:52.668  D/MainActivity: ====&amp;gt;&amp;gt;&amp;gt; SDK CALL : terminateNielsenSDK () :appSdk.end();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 9 :  Test your player by yourself ==&lt;br /&gt;
=== Guide ===&lt;br /&gt;
1. Connect your PC and test device (tablet or phone) via same router.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. PC side: run Proxy sw (like Charles) and get local IP&amp;lt;br /&amp;gt;&lt;br /&gt;
3. Test device: modify Wifi setting to pass through Proxy IP from step 2.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Test device: run your player, launch video&amp;lt;br /&amp;gt;&lt;br /&gt;
5. PC side: filter traffic by &amp;quot;nmr&amp;quot; and confirm presence of GN pings&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example of GN ping ===&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;https://secure-fr.nmrodam.com/cgi-bin/gn?prd=dcr&amp;amp;ci=us-500207&amp;amp;ch=us-500207_c77_P&amp;amp;asn=defChnAsset&amp;amp;fp_id=&amp;amp;fp_cr_tm=&amp;amp;fp_acc_tm=&amp;amp;fp_emm_tm=&amp;amp;ve_id=&amp;amp;devmodel=&amp;amp;manuf=&amp;amp;sysname=&amp;amp;sysversion=&amp;amp;sessionId=zlmmxkq867zt4bpnumlyz6dpn9hyp1610980356&amp;amp;tl=Episode%201&amp;amp;prv=1&amp;amp;c6=vc%2Cc77&amp;amp;ca=us-500207_c77_VID5556674-123456&amp;amp;cg=TAMSample%20DK&amp;amp;c13=asid%2CP10DF14BA-937E-436D-99DF-ED39A0422387&amp;amp;c32=segA%2CNA&amp;amp;c33=segB%2CNA&amp;amp;c34=segC%2CNA&amp;amp;c15=apn%2C&amp;amp;plugv=&amp;amp;playerv=&amp;amp;sup=1&amp;amp;segment2=&amp;amp;segment1=&amp;amp;forward=0&amp;amp;ad=0&amp;amp;cr=4_00_99_V1_00000&amp;amp;c9=devid%2C&amp;amp;enc=true&amp;amp;c1=nuid%2C999&amp;amp;at=view&amp;amp;rt=video&amp;amp;c16=sdkv%2Cbj.6.0.0&amp;amp;c27=cln%2C0&amp;amp;crs=&amp;amp;lat=&amp;amp;lon=&amp;amp;c29=plid%2C16109803568088038&amp;amp;c30=bldv%2C6.0.0.563&amp;amp;st=dcr&amp;amp;c7=osgrp%2C&amp;amp;c8=devgrp%2C&amp;amp;c10=plt%2C&amp;amp;c40=adbid%2C&amp;amp;c14=osver%2CNA&amp;amp;c26=dmap%2C1&amp;amp;dd=&amp;amp;hrd=&amp;amp;wkd=&amp;amp;c35=adrsid%2C&amp;amp;c36=cref1%2C&amp;amp;c37=cref2%2C&amp;amp;c11=agg%2C1&amp;amp;c12=apv%2C&amp;amp;c51=adl%2C0&amp;amp;c52=noad%2C0&amp;amp;sd=170&amp;amp;devtypid=&amp;amp;pc=NA&amp;amp;c53=fef%2Cy&amp;amp;c54=oad%2C20200713%2010%3A22%3A00&amp;amp;c55=cref3%2C&amp;amp;c57=adldf%2C2&amp;amp;ai=VID5556674-123456&amp;amp;c3=st%2Cc&amp;amp;c64=starttm%2C1610980392&amp;amp;adid=VID5556674-123456&amp;amp;c58=isLive%2Cfalse&amp;amp;c59=sesid%2Cgezrb92q4i9b9jg7acxgn783gjw0a1610980365&amp;amp;c61=createtm%2C1610980392&amp;amp;c63=pipMode%2C&amp;amp;c68=bndlid%2C&amp;amp;nodeTM=&amp;amp;logTM=&amp;amp;c73=phtype%2C&amp;amp;c74=dvcnm%2C&amp;amp;c76=adbsnid%2C&amp;amp;c77=adsuprt%2C2&amp;amp;uoo=&amp;amp;evdata=&amp;amp;c71=ottflg%2C0&amp;amp;c72=otttyp%2Cnone&amp;amp;c44=progen%2C&amp;amp;davty=0&amp;amp;si=http%3A%2F%2Fnielsenonlinesupport.com%2Fdk%2Findex.htm&amp;amp;c66=mediaurl%2Cassets%252FRTVOD_C3%252Fprog_index.m3u8&amp;amp;c62=sendTime%2C1610980392&amp;amp;rnd=714644&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 10 :  Provide your app for certification ==&lt;br /&gt;
Once ready, please send a request (https://portail-marqueurs.mediametrie.com) to Médiamétrie local staff for certification.&lt;br /&gt;
&lt;br /&gt;
== Step 11 :  Going Live ==&lt;br /&gt;
After the integration has been certified (but not prior that), disable debug logging by deleting {nol_devDebug: &amp;quot;DEBUG&amp;quot;} from initialization call - see Step 2.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=AGF_Specific_Implementation_Guidelines_for_Video_Measurement&amp;diff=7467</id>
		<title>AGF Specific Implementation Guidelines for Video Measurement</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=AGF_Specific_Implementation_Guidelines_for_Video_Measurement&amp;diff=7467"/>
		<updated>2025-11-26T10:33:44Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: original uploaded pdf file url used for handbook&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
''' AGF SDK Specific Implementation Guidelines for Video Measurement '''&lt;br /&gt;
&lt;br /&gt;
Please be sure that the Nielsen Technical Account Managers(TAMs) test all the player functionalities.&lt;br /&gt;
Here are the most common (and basic) player features that are checked during the certification process:&lt;br /&gt;
* appID&lt;br /&gt;
* Loadmetadata (content, ads)&lt;br /&gt;
* pause&lt;br /&gt;
* scrub forward, backward&lt;br /&gt;
* scrub to the start of a particular video (VOD)&lt;br /&gt;
* scrub almost to the end of a video (VOD) /to make sure an END event is called/&lt;br /&gt;
* slow internet connection (throttling) (STBs are an exception as the connection is usually stable/ 	&lt;br /&gt;
* subtitles on/off&lt;br /&gt;
* fullscreen on/off&lt;br /&gt;
* audio change&lt;br /&gt;
* playback speed&lt;br /&gt;
* video playback quality&lt;br /&gt;
* any specific features like “highlights”, “key points” or similar&lt;br /&gt;
* download functionality (the measurement should keep running if there is no network and the user plays an offline content)&lt;br /&gt;
* “Live button” (in case of livestreams of course)&lt;br /&gt;
* [mobile devices]: lock the screen&lt;br /&gt;
* [mobile devices]: move the app to background and then back to foreground&lt;br /&gt;
* [mobile devices]: alarm clock going off&lt;br /&gt;
* [mobile devices]: flight mode&lt;br /&gt;
* [mobile devices]: close/kill the app&lt;br /&gt;
 &lt;br /&gt;
The test cases depend on the particular player and device type.&lt;br /&gt;
Please note that further features can be tested if necessary.&lt;br /&gt;
If there is any specific player feature not available in each video, please let the Nielsen TAMs know about it.&lt;br /&gt;
  &lt;br /&gt;
'''Please see details on all Test Cases [https://mywikis-wiki-media.s3.us-central-1.wasabisys.com/nielsen/Handbook-AGF-EN.pdf here]'''.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=AGF_Metadata_Convention&amp;diff=7466</id>
		<title>AGF Metadata Convention</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=AGF_Metadata_Convention&amp;diff=7466"/>
		<updated>2025-11-26T09:51:26Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: new section &amp;quot;SDK specific Guidelines&amp;quot; as per AGF request from Jonas&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= AGF Metadata Convention =&lt;br /&gt;
&lt;br /&gt;
The  Metadata can pass through key values using the Nielsen reserved keys. The keys and values are listed by the product below. &lt;br /&gt;
&lt;br /&gt;
'''Note:''' All metadata values should be passed as UTF-8 strings.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Static Measurement ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''AppSDK version &amp;gt;= 9.1.0.0 is required''': &amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt; &lt;br /&gt;
The newly introduced AppSDK API staticEnd() is required for the Static Measurement. &lt;br /&gt;
The staticEnd() API is available only for AppSDK version 9.1.0.0 or higher &amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In order to avoid incorrect / implausible filling of individual STATIC metadata and custom-variables please refer to the following additional AGF assistance: &lt;br /&gt;
* '''[https://engineeringportal.nielsen.com/wiki/File:250807_AGF_Metadata_Static-Display_v.1.0_english.pdf Guide for STATIC metadata &amp;amp; custom variables (english version)]'''&lt;br /&gt;
* '''[https://engineeringportal.nielsen.com/wiki/File:250807_AGF_Metadata_Static-Display_v.1.0_deutsch.pdf Guide for STATIC metadata &amp;amp; custom variables (german version)]'''&lt;br /&gt;
&lt;br /&gt;
== Video Measurement ==&lt;br /&gt;
&lt;br /&gt;
Please refer to this AGF Metadata Document for Video: &lt;br /&gt;
* '''[https://nielsendownloads-blue.digitalengsdk.com/digital/AGF_Video_Measure_June132024/240304_AGF+Custom+Variables+and+Metadata+DCR+SDK++v1.10_english.pdf Metadata and custom-Variables Document for Video (english version)]'''&lt;br /&gt;
* '''[https://nielsendownloads-blue.digitalengsdk.com/digital/AGF_Video_Measure_June132024/240304_AGF%20Custom%20Variables%20and%20Metadata%20DCR%20SDK%20v.1.10_deutsch.pdf Metadata and custom-Variables Document for Video (german version)]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In order to avoid incorrect / implausible filling of individual metadata and custom-variables please refer to the following additional assistance: &lt;br /&gt;
* '''[https://nielsendownloads-blue.digitalengsdk.com/digital/AGF_Video_Measure_June132024/20240606%20guide%20metadata%20&amp;amp;%20custom%20variables%20-%20english.pdf Guide for metadata &amp;amp; custom variables (english version)]'''&lt;br /&gt;
* '''[https://nielsendownloads-blue.digitalengsdk.com/digital/AGF_Video_Measure_June132024/20240606%20guide%20metadata%20&amp;amp;%20custom%20variables%20-%20deutsch.pdf Guide for metadata &amp;amp; custom variables (german version)]'''&lt;br /&gt;
&lt;br /&gt;
=== SDK specific Guidelines ===&lt;br /&gt;
Please refer to this '''[[AGF Specific Implementation Guidelines for Video Measurement|AGF Specific Implementation Guidelines regarding SDK integrations]]'''.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=AGF_Specific_Implementation_Guidelines_for_Video_Measurement&amp;diff=7465</id>
		<title>AGF Specific Implementation Guidelines for Video Measurement</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=AGF_Specific_Implementation_Guidelines_for_Video_Measurement&amp;diff=7465"/>
		<updated>2025-11-26T09:49:26Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: version updated with AGF text sent by Jonas&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|AGF Implementation Documentation}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
''' AGF SDK Specific Implementation Guidelines for Video Measurement '''&lt;br /&gt;
&lt;br /&gt;
Please be sure that the Nielsen Technical Account Managers(TAMs) test all the player functionalities.&lt;br /&gt;
Here are the most common (and basic) player features that are checked during the certification process:&lt;br /&gt;
* appID&lt;br /&gt;
* Loadmetadata (content, ads)&lt;br /&gt;
* pause&lt;br /&gt;
* scrub forward, backward&lt;br /&gt;
* scrub to the start of a particular video (VOD)&lt;br /&gt;
* scrub almost to the end of a video (VOD) /to make sure an END event is called/&lt;br /&gt;
* slow internet connection (throttling) (STBs are an exception as the connection is usually stable/ 	&lt;br /&gt;
* subtitles on/off&lt;br /&gt;
* fullscreen on/off&lt;br /&gt;
* audio change&lt;br /&gt;
* playback speed&lt;br /&gt;
* video playback quality&lt;br /&gt;
* any specific features like “highlights”, “key points” or similar&lt;br /&gt;
* download functionality (the measurement should keep running if there is no network and the user plays an offline content)&lt;br /&gt;
* “Live button” (in case of livestreams of course)&lt;br /&gt;
* [mobile devices]: lock the screen&lt;br /&gt;
* [mobile devices]: move the app to background and then back to foreground&lt;br /&gt;
* [mobile devices]: alarm clock going off&lt;br /&gt;
* [mobile devices]: flight mode&lt;br /&gt;
* [mobile devices]: close/kill the app&lt;br /&gt;
 &lt;br /&gt;
The test cases depend on the particular player and device type.&lt;br /&gt;
Please note that further features can be tested if necessary.&lt;br /&gt;
If there is any specific player feature not available in each video, please let the Nielsen TAMs know about it.&lt;br /&gt;
  &lt;br /&gt;
'''Please see details on all Test Cases [https://engineeringportal.nielsen.com/wiki/File:Handbook-AGF-EN.pdf here]'''.&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
	<entry>
		<id>https://engineeringportal.nielsen.com/w/index.php?title=File:Handbook-AGF-EN.pdf&amp;diff=7464</id>
		<title>File:Handbook-AGF-EN.pdf</title>
		<link rel="alternate" type="text/html" href="https://engineeringportal.nielsen.com/w/index.php?title=File:Handbook-AGF-EN.pdf&amp;diff=7464"/>
		<updated>2025-11-26T09:47:20Z</updated>

		<summary type="html">&lt;p&gt;MichelFodjo: Handbook AGF english&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Handbook AGF english&lt;/div&gt;</summary>
		<author><name>MichelFodjo</name></author>
	</entry>
</feed>