Chromecast
Chromecast on Quickplay platform qualifies as a device on its own and can perform device registration, content authorization and playback similar to any other conventional devices. The client sender facilitates sharing required information for device registration and content authorization to the receiver and the receiver processes the same for playback.
Cast Media
Casting a media using Quickplay platform requires the following to be performed in a sequence:
- Initialize Cast Manager
- Send User Device Information message to Receiver
- Load Media onto Receiver
Please note, the above sequence of steps needs to be performed invariably for a new cast session inclusive of both Connect & Play and Play & Connect scenarios. It is advised that the initialization of cast manager and sharing user device information be performed during application launch and load media be performed on demand.
Cast Manager
CastManager
uses Google Cast Application Framework's (CAF) SessionManager
instance to manage CastSession
and coordinate all the Cast interactions.
CastManager
manages, internally, a custom media channel to facilitate communication between the Sender and the Receiver Applications.
CastManager
also provides access to CastPlayer
, for playing the contenton the Web Receiver Application, and enforces policies for accessing Quickplay Platform resources.
Initializing Cast Manager
Initializing the FLCastManager
is the first and foremost step while integrating FLChromecast
library and it is advised to perform initialization right at application launch. To initialize cast manager one must provide CastOptions
, the sender client device PlatformClient
information with PlatformAuthorizer
and custom channel namespace which would be used for sender receiver communications. The initialization callbacks could be received via FLCastManagerEventListners
. The most important option is the Cast Receiver ID, which is used to filter Cast Device discovery results and to launch the Receiver Application when a CastSession
is started.
// Cast Options
const options = {
receiverApplicationId: platformConfiguration.CAST_RECEIVER_ID,
};
// Add listeners to receive callbacks from CastManager
initialize(
castOptions: any,
clientDevice: PlatformClient,
platformAuthorizer: PlatformAuthorizer,
channelNamespace: string,
) {
try {
castOptions.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;
cast.framework.CastContext.getInstance().setOptions(castOptions);
platformAuth = platformAuthorizer;
platformClientDevice = clientDevice;
channel = channelNamespace;
castPlayerListeners();
} catch (error) {
logger.debug('cast session is failed to initialised', error as Error);
}
},
Load Media
The Cast Player with Cast Manager is analogous to the remote media player of Receiver. The same is available upon successful initialization of Cast Manager. To load media one should create a PlatformAsset
which describes the media that needs to be authorized with Quickplay platform and played upon successful authorization. One can load CastMediaMetadata
and CastMediaTrack
optionally while loading media.
// configure metadata
const mediaInfo = new chrome.cast.media.MediaInfo();
// Create PlatformAsset
const asset: PlatformAsset = {
mediaID: <Content-Id>,
drmScheme: flPlayerInterface.DrmScheme.WIDEVINE,
mediaType: flPlayerInterface.MediaType.DASH,
consumptionType: flContentAuthorization.ConsumptionType.VOD,
catalogType: 'movie',
playbackMode: flContentAuthorization.PlaybackMode.LIVE,
startTime: '',
endTime: '',
};
loadMedia(asset: PlatformAsset, castOptions?: CastPlaybackOptions);
CastPlaybackOptions
Name | Required | Type | Description |
---|---|---|---|
headers | false | HttpHeaders | Specifies the additional headers for authorized content playback. |
metadata | false | any | The metadata about the content. |
mediaTracks | false | any | Media tracks which has to set on load |
initialPlaybackTime | false | number | The parameter initialPlaybackTime specifies the time in seconds that the player needs to seek to before initiating playback. For initialPlaybackTime to be valid, it should be either set as null or undefined for livePlayback scenarios and non-negative definite values for restart or VOD playbacks. |
The above snipped demonstrates creating a DASH/Widevine Movie content for authorization and playback. The supported combinations might differ based on individual projects. The Receiver upon receiving this information attempts to authorize the asset with Quickplay platform and plays the content.
Please refer FLContentAuthorizer
documentation to read more on creating PlatformAsset
Cast Player and Events
The CastPlayer extends Player
interface and provides the benefit of having same APIs as conventional Player
from FLPlayer
library. Some of the player APIs are no-op with CastPlayer, due to constraints with underlying player, Remote Media Client in this case.
The following APIs with Player interface are no-op as of today:
- load()
- seekableRange()
- all track manipulation APIs accepting MediaType
- set(preferences:)
// access remote player
const castManager = flChromeSender.createCastManagerImpl();
castManager.castPlayer;
To listen to player events, implement the player delegate and listen for callbacks. Media load failures will also be notified via player delegate.
Cast Player UI
FLChomecast library does not wrap GoogleCast SDK to provide all functionalities that GoogleCast SDK offers. UI components from GoogleCast SDK can be used to render cast buttons. The integrators have complete control over player UI rendering and can enjoy the same luxury of integrating GoogleCast SDK directly. Most of the integrators prefer using their own UI for player which can double up as remote Cast Player and local Player. The integration is a breeze due to the fact that both players, FLPlayer(local playback) and CastPlayer(Remote playback) has same public interface.
Analytics Data
Custom metadata can be sent to newrelic via loadMedia API through 'flAnalyticsData'. Similarly custom metadata can be sent to video analytics via loadMedia API through 'videoAnalyticsData'.
E2E Integration
Here is the snippet comprising all the above sequence of steps.
<head>
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
</head>
<body>
<google-cast-launcher id="castbutton"></google-cast-launcher>
</body>
//********** Initialize cast Manager at app launch *********
// GCK Options
const castManager = flChromeSender.createCastManagerImpl();
window['__onGCastApiAvailable'] = function(isAvailable) {
if (isAvailable) {
const options = {
receiverApplicationId: '<CAST_RECEIVER_ID>',
};
//intialize cast manager
castManager.initialize( castOptions: any, clientDevice: PlatformClient, platformAuthorizer: PlatformAuthorizer, channelNamespace: string )
}
};
//********** Load Media *********
// configure metadata
const mediaInfo = new chrome.cast.media.MediaInfo();
mediaInfo.metadata = metadata;
// Create PlatformAsset
const castAssetDetail = {
mediaID: '<Content-ID>',
drmScheme: flPlayerInterface.DrmScheme.WIDEVINE,
mediaType: flPlayerInterface.MediaType.DASH,
consumptionType: flContentAuthorization.ConsumptionType.VOD,
catalogType: 'movie',
playbackMode: flContentAuthorization.PlaybackMode.LIVE,
startTime: '',
endTime: '',
};
window.player = castManager.castPlayer;
window.player.loadMedia(castAssetDetail:PlatformAsset, {
headers: ClientIPModule.getHeaders(),
// data analytics reproting
flAnalyticsData?: { appBuild: 'test_id',..},
// video analytics reporitng
videoAnalyticsData?: {
viewerId: 'userID / mobileNumber / emailId',
assetName: 'Name of the content',
tags?: customTags, // Key value pair that provide additional information about the content and it is optional.
}
});
//********** Subscribe CastManager *********
function subscribeCastManager() {
// check for local player if any and pause the local playback.
// call castplayer.loadMedia() to load the asset in receiver.
castManager.subscribe('castSessionConnected', function() {
if (window.player !== undefined) {
window.localPlayer = window.player;
localPlayer.pause();
window.player = castManager.castPlayer;
window.player.loadMedia(castAssetDetail);
playbackEvents.subscribeAll(window.player);
}
});
// check for local player if any and resume the local playback.
castManager.subscribe('castSessionEnded', function() {
if (window.localPlayer !== undefined) {
window.player = localPlayer;
player.play();
playbackEvents.subscribeAll(window.player);
}
})
}
Model Deprecation
Google has discontinued support for some of its older generation Chromecast devices, potentially leaving room for security vulnerabilities and a suboptimal user experience.
In order to phase out these older generation Chromecast devices, the following sequential steps need to be undertaken:
- Setting up the device model
- Listening to CastManager
Setting up the device model
The initial and most important step involves setting up the deprecated device model in the cast receiver app configuration.
Listening to CastManager
The application plans to utilize the CastManager callback to properly inform users by prompting error and do necessary actions to ensure compatibility with the sender application.
castManager.subscribe('error', function(error) {
// prompt error to users and do necessary actions accordingly.
})