EMP Receiver documentation
This document provides an overview of building a custom Google Cast receiver application.
https://developers.google.com/cast/docs/custom_receiver
Your custom receiver application have to be deployed to a web server with domain name and SSL support.
The url to the receiver application have to be registed at Google, with a company account owning the streaming services.
https://developers.google.com/cast/docs/registration
The receiver is compliant with the default chromecast receiver API unless otherwise stated. For information on how to build a sender and other functionality not described here. See https://developers.google.com/cast/docs/sender_apps
Sender tutorials
Development
A demo receiver app that uses this package is available here
Communicating with the Receiver - General Information
Loading Media
To load media on the receiver, we opted out of casting simple content-urls. This to ensure we can retrieve proper playtokens and make it compatible with any sender, regardless of content playback. In order to cast any media, the media has to be available in the DASH/CENC format.
Loading media is done by the following methods
GCKMediaControlChannel:loadMedia (iOS)
RemoteMediaPlayer.load (android)
For both platforms, the MediaInfo payload should contain the following properties in the custom data
{
ericssonexposure: {
customer: 'customer',
businessUnit: 'businessUnit',
sessionToken: 'sessionToken',
exposureApiURL: 'apiUrl'
},
assetId: 'assetIdOrChannelId',
programId: 'programId'
}
The receiver will request the proper media from the API itself. If none is found a castError is triggered containing more information.
Custom Messaging
When connected to the receiver messages can be send over the namespace: urn:x-cast:com.ericsson.cast.receiver. All messages to and from the receiver will be send over this namespace.
Embedded tracks
Embedded tracks are broadcasted to all connected senders when a sender send refreshcontrols message, or when subtitles/audio tracks change or period change.
If the stream has multi periods the audio and text tracks can change even id's
{
type: 'tracksupdated',
data: {
tracksInfo: {
activeTrackIds: [0, 1]
tracks: [
label: 'label',
type: '(text|audio)',
trackId: 0,
language: 'sv'
]
}
}
}
- Use the 'activeTrackIds' property to display on the sender which track is currently active on the receiver.
- If only one audiotrack is available, no audiotracks are broadcasted. Instead the default track is used.
- If no subtitle is currently active and only one audiotrack is available, the activeTrackIds array can be null
- The information send in this event is always leading, in the case multiple senders modify tracks at the same time. always use the last received message to display the correct information to the user
Changing subtitles
To update which subtitle track is being displayed on the receiver, the following messages can be send
{
type: 'showtexttrack',
data: {
language: en
}
}
{
type: 'hidetexttrack'
}
After changing subtitles all connected senders (including the sender that made the request) receive a 'tracksupdated' message containing updated information about the embedded tracks.
Changing audiotracks
To update which audio track is being used on the receiver, the following messages can be send
{
type: 'enableaudiotrack',
data: {
language: en
}
}
After changing audiotracks all connected senders (including the sender that made the request) receive a 'tracksupdated' message containing updated information about the embedded tracks.
Refresh Controls
After joining a session, it might be necessary to request the constrols' status (volume level, timeshift enabled, tracks). By sending this message to the receiver, it will then answer with updated controls.
{
type: 'refreshcontrols',
data: {
}
}
LoadRequest CustomData
audioLanguage: default audio language
textLanguage: default subtitle
startTime: optional cast initial time, will be override with loadRequest.currentTime
timeShiftDisabled: default timeshiftDisabled property
maxBitrate: cast max bitrate
autoplay: default autoplay
var loadRequest = new window.chrome.cast.media.LoadRequest(mediaInfo);
loadRequest.customData = {
audioLanguage: "en",
textLanguage: "en",
startTime: 0,
timeShiftDisabled: false,
maxBitrate: 10000,
autoplay: true
};
Start Time
To start casting a media from a position other than 0, it is possible to set the currentTime attribute in the LoadRequest object (found in the Chromecast API).
var loadRequest = new window.chrome.cast.media.LoadRequest(mediaInfo);
loadRequest.currentTime = startTime;
Title, Subtitle and Artwork
It is possible to send movie metadata along with the request: movie title, subtitle and image(s).
var assetMetadata = new window.chrome.cast.media.MovieMediaMetadata();
assetMetadata.title = '<MovieTitle>';
assetMetadata.subtitle = '<MovieSubtitle>';
assetMetadata.images = [new window.chrome.cast.Image('<ImageUrl>')];
mediaInfo.metadata = assetMetadata;
Other relevant messages sent by the EMP Receiver
timeShiftEnabled - Signals whether timeshift is enabled in the controls or not.
{
type: 'timeShiftEnabled',
data: (boolean)
}
volumechange - signals a change in the volume status.
{
type: 'volumechange',
data: {
volume: (number),
muted: (boolean)
}
}
durationchange - signals a change in the duration of the media being played.
{
type: 'durationchange',
data: (number)
}
programchanged - signals a change in the program of a given channel.
{
type: 'programchanged',
data: {
programId: (string)
}
}
Release notes
1.72.0
New features and Enhancements
EMP-10652 Player&Chromecast: Update shaka to v2.2.6, NPM 2.2.6-2
https://github.com/google/shaka-player/releases
Bug fixes
EMP-10654 Shaka 2.2.6 Error if starttime is bigger then duration
EMP-10710 CC doesn't set a bookmark after 10sec for catch-up content - the aborted event sends offset 0
1.67.0
New features and Enhancements
Updated dependency to empPlayer: v1.67.0
1.66.0
Bug fixes
EMP-10274 Chromecast: Fixed error after scrubbing.
New features and Enhancements
EMP-8686 Chromecast: Update Shaka player from v2.0.2 to v2.2.0 https://github.com/google/shaka-player/releases
EMP-9886 Chromecast: HTML5 player gets unresponsive when stuck in a buffering state (when a segment is not available for instance).
For VOD/Catchup, EMP-Player prefetch the segement at the seek point, if the segment is not there, seek is cancel.
SEGMENT_MISSING event is raised, that can be used to inform the user that the streams is not ready for seeking yet.
1.65.0
Bug fixes
EMP-10153 Chromecast: Console error: Unable to call startTimeLive, this feature is only available for live streams.
1.64.0
Bug fixes
EMP-9952 not showing splash screen while switching between assets
1.63.1
Bug fixes
EMP-9858 fixed error with code 11: "Failed to execute 'addSourceBuffer' on 'MediaSource'"
1.63.0
Bug fixes
EMP-9754 Entering pause state only if the player is playing something. If pause event is received and the player is not playing anything, then the 'pause' state change does not happen.
Receiver API
Classes
- EMPReceiverApp
Deprecated make changes in the CC demo git repo
- EmpReceiverEvents
- empReceiver
Events
- "METADATA_UPDATED"
Fired when asset metadata has been updated
- "STATE_CHANGED"
Fired when receiver state has changed
- "RESOLUTION_CHANGED"
Fired when receiver 'resolution has changed - resolution parameter (if null, app should hide UI display element)
EMPReceiverApp
Deprecated make changes in the CC demo git repo
Kind: global class
EmpReceiverEvents
Kind: global class
new EmpReceiverEvents()
EmpReceiverEvents - Holds all available receiver events
empReceiver
Kind: global class
new empReceiver(element, [options], [ready])
empReceiver - Object that interacts with chromecast
Param | Type | Description |
---|
element | String | ID or DOM element of the receiver html element |
[options] | Object | receiver options such as: controls (children), debug, messageUrn |
[ready] | Callback | callback to be called when the receiver is reader |
empReceiver.state ⇒ empReceiver.ReceiverStates
Kind: instance property of empReceiver
Returns: empReceiver.ReceiverStates
- current receiver state.
empReceiver.isChromecast ⇒ bool
Kind: instance property of empReceiver
Returns: bool
- if running on Chromecast device.
empReceiver.version ⇒ Number
Player version
Kind: instance property of empReceiver
Returns: Number
- The player version
empReceiver.player ⇒ EmpPlayer
Returns the underlying EmpPlayer object
EmpPlayer API: https://www.npmjs.com/package/empplayer
Kind: instance property of empReceiver
Export:
empReceiver.mockMediaManagerEvent_()
debugging the receiver UI in Chrome.
Kind: instance method of empReceiver
empReceiver.onMessage()
cast.receiver.CastMessageBus.Event
public for debugging the receiver UI in Chrome.
Kind: instance method of empReceiver
Export:
empReceiver.hideMediaResolution()
emits RESOLUTION_CHANGED event
Kind: instance method of empReceiver
Export:
empReceiver.displayMediaResolution()
gets current displayed resolution and emits RESOLUTION_CHANGED event with resolution as argument
Kind: instance method of empReceiver
Export:
empReceiver.loadDebug_()
debugging the receiver UI in Chrome.
Kind: instance method of empReceiver
empReceiver.sendTracks()
broadcasts tracks to the senders
Kind: instance method of empReceiver
Export:
empReceiver.refreshControls()
updates the controls on in the senders (volume level, timeshift enabled, autplay, is live, duration)
Kind: instance method of empReceiver
Export:
empReceiver.getMediaInformation() ⇒ MediaInformation
Kind: instance method of empReceiver
Returns: MediaInformation
- current asset metadata.
empReceiver.getAnalyticsDeviceInfo_()
geta analytics deviceInfo, which includes emp-chromecast-receiver version
Kind: instance method of empReceiver
Export:
empReceiver.shutdownWhenLastSenderDisconnect()
set shutdown When Last Sender Disconnect
Kind: instance method of empReceiver
empReceiver.createPlayer()
Handle initialization of a player when a new video is cast
Kind: instance method of empReceiver
empReceiver.sendMessage_(json, id)
sends message to the senders
Kind: instance method of empReceiver
Export:
Param | Type | Description |
---|
json | message | object with message details |
id | opt_senderId | optional set if you want to send message to just one specific sender |
empReceiver.sendStatus_(id, id)
sends message to the senders
Kind: instance method of empReceiver
Export:
Param | Type | Description |
---|
id | opt_senderId | optional sender id |
id | opt_requestId | optional request id |
"METADATA_UPDATED"
Fired when asset metadata has been updated
Kind: event emitted
"STATE_CHANGED"
Fired when receiver state has changed
Kind: event emitted
"RESOLUTION_CHANGED"
Fired when receiver 'resolution has changed - resolution parameter (if null, app should hide UI display element)
Kind: event emitted