数字版权管理

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。提供方可以选择是否每次都实例化新的管理器实例。如需始终使用同一实例,请执行以下操作:

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)之间任何版本的设备上播放受 DRM 保护的内容时遇到视频卡顿问题,可以尝试启用异步缓冲区排队