Anvato Chromecast Receiver Framework (ACRF)
Quick Start
Prerequisites
You need the the following for integration:
- The Anvato Chromecast Receiver Framework
- The Anvato Player SDK with Chromecast enabled
- Customer’s Chromecast Developer Account
- Register Chromecast receiver App-Id with Anvato Player Services to receive
- Partner App Access Key
- Partner App Security Key
- Your own Chromecast Hardware for testing
Deployment Locations for anvreceiver.min.js
- PRODUCTION: https://cast.anvato.net/anv-caf/prod/scripts/anvreceiver.min.js
- STAGE: https://cast.anvato.net/anv-caf/stage/scripts/anvreceiver.min.js
How to Build the Partner Receiver Application
As a partner Chromecast app developer, you build your application UI in HTML5/ CSS/ JavaScript as you normally would; this is called the Partner Application. However, please ensure that you follow the following guidelines:
- Include Chromecast Receiver and Media Player libraries
- Include Anvato Chromecast Receiver Framework script anvreceiver.min.js
- Provide your view url in the data-view-url attribute of anvreceiver.min.js script tag
- Provide your stylesheet for the Partner Application
- Provide your Partner Application script
Including anvreceiver.js script instantiates Anvato Chromecast Receiver Framework and utilizes the anvr namespace to expose API methods and callbacks to get partner application configuration.
The Structure of Partner Application Script
A typical partner application script consists of the following sections:
- Partner application configuration passed under
anvr.config
namespace -
ACRF callbacks under
anvr
namespaceanvr.onReady
: This callback is called when initialization is completed. When this is called, useful API methods under anvr namespace become available. And the partner application accesses the functionality provided by AnvatoChromecastReceiverManager and AnvatoChromeCastVideoPlayer instances.anvr.onCustomMessage
: This callback is called when a sender sends a message through the custom channel(s) that are passed into the configuration under anvr.config.anvr.onStateChanged
: This callback is called when there is a change in the ACRF current state. The application is expected to make changes to the receiver UI based on the requested state. The application can complete this transition by returning true in the callback method (synchronously) or defer this approval by calling anvr.onStateTransitionCompleted();anvr.onTimeUpdated
: The receiver application gets the current time index and the duration of the content/ad using this callback from the AnvatoChromeCastVideoPlayer. Advanced use cases such as ad stitched VOD require using the data sent via related event such as AD_BREAKS event
-
ACRF event listener callback under anvr namespace:
anvr.listener
RECEIVER_TYPE_SET
: This event notifies the partner application about the receiver type vod or liveMETADATA_LOADED
: This event is dispatched with the video metadataPROGRAM_CHANGED
: This event applies to the live events and provides live updates to the current program information using instream metadata and schedule services if available for the partner.SEEK_STARTED
: Notifies the partner application about the beginning of scrubbing initiated by a senderSEEK_ENDED
: Notifies the partner application about the completion of scrubbing initiated by a senderAD_BREAKS
: Provides ad breaks data which needs to utilized for enforcing ad policy and updating the UI namely the control bar.
- Partner helper methods
- Finally
anvr.init()
call that injects the provided partner view to ACRF, instantiates AnvatoChromecastReceiverManager and AnvatoChromeCastVideoPlayer with the provided configuration within ACRF and finally starts the main flow that is followed by events/callbacks and interacted using API methods.
Debugging the application
In order to use the APIs and the services the Receiver App is providing and debug the application, the bundle must be deployed to a remote location as is. Using this location the bundle must be registered as a development application. And corresponding App ID must be entered in a Chromecast enabled Anvato Player SDK.
A Chromecast device that is registered under the same account with the development application must be connected to a screen and its IP address must be detected.
Once the player app utilizing Anvato Player SDK is up and running, Chromecast streaming must be
enabled. The debug logs can be retrieved using Chromecast console on http://CHROMECAST_IP:9222
At this point you are ready for developing your Chromecast receiver using the Anvato Receiver App.
Publishing the application
Publishing the application involves turning off any debug modes, minifying the JavaScript and CSS files, deploying the customized bundle to a remote location, and finally registering the application.
Development Guide
Receiver Configuration
ACRF accepts the receiver configuration set to anvr.config. The configuration has the following fields:
Name | Type | Description | Required |
---|---|---|---|
videoPlaceholderId |
String | HTML5 video element ID | YES |
debug |
Boolean | Used for turning on debug logs | NO |
customNamespaces |
Array of Strings | Custom messaging namespace(s) | NO |
recommendations |
Object | Recommendations plugin configuration (applies to MCP VOD Content) | NO |
plugins |
Object | ACRF plugin configuration is passed in this field | NO |
Plugins
Adobe Heartbeat Analytics
The following configuration must be used for enabling Heartbeat Analytics service including custom metadata tracking.
Plugin Name | Parameters | Definition |
---|---|---|
heartbeat |
marketingCloudId |
Marketing Cloud ID provided by Adobe. |
customTrackingServer |
This parameter is used for specifying the servers processing the custom metadata (Typically Adobe Visitor and AppMeasurement servers). Multiple tracking servers seperated by comma can be entered. | |
trackingServer |
Tracking server for Heartbeat provided by Adobe. | |
jobId |
Job ID provided by Adobe. | |
account |
account ID provided by Adobe. | |
publisherId |
publisher ID provided by Adobe. | |
version |
Must be set to “1.5” for the latest heartbeat implementation. |
Processing Receiver States
Receiver states are notified using anvr.onStateChanged
callback. The SDK user is expected to
update the view accordingly. Additionally the SDK user is supposed to notify the ACRF about the end of
transition.
Sending this notification is possible in 2 ways:
- Synchronous: Returning true in the callback.
-
Asynchronous: Once the time consuming transitions are completed,
anvr.onStateTransitionCompleted()
must be called to notify ACRF about the completion of the transition.ACRF has the following states and transitions:
Listening the Receiver Events
Listening the ACRF events is possible by setting listener callback under anvr namespace. The event format is shown below for a sample event:
{
"name": "RECEIVER_TYPE_SET",
"time": "11:32:44:164",
"info": "Chromecast player type has been set based on the content",
"args": [
"vod"
],
"recipient": [
"16:client-8220",
"16:client-73691",
"16:client-65131",
"16:client-70690"
]
}
Name | Type | Description |
---|---|---|
name |
String | Event name |
time |
String | Event time |
info |
String | Event definition |
args |
Array | Event payload |
recipient |
String | The recipient sender IDs |
Detailed information for each event is given in the Reference Guide section.
Receiving the Error Events
The ACRF Errors are dispatched using the event channel mentioned above. Still conforming to the same format an error message has the following payload in the args field:
[errorCode, errorMessage, isCritical]
A sample error event:
["RCVR400", "The requested media source could not be downloaded", true]
Detailed information is given in the Reference Guide section.
Messaging Through Custom Channel
A custom channel can be used for receiving and sending messages to the application layer of a sender.
In order to use custom channel, its namespace(s) must be registered to customNamespaces
under anvr.config
.
ACRF will establish the requested messaging channels when anvr.init()
is called.
Once above steps are completed, the custom channels will be available for use whenever
anvr.onReady
callback is called for the first time.
The custom messages can be received using the anvr.onCustomMessage
callback with arguments namespace, sender and message to identify the origin and the message.
In order to send custom messages anvr.sendCustomMessage(namespace, sender,
message)
method must be used with the arguments specifying the name and destination.
Reference Guide
Callbacks
anvr.onReady()
Called when initialization is completed. When this is called, useful API methods become available under anvr namespace.
Parameters: | Name | Type | Description |
---|---|---|---|
name |
String | Parameter name |
Returns:
Type: String
anvr.onCustomMessage(namespace, sender, message)
This callback is called when a sender sends a message through the custom channel(s) that are passed into the configuration under anvr.config.
Parameters: | Name | Type | Description |
---|---|---|---|
namespace |
String | custom channel namespace | |
sender |
String | sender Id | |
message |
String | message content |
anvr.onStateChanged(state)
This callback is called when there is a change in the ACRF current state. The application is expected to make changes to the receiver UI based on the requested state.
Parameters: | Name | Type | Description |
---|---|---|---|
state |
String | Receiver state |
Returns:
Type: Boolean or undefined
anvr.onTimeUpdated(currentTime, totalTime, contentType, adBreakIndex, adIndex)
Provides the current time index and the duration of the content or ad based on contentType. Additionally, adBreakIndex and adIndex are provided if the contentType is “ad” and index information is available.
Advanced use cases such as playing ad stitched VOD require using the data sent via related events such as AD_BREAKS event.
Parameters: | Name | Type | Description |
---|---|---|---|
currentTime |
Number | Current time index in seconds | |
totalTime |
Number | Total time in seconds | |
contentType |
String | “ad” or “content” | |
adBreakIndex |
Number | Ad break index | |
adIndex |
Number | Ad index inside an ad break |
Returns:
Type: Boolean or undefined
anvr.onSeekRequested(timeIndex)
Called when the receiver receives a seek request. This callback is used if there is a need to change the seek index or perform some tasks when there is a seek request.
Parameters: | Name | Type | Description |
---|---|---|---|
timeIndex |
Number | Seek index in seconds |
Returns:
Type: Number
API Methods
anvr.init()
Injects the provided partner view to ACRF, instantiates AnvatoChromecastReceiverManager and AnvatoChromeCastVideoPlayer with the provided configuration within ACRF and finally starts the main flow that is followed by events/callbacks and interacted using API methods. Must be called when the partner application configuration and callbacks are provided.
anvr.sendCustomMessage(namespace, sender, message)
Sends a custom message to the specified sender in the provided namespace.
Parameters: | Name | Type | Description |
---|---|---|---|
namespace |
String | custom channel namespace | |
sender |
String | sender Id | |
message |
String | message content |
anvr.onStateTransitionCompleted()
Called when the state transition is asynchronous and it is completed.
RPCs
ACRF allows calling specified API methods from a sender using remote procedure call via the namespace urn:x-cast:com.anvato.chromecast
.
RPC message must have the format shown on the side:
{
type: "rpc",
content: {
name: fnName,
args: args
}
}
toggleCaption
Used for toggling on/off closed captions. Once this RPC is called, ACRF will dispatch CAPTION_STATUS
with the same arguments as payload. And this event will be repeated for subsequent senders once they join the session. It is recommended that only the initial sender loading the content must call this RPC to reflect the user choice, and others shall adapt their sender UI accordingly. Upon a user interaction based caption setting any sender can call this RPC.
Method Name | Arguments | Definition |
---|---|---|
toggleCaption | selectedCaption | 2-letter language code for enabling caption among multiple captions or true when only one caption is available, or false to turn it off |
availableCaptions | Array of available captions' 2-letter language code |
{
type: "rpc",
content: {
name: "toggleCaption",
args: ["en", ["en", "es"]]
}
}
Events
Receiver dispatches the events to the related sender SDK and receiver application in the format shown on the side:
{
"name": EVENT_NAME,
"time": TIME_STAMP,
"info": EVENT_INFO,
"args": [ ARG0, ARG1, ... ],
"recipient": [SENDER0, SENDER1, ...]
}
Event information is provided below.
Event Name | Event Definition | Arguments |
---|---|---|
RECEIVER_TYPE_SET | Chromecast player type has been set based on the content | receiver type: “vod” or “live” |
CHROMECAST_RECEIVER_ERROR | Chromecast receiver has thrown an error | error code |
error info | ||
Is Error Critical | ||
VERIFICATION_STATUS | Verification status has changed | isVerified |
token (if verified. o/w null) | ||
METADATA_LOADED | Video metadata is available | event ID / video ID |
upid (another identifier used as a key for metadata lookup) / video ID | ||
metadata | ||
video load configuration | ||
PROGRAM_CHANGED | Live program has changed | event ID |
upid (another identifier used as a key for metadata lookup) | ||
metadata detail (rovi metadata if available) | ||
SEEK_STARTED | A sender initiated a seek | none |
SEEK_ENDED | Sender initiated seek has been completed | none |
AD_BREAKS | Ad breaks have been detected in the stream | array of ad break info: {start: TS_SECONDS, end: TS_SECONDS} |
RECOMMENDATIONS_AVAILABLE | Detected recommended videos based on the current video | recommendations object from MCP/TKX |
RECOMMENDATIONS_VIEW_REQUESTED | Recommendations view requested from connected players | none |
RECOMMENDATION_SELECTED | A video from recommendations has been selected | recommendation item object |
CAPTION_STATUS | Caption status has been updated | selected caption |
available captions | ||
CHROMECAST_QUEUE_UPDATED | Chromecast queue has been updated | array of queue item objects: {queueIndex: QUEUE_INDEX, def_title: TITLE, def_description: DESCRIPTION, src_image_url: THUMBNAIL_IMAGE} |
NEXT_VIDEO | Next video metadata is available | metadata |
preload duration / countdown duration | ||
CUSTOM_LOAD_CONFIG_DETECTED | Custom config accompanying the main (encrypted load config detected) | custom load config |
PARTNER_DATA_UPDATED | The merged custom load config and partner data set via setPartnerData has been updated | data set by receiver app |
PLAYING_START | The playback has started | content ID |
VIDEO_STARTED | The video started | content ID |
VIDEO_COMPLETED | The video completed | content ID |
USER_PAUSE | The video has been paused by a sender | none |
USER_RESUME | The video has been resumed by a sender | none |
AD_STARTED | The ad started | content ID |
AD_COMPLETED | The ad completed | content ID |
CAPTION_STYLE_SET | Caption style has been set by a sender (either while loading or after) | caption style object |
Errors
Error payload is passed with the args property as shown below. isCritical flag is used for providing the SDK user with the information about whether the playback will stop/not start at all or the error is recoverable.
{
name: "CHROMECAST_RECEIVER_ERROR",
time: {error time},
info: "Chromecast receiver has thrown an error",
args: [errorCode, errorDefinition, isCritical],
recipient: [SENDER0, SENDER1, ...]
}
Error Code | Error Definition | isCritical |
---|---|---|
RCVR001 | Failed to decrypt the sender verification payload | true |
RCVR002 | Failed to parse the sender verification payload | true |
RCVR010 | Failed to decrypt the sender payload | true |
RCVR011 | Failed to parse the sender payload | true |
RCVR021 | Custom cast channel associated with the provided senderId does not exist while attempting to call sendCustomMessage | false |
RCVR030 | The invoked remote method could not be located in the registered RPC methods | false |
RCVR300 | Error related to media playback | true |
RCVR400 | The requested media source could not be downloaded | true |
RCVR401 | Error loading or parsing the manifest | true |
RCVR403 | Error fetching the keys or decrypting the content | true |
RCVR405 | Generic video service error | true |
RCVR900 | Schedule service returned an expired event | false |
Samples
Sample Receiver Application
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="partner.css"/>
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script data-view-url="partner.html" src="scripts/anvreceiver.min.js"></script>
<script type="text/javascript" src="partner.js"></script>
</head>
<body>
</body>
</html>
Sample Partner Receiver Application script
if (typeof anvr == 'undefined') {
anvr = {};
}
anvr.config = {
debug: false,
videoPlaceholderId: "video-placeholder",
customNamespaces: ["urn:x-cast:com.br.chromecast"]
};
//---------2. CALLBACK METHODS ------------
anvr.onReady = function() {
// API methods from instantiated instances are exposed here
};
anvr.onCustomMessage = function(namespace, sender, message) {
anvr.sendCustomMessage(namespace, sender, message);
};
anvr.onStateChanged = function(state) {
setTimeout(asyncTransition.bind(null, state), 100);// simulating async transition,
// sync transition can be performed here by returning true
};
anvr.onTimeUpdated = function(currentTime, totalTime, contentType, adBreakIndex, adIndex) {
//...
};
//--------- 3. ACRF EVENT LISTENER ------------
anvr.listener = function(event) {
// ..
switch(event.name) {
case "RECEIVER_TYPE_SET":
//...
break;
case "METADATA_LOADED": // for initial metadata load (for vod and live)
//..
break;
case "PROGRAM_CHANGED": // for live program change events
//..
break;
case "SEEK_STARTED":
//..
break;
case "SEEK_ENDED":
//..
break;
case "AD_BREAKS":
//..
break;
}
};
//---------- 4. HELPER METHODS ------------
function asyncTransition(state) {
//..
anvr.onStateTransitionCompleted();
}
//---------- 5. ACRF INIT CALL ------------
anvr.init();