数字版权管理

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 无需任何特殊配置即可处理这种情况。即使流使用不同的密钥,它们之间的自适应(例如标清和高清视频)也是无缝的。

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

情况 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。提供程序可以选择是每次都实例化新的管理器实例还是不实例化。要始终使用同一个实例

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 level 23) 到 Android 11 (API level 30)(含)的任何 Android 版本的设备上播放受 DRM 保护的内容时遇到视频卡顿,可以尝试启用异步缓冲区排队