<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://nielsentest.mywikis.net/w/index.php?action=history&amp;feed=atom&amp;title=DCR_Chromecast_iOS_SDK</id>
	<title>DCR Chromecast iOS SDK - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://nielsentest.mywikis.net/w/index.php?action=history&amp;feed=atom&amp;title=DCR_Chromecast_iOS_SDK"/>
	<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_iOS_SDK&amp;action=history"/>
	<updated>2026-04-05T17:23:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_iOS_SDK&amp;diff=6405&amp;oldid=prev</id>
		<title>Admin: /* RECIEVER side : */</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_iOS_SDK&amp;diff=6405&amp;oldid=prev"/>
		<updated>2023-07-12T15:56:08Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;RECIEVER side :&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:56, 12 July 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l244&quot;&gt;Line 244:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 244:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== RECIEVER side : ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== RECIEVER side : ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Playback has started at ChromeCast device (TV)&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Playback has started at ChromeCast device (TV)&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;7) Retrieve the &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;MediaMedaData &lt;/del&gt;sent by the sender device.&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;7) Retrieve the &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;MediaMetaData &lt;/ins&gt;sent by the sender device.&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;8) Instantiate the Browser SDK.&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;8) Instantiate the Browser SDK.&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;9) Pass metadata by calling '''loadMetaData()'''.&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;9) Pass metadata by calling '''loadMetaData()'''.&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_iOS_SDK&amp;diff=6115&amp;oldid=prev</id>
		<title>NickParrucci: /* 2.2 Chromecast mirroring scenario */</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_iOS_SDK&amp;diff=6115&amp;oldid=prev"/>
		<updated>2023-02-09T15:22:31Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;2.2 Chromecast mirroring scenario&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:22, 9 February 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l22&quot;&gt;Line 22:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 22:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 2.2 Chromecast mirroring scenario ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 2.2 Chromecast mirroring scenario ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The video is playing on both the sender and receiver apps. &amp;lt;br /&amp;gt;  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The video is playing on both the sender and receiver apps. &amp;lt;br /&amp;gt;  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Both the sender and receiver apps should pass Nielsen API calls.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[File:Screen Shot 2018-09-25 at 09.35.19.png|600px|center]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[File:Screen Shot 2018-09-25 at 09.35.19.png|600px|center]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
	<entry>
		<id>https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_iOS_SDK&amp;diff=6109&amp;oldid=prev</id>
		<title>NickParrucci: Created page with &quot;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp; DTVR}}  {{CurrentBreadcrumb}} Category:Digital  == 1. General Cast architecture == &lt;br /&gt; File:Screen Shot 2018...&quot;</title>
		<link rel="alternate" type="text/html" href="https://nielsentest.mywikis.net/w/index.php?title=DCR_Chromecast_iOS_SDK&amp;diff=6109&amp;oldid=prev"/>
		<updated>2023-02-02T20:36:42Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}} &lt;a href=&quot;/wiki/Category:Digital&quot; title=&quot;Category:Digital&quot;&gt;Category:Digital&lt;/a&gt;  == 1. General Cast architecture == &amp;lt;br /&amp;gt; File:Screen Shot 2018...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Breadcrumb|}} {{Breadcrumb|Digital}} {{Breadcrumb|DCR &amp;amp; DTVR}}  {{CurrentBreadcrumb}}&lt;br /&gt;
[[Category:Digital]]&lt;br /&gt;
&lt;br /&gt;
== 1. General Cast architecture ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Screen Shot 2018-09-25 at 10.26.22(1).png||600px|center|]]&lt;br /&gt;
See https://developers.google.com/cast/docs/developers&lt;br /&gt;
&lt;br /&gt;
=== Sender App ===&lt;br /&gt;
is a user-controlled native app that runs on a mobile device (Android, iOS) or a laptop (JS).&lt;br /&gt;
&lt;br /&gt;
=== Receiver App ===&lt;br /&gt;
is an HTML5/JavaScript application placed at a custom URL that handles communication between the sender app and the Chromecast device.&lt;br /&gt;
&lt;br /&gt;
== 2. Cast scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Pure casting scenario === &lt;br /&gt;
The video is only playing on a Chromecast device. &amp;lt;br /&amp;gt;&lt;br /&gt;
The sender app should not pass any Nielsen API calls once the pure casting scenario starts. All Nielsen API calls are handled by the receiver app.&lt;br /&gt;
[[File:Screen Shot 2018-09-25 at 09.35.08.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Chromecast mirroring scenario ===&lt;br /&gt;
The video is playing on both the sender and receiver apps. &amp;lt;br /&amp;gt; &lt;br /&gt;
Both the sender and receiver apps should pass Nielsen API calls.&lt;br /&gt;
[[File:Screen Shot 2018-09-25 at 09.35.19.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
== 3.Sender App (iOS) - Nielsen SDK implementation ==&lt;br /&gt;
&lt;br /&gt;
=== 3.1 General ===&lt;br /&gt;
By adding the below cast-specific API calls alongside the standard implementation of the Nielsen AppSDK into your native application, a sender app can pass appropriate cast-specific metadata.&lt;br /&gt;
&lt;br /&gt;
=== 3.2 API call updateOTT ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
mAppSdk.updateOTT(JSONObject ottInfo)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Use the updateOTT method to notify the AppSDK whether the remote OTT device (like Google ChromeCast, Roku, Amazon FireTV, etc.) is connected or disconnected (indicated by &amp;quot;ottStatus&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
When the OTT device is connected, call updateOTT with &amp;quot;ottStatus&amp;quot;: &amp;quot;1&amp;quot; as well as a set of OTT device related parameters in the ottInfo Dictionary.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary *ottInfo = @&lt;br /&gt;
        {&lt;br /&gt;
   @&amp;quot;ottStatus&amp;quot;: @&amp;quot;1&amp;quot;,&lt;br /&gt;
   @&amp;quot;ottType&amp;quot;: @&amp;quot;casting&amp;quot;,&lt;br /&gt;
   @&amp;quot;ottDevice&amp;quot;: @&amp;quot;chromecast&amp;quot;,&lt;br /&gt;
   @&amp;quot;ottDeviceName&amp;quot;: @&amp;quot;Google ChromeCast&amp;quot;,&lt;br /&gt;
   @&amp;quot;ottDeviceID&amp;quot;: @&amp;quot;xxxx-xxxx-xxxx&amp;quot;,&lt;br /&gt;
   @&amp;quot;ottDeviceManufacturer&amp;quot;: @&amp;quot;Google&amp;quot;,&lt;br /&gt;
   @&amp;quot;ottDeviceModel&amp;quot;: @&amp;quot;ChromeCast&amp;quot;,&lt;br /&gt;
   @&amp;quot;ottDeviceVersion&amp;quot;: @&amp;quot;1.0.0&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the OTT device is disconnected, call updateOTT with &amp;quot;ottStatus&amp;quot;: &amp;quot;0&amp;quot;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
NSDictionary *ottInfo = @&lt;br /&gt;
{&lt;br /&gt;
    @&amp;quot;ottStatus&amp;quot;: @&amp;quot;0&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* Every time the application is launched or moves to foreground, call updateOTT to report the current OTT status.&lt;br /&gt;
* The application needs to report all the possible OTT types (casting, screen mirroring, and any other types) to App SDK.&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Communicating with the Chromecast Receiver App ===&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
SDK cannot communicate directly with the Receiver App running on the Chromecast as it needs access to the Google Casting framework. Alternatively, App SDK requires the application to pass the data to the Receiver App. The application should:&lt;br /&gt;
* Retrieve the Opt-Out status on the device (using [https://engineeringportal.nielsen.com/docs/optOutStatus getOptOutStatus()]) and its Demographic ID (using [https://engineeringportal.nielsen.com/docs/demographicId getDemographicId()])&lt;br /&gt;
* Relay the retrieved details / values to the Receiver App, as additional parameters in GCKMediaMetadata payload.&lt;br /&gt;
** Create the metadata information for this purpose, using GCKMediaMetadata.&lt;br /&gt;
The two custom parameters to be included in GCKMediaMetadata are&lt;br /&gt;
*kGCKMetadataNlsKeyDeviceID for device ID.&lt;br /&gt;
*kGCKMetadataNlsKeyOptout for Opt-out status (true or false).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Notes :&lt;br /&gt;
* To get more information about Opt Out, please refer to [https://engineeringportal.nielsen.com/docs/DCR_Video_iOS_SDK general AppSDK implementation guide]: Privacy and Nielsen Opt-Out&lt;br /&gt;
* Result of getOptOutStatus() should be 0 or 1 (true or false)&lt;br /&gt;
* Result of getDemographicId() is an alphanumeric string (ex: a5ff494cce22bda39b29da2509f90f52e4e044587107ba9ca092eb3a1c2eccdf)&lt;br /&gt;
* IMPORTANT: Nielsen Opt Out status is completely dependent on the setting in the sender device (iPhone or iPad) - not any settings in the ChromeCast menus.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Below is a sample code snippet on how the application should retrieve and relay the information from App SDK to Receiver App:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static NSString * const kGCKMetadataNlsKeyDeviceID = @&amp;quot;kGCKMetadataNlsKeyDeviceID&amp;quot;;&lt;br /&gt;
static NSString * const kGCKMetadataNlsKeyOptout = @&amp;quot;kGCKMetadataNlsKeyOptout&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc] init];&lt;br /&gt;
NSUInteger channelIndex = [self.appConfig.channels indexOfObject:self.currentChannel] + 1;&lt;br /&gt;
[metadata setString:[NSString stringWithFormat:@&amp;quot;Channel %d&amp;quot;, channelIndex] forKey:kGCKMetadataKeyTitle];&lt;br /&gt;
[metadata setString:self.currentChannel.urlString forKey:kGCKMetadataKeySubtitle];&lt;br /&gt;
&lt;br /&gt;
// custom parameters&lt;br /&gt;
[metadata setString:self.nielsenAppApi.demographicId forKey:kGCKMetadataNlsKeyDeviceID];&lt;br /&gt;
[metadata setString:(self.nielsenAppApi.optOutStatus) forKey:kGCKMetadataNlsKeyOptout];&lt;br /&gt;
&lt;br /&gt;
[self logConsole:[NSString stringWithFormat:@&amp;quot;Reporting parameters to receiver. %@: %@, %@: %@&amp;quot;, kGCKMetadataNlsKeyDeviceID, self.nielsenAppApi.demographicId, kGCKMetadataNlsKeyOptout, (self.nielsenAppApi.optOutStatus)]];&lt;br /&gt;
&lt;br /&gt;
GCKMediaInformation *mediaInformation =&lt;br /&gt;
[[GCKMediaInformation alloc] initWithContentID:self.currentChannel.urlString&lt;br /&gt;
                                    streamType:GCKMediaStreamTypeUnknown&lt;br /&gt;
                                    contentType:@&amp;quot;video/mp4&amp;quot;&lt;br /&gt;
                                    metadata:metadata&lt;br /&gt;
                                    streamDuration:0&lt;br /&gt;
                                    customData:nil];&lt;br /&gt;
[self.chromecastControlChannel loadMedia:mediaInformation autoplay:YES playPosition:0];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4. Receiver app (JavaScript) - Nielsen SDK implementation  ==&lt;br /&gt;
Once casting starts, the receiver app becomes important as a BSDK instance must be created and the related appropriate API events must be called. Please refer to the Browser SDK guide for more information.&lt;br /&gt;
&lt;br /&gt;
=== 4.1 BSDK init ===&lt;br /&gt;
The BSDK receiver instance gets initialized on load of the Chromecast receiver app.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
window.nolSDKInstance = NOLBUNDLE.nlsQ(&amp;quot;Pxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx&amp;quot;, &amp;quot;ChromeCastInstance&amp;quot; );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note: replace &amp;quot;Pxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx&amp;quot; with your Nielsen provided AppID.&lt;br /&gt;
&lt;br /&gt;
=== 4.2 LoadMetadata=== &lt;br /&gt;
On load of remote player, retrieve content metadata sent by the sender device and pass it using the loadMetadata API call.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
var metadata = {&lt;br /&gt;
              &amp;quot;assetid&amp;quot; : senderMetadata.assetid,&lt;br /&gt;
              &amp;quot;type&amp;quot; : senderMetadata.type,&lt;br /&gt;
              &amp;quot;program&amp;quot; : senderMetadata.program,&lt;br /&gt;
              &amp;quot;title&amp;quot; : senderMetadata.title,&lt;br /&gt;
              &amp;quot;length&amp;quot; : senderMetadata.length,&lt;br /&gt;
              &amp;quot;mediaUrl&amp;quot; : senderMetadata.mediaUrl,&lt;br /&gt;
              &amp;quot;airdate&amp;quot; : senderMetadata.airdate,&lt;br /&gt;
              &amp;quot;isfullepisode&amp;quot; : senderMetadata.isfullepisode,&lt;br /&gt;
              &amp;quot;crossId1&amp;quot; : senderMetadata.crossId1,&lt;br /&gt;
              &amp;quot;nol_c1&amp;quot; : senderMetadata.nol_c1,&lt;br /&gt;
              &amp;quot;nol_c2&amp;quot; : senderMetadata.nol_c2,&lt;br /&gt;
              &amp;quot;segB&amp;quot; : senderMetadata.segB,&lt;br /&gt;
              &amp;quot;segC&amp;quot; : senderMetadata.segC,&lt;br /&gt;
              &amp;quot;adloadtype&amp;quot; : senderMetadata.adloadtype,&lt;br /&gt;
              &amp;quot;hasAds&amp;quot; : senderMetadata.hasAds&lt;br /&gt;
          };&lt;br /&gt;
window.nolSDKInstance.ggPM('loadmetadata', metadata);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note : refer to specification of Czech MetaData and follow it&lt;br /&gt;
&lt;br /&gt;
=== 4.3 updateOTT  ===&lt;br /&gt;
Send the updateOTT event to BSDK receiver instance. The updateOTT event should relay the ottmetadata (kGCKMetadataNlsKeyDeviceID and kGCKMetadataNlsKeyOptout) received from sender app.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
sessionId = senderMetadata.kGCKMetadataNlsKeyNUID?senderMetadata.kGCKMetadataNlsKeyNUID:senderMetadata.kGCKMetadataNlsKeyDeviceID;&lt;br /&gt;
&lt;br /&gt;
var contentMetadataObject ={&lt;br /&gt;
                        type: &amp;quot;content&amp;quot;,&lt;br /&gt;
                        ottStatus: &amp;quot;1&amp;quot;,&lt;br /&gt;
                        ottType: &amp;quot;casting&amp;quot;,&lt;br /&gt;
                        ottDevice: &amp;quot;chromecast&amp;quot;,&lt;br /&gt;
                        ottDeviceName: &amp;quot;Google Chromecast&amp;quot;,&lt;br /&gt;
                        ottDeviceID: sessionId,&lt;br /&gt;
                        ottDeviceManufacturer: &amp;quot;Google&amp;quot;,&lt;br /&gt;
                        ottDeviceModel: &amp;quot;ChromeCastModel&amp;quot;,&lt;br /&gt;
                        ottDeviceVersion: &amp;quot;1.0.0&amp;quot;, &lt;br /&gt;
    kGCKMetadataNlsKeyOptout : ([&amp;quot;1&amp;quot;,true,1,&amp;quot;true&amp;quot;].indexOf(senderMetadata.kGCKMetadataNlsKeyOptout)&amp;gt;=0)?true:false,&lt;br /&gt;
                        kGCKMetadataNlsKeyDeviceID : sessionId&lt;br /&gt;
                  };&lt;br /&gt;
window.nolSDKInstance.ggPM('updateOTT', contentMetadataObject);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4.4 Rest of API calls  ===&lt;br /&gt;
Fire off other API calls based on App/Player state. Refer to the BSDK implementation guide for more information.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// play&lt;br /&gt;
window.nolSDKInstance.ggPM('play',Math.round(event.path[0].currentTime));&lt;br /&gt;
&lt;br /&gt;
// setPlayheadPosition&lt;br /&gt;
window.nolSDKInstance.ggPM('setPlayheadPosition',Math.round(event.path[0].currentTime));&lt;br /&gt;
&lt;br /&gt;
// pause&lt;br /&gt;
window.nolSDKInstance.ggPM('pause',Math.round(event.path[0].currentTime));&lt;br /&gt;
&lt;br /&gt;
// stop&lt;br /&gt;
window.nolSDKInstance.ggPM('stop',Math.round(event.path[0].currentTime));&lt;br /&gt;
&lt;br /&gt;
// end&lt;br /&gt;
window.nolSDKInstance.ggPM('end',Math.round(event.path[0].currentTime));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4.4 Sample code  ===&lt;br /&gt;
Below is a sample code snippet on how the receiver app should retrieve the ottMetadata received from sender apps and relay the information to receiver BSDK instance.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
sampleplayer.CastPlayer.prototype.onLoad_ = function(event) {&lt;br /&gt;
&lt;br /&gt;
var senderMetadata = event.data.media.metadata,&lt;br /&gt;
	    &lt;br /&gt;
sessionId =senderMetadata.kGCKMetadataNlsKeyDeviceID;&lt;br /&gt;
&lt;br /&gt;
  this.cancelDeferredPlay_('new media is loaded');&lt;br /&gt;
  this.load(new cast.receiver.MediaManager.LoadInfo( (event.data),  event.senderId));&lt;br /&gt;
	var contentMetadata = {&lt;br /&gt;
         	      &amp;quot;assetid&amp;quot; : senderMetadata.assetid,&lt;br /&gt;
              &amp;quot;type&amp;quot; : senderMetadata.type,&lt;br /&gt;
              &amp;quot;program&amp;quot; : senderMetadata.program,&lt;br /&gt;
              &amp;quot;title&amp;quot; : senderMetadata.title,&lt;br /&gt;
              &amp;quot;length&amp;quot; : senderMetadata.length,&lt;br /&gt;
              &amp;quot;mediaUrl&amp;quot; : senderMetadata.mediaUrl,&lt;br /&gt;
              &amp;quot;airdate&amp;quot; : senderMetadata.airdate,&lt;br /&gt;
              &amp;quot;isfullepisode&amp;quot; : senderMetadata.isfullepisode,&lt;br /&gt;
              &amp;quot;crossId1&amp;quot; : senderMetadata.crossId1,&lt;br /&gt;
              &amp;quot;nol_c1&amp;quot; : senderMetadata.nol_c1,&lt;br /&gt;
              &amp;quot;nol_c2&amp;quot; : senderMetadata.nol_c2,&lt;br /&gt;
              &amp;quot;segB&amp;quot; : senderMetadata.segB,&lt;br /&gt;
              &amp;quot;segC&amp;quot; : senderMetadata.segC,&lt;br /&gt;
              &amp;quot;adloadtype&amp;quot; : senderMetadata.adloadtype,&lt;br /&gt;
              &amp;quot;hasAds&amp;quot; : senderMetadata.hasAds&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
      window.nolSDKInstance.ggPM('loadmetadata', contentMetadata);&lt;br /&gt;
	  &lt;br /&gt;
	   var ottMetadataObject ={&lt;br /&gt;
			ottStatus: &amp;quot;1&amp;quot;,&lt;br /&gt;
			ottType: &amp;quot;casting&amp;quot;,&lt;br /&gt;
			ottDevice: &amp;quot;chromecast&amp;quot;,&lt;br /&gt;
			ottDeviceName: &amp;quot;Google Chromecast&amp;quot;,&lt;br /&gt;
			ottDeviceID: sessionId,&lt;br /&gt;
			ottDeviceManufacturer: &amp;quot;Google&amp;quot;,&lt;br /&gt;
			ottDeviceModel: &amp;quot;ChromeCastModel&amp;quot;,&lt;br /&gt;
			ottDeviceVersion: &amp;quot;1.0.0&amp;quot;, &lt;br /&gt;
			kGCKMetadataNlsKeyOptout : senderMetadata.kGCKMetadataNlsKeyOptout,&lt;br /&gt;
		              kGCKMetadataNlsKeyDeviceID : sessionId	&lt;br /&gt;
		  };&lt;br /&gt;
&lt;br /&gt;
window.nolSDKInstance.ggPM('updateOTT', ottMetadataObject);};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. Summary - Correct squence of API calls ==&lt;br /&gt;
Below is the sequence of API calls sequence from the beginning to the end of casting.&lt;br /&gt;
&lt;br /&gt;
=== SENDER side : === &lt;br /&gt;
1) If the video is playing only on the sender app, the standard Nielsen SDK API calls should be invoked.&amp;lt;br /&amp;gt;&lt;br /&gt;
2) Once a user presses the cast icon and if the video was playing already, call '''end()'''.&amp;lt;br /&amp;gt;&lt;br /&gt;
3) Inform the AppSDK about the Chromecast's status (connected or disconnected) by calling '''updateOTT(config metadata)'''. &amp;lt;br /&amp;gt;&lt;br /&gt;
4) Retrieve the optOutStatus and demographicId by calling '''getOptOutStatus()''' and '''getDemographicId()'''.&amp;lt;br /&amp;gt;&lt;br /&gt;
5) Pass the optOutStatus and demographicId into the MediaMetaData object.&amp;lt;br /&amp;gt;&lt;br /&gt;
6) Start casting (the video should be stopped on the sender device).&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RECIEVER side : ===&lt;br /&gt;
Playback has started at ChromeCast device (TV)&amp;lt;br /&amp;gt;&lt;br /&gt;
7) Retrieve the MediaMedaData sent by the sender device.&amp;lt;br /&amp;gt;&lt;br /&gt;
8) Instantiate the Browser SDK.&amp;lt;br /&amp;gt;&lt;br /&gt;
9) Pass metadata by calling '''loadMetaData()'''.&amp;lt;br /&amp;gt;&lt;br /&gt;
10) Pass playheads every second by calling '''setPlayheadPosition()'''.&amp;lt;br /&amp;gt;&lt;br /&gt;
11) Based on the user's interactions or the playlist state, call '''stop()''' (once paused) or '''end()''' (once the content or casting has ended).&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SENDER side : === &lt;br /&gt;
Casting has ended and playback continues on the sender device&amp;lt;br /&amp;gt;&lt;br /&gt;
12) Start a new session by calling '''play()''' and '''loadMetaData()'''.&amp;lt;br /&amp;gt;&lt;br /&gt;
13) Continue sending API calls as usual.&lt;br /&gt;
&lt;br /&gt;
== 6. Testing implementation ==&lt;br /&gt;
See https://developers.google.com/cast/docs/debugging&amp;lt;br /&amp;gt;&lt;br /&gt;
Note: make sure that all your test devices and PC are connected to the same network.&amp;lt;br /&amp;gt;&lt;br /&gt;
1. Start the iOS/iPad application and play video.&amp;lt;br /&amp;gt;&lt;br /&gt;
2. Connect the app to Chromecast by pressing the cast button.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Screen Shot 2018-09-25 at 10.15.38.png|400px|center]]&lt;br /&gt;
3. Launch Chrome browser and access URL chrome://inspect.&amp;lt;br /&amp;gt;&lt;br /&gt;
4. Under your ChromeCast device, press “inspect”&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Screen Shot 2018-09-25 at 10.15.49.png|600px|center]]&lt;br /&gt;
5. In your browser console, check JS activity - including Nielsen SDK. Note: make sure that the BSDK has DEBUG mode on.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Screen Shot 2018-09-25 at 10.16.02.png|600px|center]]&lt;br /&gt;
6. In your Network – make sure that outgoing data to Nielsen collection is present.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:Screen Shot 2018-09-25 at 10.21.23.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== 7. Demos ==&lt;br /&gt;
=== Function Demo Explanation (video) ===&lt;br /&gt;
https://youtu.be/Xw-D2H8BpRQ&lt;br /&gt;
&lt;br /&gt;
=== Sender (Android) ===&lt;br /&gt;
https://sdkdemo.admosphere.cz/demo-android/NielsenUScastDemo/v1.0/MPMTVRCastJV.apk&amp;lt;br /&amp;gt;&lt;br /&gt;
https://sdkdemo.admosphere.cz/demo-android/NielsenUScastDemo/v1.0/MPMTVRCastJV.zip&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reciever (JavaScript) ===&lt;br /&gt;
https://sdkdemo.admosphere.cz/demo-android/NielsenUScastDemo/v1.0/reciever.zip&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>NickParrucci</name></author>
	</entry>
</feed>