数字版权管理

ExoPlayer 使用 Android 的 MediaDrm API 支持受 DRM 保护的播放。下表描述了不同受支持的 DRM 方案所需的最低 Android 版本以及支持的流式传输格式。

DRM 方案 Android 版本号 Android API 级别 支持的格式
Widevine “cenc” 4.4 19 DASH、HLS(仅限 FMP4)
Widevine “cbcs” 7.1 25 DASH、HLS(仅限 FMP4)
ClearKey “cenc” 5.0 21 DASH
PlayReady SL2000 “cenc” Android TV Android TV DASH、SmoothStreaming、HLS(仅限 FMP4)

为了使用 ExoPlayer 播放受 DRM 保护的内容,必须在构建媒体项时指定 DRM 系统的 UUID,并且还可以提供其他属性。然后,播放器将使用这些属性构建 DrmSessionManager 的默认实现,称为 DefaultDrmSessionManager,它适用于大多数用例。对于某些用例,可能需要其他 DRM 属性,如下节所述。

密钥轮换

要播放具有轮换密钥的流,请在构建媒体项时将 true 传递给 MediaItem.DrmConfiguration.Builder.setMultiSession

多密钥内容

多密钥内容包含多个流,其中某些流使用与其他流不同的密钥。多密钥内容可以通过两种方式之一播放,具体取决于许可证服务器的配置方式。

情况 1:许可证服务器响应所有内容密钥

在这种情况下,许可证服务器的配置方式是,当它收到一个密钥的请求时,它会响应内容的所有密钥。ExoPlayer 处理这种情况,无需任何特殊配置。即使流使用不同的密钥,流之间的自适应(例如 SD 和 HD 视频)也是无缝的。

如果可能,我们建议您将许可证服务器配置为以这种方式运行。这是支持多密钥内容播放最有效和最可靠的方式,因为它不需要客户端发出多个许可证请求来访问不同的流。

情况 2:许可证服务器仅响应请求的密钥

在这种情况下,许可证服务器配置为仅响应请求中指定的密钥。可以通过在构建媒体项时将 true 传递给 MediaItem.DrmConfiguration.Builder.setMultiSession 来播放此许可证服务器配置下的多密钥内容。

我们不建议您将许可证服务器配置为以这种方式运行。它需要额外的许可证请求来播放多密钥内容,这比上面描述的替代方案效率和鲁棒性都较低。

离线密钥

可以通过在构建媒体项时将密钥集 ID 传递给 MediaItem.DrmConfiguration.Builder.setKeySetId 来加载离线密钥集。这允许使用存储在指定 ID 的离线密钥集中存储的密钥进行播放。

清晰内容的 DRM 会话

使用占位符 DrmSessions 允许 ExoPlayer 对清晰内容使用与播放加密内容时相同的解码器。当媒体同时包含清晰部分和加密部分时,您可能希望使用占位符 DrmSessions 以避免在清晰部分和加密部分之间转换时重新创建解码器。可以通过在构建媒体项时将 true 传递给 MediaItem.DrmConfiguration.Builder.forceSessionsForAudioAndVideoTracks 来启用对音频和视频轨道的占位符 DrmSessions 的使用。

使用自定义 DrmSessionManager

如果应用程序想要自定义用于播放的 DrmSessionManager,则可以实现一个 DrmSessionManagerProvider 并将其传递给 MediaSource.Factory,该 MediaSource.Factory 用于构建播放器。提供程序可以选择每次是否实例化一个新的管理器实例。要始终使用相同的实例

Kotlin

val customDrmSessionManager: DrmSessionManager = CustomDrmSessionManager()
// Pass a drm session manager provider to the media source factory.
val mediaSourceFactory =
  DefaultMediaSourceFactory(context).setDrmSessionManagerProvider { customDrmSessionManager }

Java

DrmSessionManager customDrmSessionManager = new CustomDrmSessionManager(/* ... */ );
// Pass a drm session manager provider to the media source factory.
MediaSource.Factory mediaSourceFactory =
    new DefaultMediaSourceFactory(context)
        .setDrmSessionManagerProvider(mediaItem -> customDrmSessionManager);

提高播放性能

如果您在 Android 6.0(API 级别 23)到 Android 11(API 级别 30)的任何版本的 Android 设备上播放受 DRM 保护的内容时遇到视频卡顿问题,您可以尝试启用异步缓冲队列