Skip to main content

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

NameRequiredTypeDescription
headersfalseHttpHeadersSpecifies the additional headers for authorized content playback.
metadatafalseanyThe metadata about the content.
mediaTracksfalseanyMedia tracks which has to set on load
initialPlaybackTimefalsenumberThe 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.

note

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.
})