This document provides an overview of the queueing and DRM integration support.
DRM enhancements
The ExoPlayer Cast Demo
has been updated to utilize a structured way to pass DRM configuration using
ExoPlayer’s MediaInfo
to a receiver application. The Cast sample
also uses a demo receiver that includes the same code in this overview, allowing
you to test out DRM support. However, if you would like to Cast DRM protected
content, you should build and host your own
Web Receiver.
Before beginning, it would be helpful to familiarize yourself with the documentation on DRM support in Google Cast and ExoPlayer. This overview will show you how to wire-up the ExoPlayer DRM configuration to a Web Receiver. For information on how to utilize DRM in ExoPlayer, see the official ExoPlayer website.
Providing the DRM configuration
The ExoPlayer demo app contains sample code that shows how to provide DRM configuration as part of a MediaItem. The four options you can configure are:
- Headers - a dictionary of headers that are applied to the HTTPS request to retrieve the DRM license.
- License URL - the URL used to acquire the license.
- Protection System - the DRM protection scheme used to protect the content, for example, Widevine.
The DRM configuration you provide to ExoPlayer is sent to your receiver
application as a property in customData
on the MediaInformation
object as part of a load request. By default, this property is called
exoPlayerConfig
, which matches the following definition.
/**
* Extended configuration settings for ExoPlayer.
*/
ExoPlayerConfig class {
constructor() {
/**
* Dictionary of headers to apply to the license request.
* @type {!Object|undefined}
*/
this.headers;
/**
* The URL for your DRM server.
* @type {string|undefined}
*/
this.licenseUrl;
/**
* Preferred protection system to use for decrypting content.
* @type {!cast.framework.ContentProtection|undefined}
*/
this.protectionSystem;
/**
* Indicates whether CORS Access-Control requests should be made using
* credentials such as cookies or authorization headers.
*
* If withCredentials is set to true then Access-Control-Allow-Origin cannot
* be set to '*'.
* @type {boolean|undefined}
*/
this.withCredentials;
}
}
Initial setup
Depending on the DRM solution you use, you might need to configure a licenseRequestHandler
and a mediaPlaybackInfoHandler
. The licenseRequestHandler
allows you to customize
how CAF requests a license from your license key server. The
mediaPlaybackInfoHandler
lets you modify the
PlaybackConfig
on a per media item basis if, for example, each piece of content has to use a
different license server URL.
To capture a copy of the ExoPlayerConfig
from each load request object, create
a load request interceptor in your Web Receiver SDK application.
The first step is to register your handlers before starting your Cast application.
const context = cast.framework.CastReceiverContext.getInstance();
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.licenseRequestHandler =
licenseRequestHandler;
context.getPlayerManager().setMediaPlaybackInfoHandler(
mediaPlaybackInfoHandler);
context.getPlayerManager().setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
loadInterceptor);
// starts the Cast application
context.start({playbackConfig: playbackConfig});
Load request interceptor
The load request interceptor is a callback that allows you to view and modify a Cast load request before CAF attempts to load a media item. Importantly, it is called before the license request hander and the media playback info handler.
The load request interceptor is passed a LoadRequestData
object that contains the Exo Player Config that was sent by your app. You can
save this object as a global variable for use in your license request handler
and media playback info handler.
loadInterceptor(loadRequestData) {
// not every load request will have a customData object
if (loadRequestData.media && loadRequestData.media.customData &&
loadRequestData.media.customData['exoPlayerConfig']) {
// exoPlayerConfig is a global variable here
exoPlayerConfig =
loadRequestData.media.customData['exoPlayerConfig'];
}
// you must return the loadRequestData object
return loadRequestData;
}
License request handler
The license request handler allows you to customize the HTTPS request Web
Receiver makes to your license server. The handler is passed a NetworkRequestInfo
object, which you can then use to add HTTP headers, include cookies, or even
modify the URL. The handler should return this object.
If, for example, you needed to add custom headers to your license request, you could create a license request handler similar to this:
licenseRequestHandler(networkRequestInfo) {
if (!exoPlayerConfig) {
return networkRequestInfo;
}
networkRequestInfo.headers =
exoPlayerConfig.headers ? exoPlayerConfig.headers : undefined;
return networkRequestInfo;
}
Media playback info handler
The media playback info handler allows you to make changes to your playback
configuration on a per media item basis. The handler is passed a LoadRequestData
and a PlaybackConfig
,
you should return a playback config. The media playback info handler will be
called before each item you Cast is loaded. If you had per-content license urls,
can to change them and the protection system before the load.
mediaPlaybackInfoHandler(loadRequest, playbackConfig) {
if (!exoPlayerConfig) {
return;
}
playbackConfig.licenseUrl = exoPlayerConfig.licenseUrl ?
exoPlayerConfig.licenseUrl :
undefined;
playbackConfig.protectionSystem = exoPlayerConfig.protectionSystem ?
exoPlayerConfig.protectionSystem :
undefined;
return playbackConfig;
}
Further resources
Each DRM implementation is custom and this code is provided as a demonstration only. You should consult your DRM provider to ensure you have correctly implemented DRM in your ExoPlayer and Cast applications.
ExoPlayer’s Website features up-to-date documentation and announcements. Issues with ExoPlayer and its Cast integration can be reported at ExoPlayer’s GitHub repository.