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 级别 23)至 Android 11(API 级别 30)的任意版本的设备上,播放受 DRM 保护的内容时,如果您遇到视频卡顿,可以尝试启用异步缓冲区队列。