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