DCR Chromecast iOS SDK
From Engineering Client Portal
1. General Cast architecture
See https://developers.google.com/cast/docs/developers
Sender App
is a user-controlled native app that runs on a mobile device (Android, iOS) or a laptop (JS).
Receiver App
is an HTML5/JavaScript application placed at a custom URL that handles communication between the sender app and the Chromecast device.
2. Cast scenarios
2.1 Pure casting scenario
The video is only playing on a Chromecast device.
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.
2.2 Chromecast mirroring scenario
The video is playing on both the sender and receiver apps.
Both the sender and receiver apps should pass Nielsen API calls.
3.Sender App (iOS) - Nielsen SDK implementation
3.1 General
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.
3.2 API call updateOTT
mAppSdk.updateOTT(JSONObject ottInfo)
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 "ottStatus").
When the OTT device is connected, call updateOTT with "ottStatus": "1" as well as a set of OTT device related parameters in the ottInfo Dictionary.
NSDictionary *ottInfo = @
{
@"ottStatus": @"1",
@"ottType": @"casting",
@"ottDevice": @"chromecast",
@"ottDeviceName": @"Google ChromeCast",
@"ottDeviceID": @"xxxx-xxxx-xxxx",
@"ottDeviceManufacturer": @"Google",
@"ottDeviceModel": @"ChromeCast",
@"ottDeviceVersion": @"1.0.0"
}
When the OTT device is disconnected, call updateOTT with "ottStatus": "0".
NSDictionary *ottInfo = @
{
@"ottStatus": @"0"
}
Notes:
- Every time the application is launched or moves to foreground, call updateOTT to report the current OTT status.
- The application needs to report all the possible OTT types (casting, screen mirroring, and any other types) to App SDK.
3.3 Communicating with the Chromecast Receiver App
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:
- Retrieve the Opt-Out status on the device (using getOptOutStatus()) and its Demographic ID (using getDemographicId())
- Relay the retrieved details / values to the Receiver App, as additional parameters in GCKMediaMetadata payload.
- Create the metadata information for this purpose, using GCKMediaMetadata.
The two custom parameters to be included in GCKMediaMetadata are
- kGCKMetadataNlsKeyDeviceID for device ID.
- kGCKMetadataNlsKeyOptout for Opt-out status (true or false).
Notes :
- To get more information about Opt Out, please refer to general AppSDK implementation guide: Privacy and Nielsen Opt-Out
- Result of getOptOutStatus() should be 0 or 1 (true or false)
- Result of getDemographicId() is an alphanumeric string (ex: a5ff494cce22bda39b29da2509f90f52e4e044587107ba9ca092eb3a1c2eccdf)
- 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.
Below is a sample code snippet on how the application should retrieve and relay the information from App SDK to Receiver App:
static NSString * const kGCKMetadataNlsKeyDeviceID = @"kGCKMetadataNlsKeyDeviceID";
static NSString * const kGCKMetadataNlsKeyOptout = @"kGCKMetadataNlsKeyOptout";
GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc] init];
NSUInteger channelIndex = [self.appConfig.channels indexOfObject:self.currentChannel] + 1;
[metadata setString:[NSString stringWithFormat:@"Channel %d", channelIndex] forKey:kGCKMetadataKeyTitle];
[metadata setString:self.currentChannel.urlString forKey:kGCKMetadataKeySubtitle];
// custom parameters
[metadata setString:self.nielsenAppApi.demographicId forKey:kGCKMetadataNlsKeyDeviceID];
[metadata setString:(self.nielsenAppApi.optOutStatus) forKey:kGCKMetadataNlsKeyOptout];
[self logConsole:[NSString stringWithFormat:@"Reporting parameters to receiver. %@: %@, %@: %@", kGCKMetadataNlsKeyDeviceID, self.nielsenAppApi.demographicId, kGCKMetadataNlsKeyOptout, (self.nielsenAppApi.optOutStatus)]];
GCKMediaInformation *mediaInformation =
[[GCKMediaInformation alloc] initWithContentID:self.currentChannel.urlString
streamType:GCKMediaStreamTypeUnknown
contentType:@"video/mp4"
metadata:metadata
streamDuration:0
customData:nil];
[self.chromecastControlChannel loadMedia:mediaInformation autoplay:YES playPosition:0];
4. Receiver app (JavaScript) - Nielsen SDK implementation
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.
4.1 BSDK init
The BSDK receiver instance gets initialized on load of the Chromecast receiver app.
window.nolSDKInstance = NOLBUNDLE.nlsQ("Pxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", "ChromeCastInstance" );
Note: replace "Pxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" with your Nielsen provided AppID.
4.2 LoadMetadata
On load of remote player, retrieve content metadata sent by the sender device and pass it using the loadMetadata API call.
var metadata = {
"assetid" : senderMetadata.assetid,
"type" : senderMetadata.type,
"program" : senderMetadata.program,
"title" : senderMetadata.title,
"length" : senderMetadata.length,
"mediaUrl" : senderMetadata.mediaUrl,
"airdate" : senderMetadata.airdate,
"isfullepisode" : senderMetadata.isfullepisode,
"crossId1" : senderMetadata.crossId1,
"nol_c1" : senderMetadata.nol_c1,
"nol_c2" : senderMetadata.nol_c2,
"segB" : senderMetadata.segB,
"segC" : senderMetadata.segC,
"adloadtype" : senderMetadata.adloadtype,
"hasAds" : senderMetadata.hasAds
};
window.nolSDKInstance.ggPM('loadmetadata', metadata);
Note : refer to specification of Czech MetaData and follow it
4.3 updateOTT
Send the updateOTT event to BSDK receiver instance. The updateOTT event should relay the ottmetadata (kGCKMetadataNlsKeyDeviceID and kGCKMetadataNlsKeyOptout) received from sender app.
sessionId = senderMetadata.kGCKMetadataNlsKeyNUID?senderMetadata.kGCKMetadataNlsKeyNUID:senderMetadata.kGCKMetadataNlsKeyDeviceID;
var contentMetadataObject ={
type: "content",
ottStatus: "1",
ottType: "casting",
ottDevice: "chromecast",
ottDeviceName: "Google Chromecast",
ottDeviceID: sessionId,
ottDeviceManufacturer: "Google",
ottDeviceModel: "ChromeCastModel",
ottDeviceVersion: "1.0.0",
kGCKMetadataNlsKeyOptout : (["1",true,1,"true"].indexOf(senderMetadata.kGCKMetadataNlsKeyOptout)>=0)?true:false,
kGCKMetadataNlsKeyDeviceID : sessionId
};
window.nolSDKInstance.ggPM('updateOTT', contentMetadataObject);
4.4 Rest of API calls
Fire off other API calls based on App/Player state. Refer to the BSDK implementation guide for more information.
// play
window.nolSDKInstance.ggPM('play',Math.round(event.path[0].currentTime));
// setPlayheadPosition
window.nolSDKInstance.ggPM('setPlayheadPosition',Math.round(event.path[0].currentTime));
// pause
window.nolSDKInstance.ggPM('pause',Math.round(event.path[0].currentTime));
// stop
window.nolSDKInstance.ggPM('stop',Math.round(event.path[0].currentTime));
// end
window.nolSDKInstance.ggPM('end',Math.round(event.path[0].currentTime));
4.4 Sample code
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.
sampleplayer.CastPlayer.prototype.onLoad_ = function(event) {
var senderMetadata = event.data.media.metadata,
sessionId =senderMetadata.kGCKMetadataNlsKeyDeviceID;
this.cancelDeferredPlay_('new media is loaded');
this.load(new cast.receiver.MediaManager.LoadInfo( (event.data), event.senderId));
var contentMetadata = {
"assetid" : senderMetadata.assetid,
"type" : senderMetadata.type,
"program" : senderMetadata.program,
"title" : senderMetadata.title,
"length" : senderMetadata.length,
"mediaUrl" : senderMetadata.mediaUrl,
"airdate" : senderMetadata.airdate,
"isfullepisode" : senderMetadata.isfullepisode,
"crossId1" : senderMetadata.crossId1,
"nol_c1" : senderMetadata.nol_c1,
"nol_c2" : senderMetadata.nol_c2,
"segB" : senderMetadata.segB,
"segC" : senderMetadata.segC,
"adloadtype" : senderMetadata.adloadtype,
"hasAds" : senderMetadata.hasAds
};
window.nolSDKInstance.ggPM('loadmetadata', contentMetadata);
var ottMetadataObject ={
ottStatus: "1",
ottType: "casting",
ottDevice: "chromecast",
ottDeviceName: "Google Chromecast",
ottDeviceID: sessionId,
ottDeviceManufacturer: "Google",
ottDeviceModel: "ChromeCastModel",
ottDeviceVersion: "1.0.0",
kGCKMetadataNlsKeyOptout : senderMetadata.kGCKMetadataNlsKeyOptout,
kGCKMetadataNlsKeyDeviceID : sessionId
};
window.nolSDKInstance.ggPM('updateOTT', ottMetadataObject);};
5. Summary - Correct squence of API calls
Below is the sequence of API calls sequence from the beginning to the end of casting.
SENDER side :
1) If the video is playing only on the sender app, the standard Nielsen SDK API calls should be invoked.
2) Once a user presses the cast icon and if the video was playing already, call end().
3) Inform the AppSDK about the Chromecast's status (connected or disconnected) by calling updateOTT(config metadata).
4) Retrieve the optOutStatus and demographicId by calling getOptOutStatus() and getDemographicId().
5) Pass the optOutStatus and demographicId into the MediaMetaData object.
6) Start casting (the video should be stopped on the sender device).
RECIEVER side :
Playback has started at ChromeCast device (TV)
7) Retrieve the MediaMedaData sent by the sender device.
8) Instantiate the Browser SDK.
9) Pass metadata by calling loadMetaData().
10) Pass playheads every second by calling setPlayheadPosition().
11) Based on the user's interactions or the playlist state, call stop() (once paused) or end() (once the content or casting has ended).
SENDER side :
Casting has ended and playback continues on the sender device
12) Start a new session by calling play() and loadMetaData().
13) Continue sending API calls as usual.
6. Testing implementation
See https://developers.google.com/cast/docs/debugging
Note: make sure that all your test devices and PC are connected to the same network.
1. Start the iOS/iPad application and play video.
2. Connect the app to Chromecast by pressing the cast button.
3. Launch Chrome browser and access URL chrome://inspect.
4. Under your ChromeCast device, press “inspect”
5. In your browser console, check JS activity - including Nielsen SDK. Note: make sure that the BSDK has DEBUG mode on.
6. In your Network – make sure that outgoing data to Nielsen collection is present.