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 保护的内容时遇到视频卡顿问题,您可以尝试启用异步缓冲队列。