ExoPlayer 集成

本文档简要介绍了队列和 DRM 集成支持。

DRM 增强功能

更新了 ExoPlayer Cast 演示,以利用结构化方式使用 ExoPlayer 的 MediaInfo 将 DRM 配置传递给接收器应用。Cast 示例还使用一个演示接收器,其中包含本概览中的相同代码,以便您测试 DRM 支持。但是,如果您要投射受 DRM 保护的内容,则应构建并托管您自己的网络接收器

在开始之前,您最好熟悉一下 Google CastExoPlayer 中有关 DRM 支持的文档。本概览将介绍如何将 ExoPlayer DRM 配置连接到网络接收器。如需了解如何在 ExoPlayer 中使用 DRM,请参阅官方 ExoPlayer 网站

提供 DRM 配置

ExoPlayer 演示版应用包含的示例代码,演示了如何在 MediaItem 中提供 DRM 配置。您可以配置以下四个选项:

  • 标头 - 标头字典,该标头应用于 HTTPS 请求以检索 DRM 许可。
  • 许可网址 - 用于获取许可的网址。
  • 保护系统 - 用于保护内容的 DRM 保护方案,例如 Widevine。

您提供给 ExoPlayer 的 DRM 配置会作为加载请求的一部分,作为 MediaInformation 对象的 customData 中的属性发送到接收器应用。默认情况下,此属性称为 exoPlayerConfig,它与以下定义匹配。

/**
 * 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;
  }
}

初始设置

根据您使用的 DRM 解决方案,您可能需要配置 licenseRequestHandlermediaPlaybackInfoHandler。借助 licenseRequestHandler,您可以自定义 CAF 如何从您的许可密钥服务器请求许可。使用 mediaPlaybackInfoHandler 可以按媒体项修改 PlaybackConfig(例如,每一项内容都必须使用不同的许可服务器网址)。

如需从每个加载请求对象捕获 ExoPlayerConfig 的副本,请在您的 Web 接收器 SDK 应用中创建一个加载请求拦截器。

第一步是在启动 Cast 应用之前注册处理程序。

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

加载请求拦截器

加载请求拦截器是一个回调,可让您在 CAF 尝试加载媒体项之前查看和修改投射加载请求。重要的是,它会在许可请求处理程序和媒体播放信息处理程序之前调用。

系统会向加载请求拦截器传递一个 LoadRequestData 对象,该对象包含应用发送的 Exo 播放器配置。您可以将此对象保存为全局变量,以便在许可请求处理程序和媒体播放信息处理程序中使用。

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;
}

许可请求处理程序

借助许可请求处理程序,您可以自定义 Web 接收器向许可服务器发出的 HTTPS 请求。系统会向处理程序传递一个 NetworkRequestInfo 对象,然后您可以使用该对象添加 HTTP 标头、包含 Cookie,甚至修改网址。处理程序应返回此对象。

例如,如果您需要向许可请求添加自定义标头,可以创建类似于以下内容的许可请求处理程序:

licenseRequestHandler(networkRequestInfo) {
    if (!exoPlayerConfig) {
        return networkRequestInfo;
    }

    networkRequestInfo.headers =
            exoPlayerConfig.headers ? exoPlayerConfig.headers : undefined;

    return networkRequestInfo;
}

媒体播放信息处理程序

通过媒体播放信息处理程序,您可以按媒体项更改播放配置。系统会向该处理程序传递 LoadRequestDataPlaybackConfig,您应返回播放配置。系统会在您 Cast 的每项内容加载之前调用媒体播放信息处理程序。如果您有基于内容的许可网址,可以在加载之前更改这些网址和保护系统。

mediaPlaybackInfoHandler(loadRequest, playbackConfig) {
    if (!exoPlayerConfig) {
        return;
    }

    playbackConfig.licenseUrl = exoPlayerConfig.licenseUrl ?
            exoPlayerConfig.licenseUrl :
            undefined;
    playbackConfig.protectionSystem = exoPlayerConfig.protectionSystem ?
            exoPlayerConfig.protectionSystem :
            undefined;

    return playbackConfig;
}

其他资源

每个 DRM 实现都是自定义的,此代码仅用作演示。您应咨询您的 DRM 提供商,确保您已在 ExoPlayer 和 Cast 应用中正确实现 DRM。

ExoPlayer 的网站提供了最新的文档和公告。有关 ExoPlayer 及其 Cast 集成的问题可在 ExoPlayer 的 GitHub 代码库中报告。