You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExoPlayer播放本地DRM视频报Failed to restore keys错误排查

问题描述

受DRM保护的视频已成功下载至本地存储,尝试播放该本地视频时,ExoPlayer抛出DRM session错误,需要调试DRM模块定位Failed to restore keys错误的根因。

预期结果

本地下载的DRM保护视频可正常播放。

ExoPlayer版本

2.14.2

复现问题的设备
  • 搭载Android 11系统的Nokia G20
  • 搭载Android 10系统的Realme 5 Pro
异常日志
E/DefaultDrmSession: DRM session error
      java.lang.IllegalArgumentException: Failed to restore keys
        at android.media.MediaDrm.restoreKeys(Native Method)
        at com.google.android.exoplayer2.drm.FrameworkMediaDrm.restoreKeys(FrameworkMediaDrm.java:262)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.restoreKeys(DefaultDrmSession.java:437)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.doLicense(DefaultDrmSession.java:401)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.acquire(DefaultDrmSession.java:294)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSession(DefaultDrmSessionManager.java:775)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSessionWithRetry(DefaultDrmSessionManager.java:684)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSessionManager.java:563)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSessionManager.java:510)
        at com.google.android.exoplayer2.source.SampleQueue.onFormatResult(SampleQueue.java:918)
        at com.google.android.exoplayer2.source.SampleQueue.peekSampleMetadata(SampleQueue.java:686)
        at com.google.android.exoplayer2.source.SampleQueue.read(SampleQueue.java:412)
        at com.google.android.exoplayer2.source.chunk.ChunkSampleStream.readData(ChunkSampleStream.java:398)
        at com.google.android.exoplayer2.BaseRenderer.readSource(BaseRenderer.java:395)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readSourceOmittingSampleData(MediaCodecRenderer.java:996)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:830)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:945)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:478)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:223)
        at android.os.HandlerThread.run(HandlerThread.java:67)
E/VideoDisplayComponent: onDrmSessionManagerError
    java.lang.IllegalArgumentException: Failed to restore keys
        at android.media.MediaDrm.restoreKeys(Native Method)
        at com.google.android.exoplayer2.drm.FrameworkMediaDrm.restoreKeys(FrameworkMediaDrm.java:262)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.restoreKeys(DefaultDrmSession.java:437)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.doLicense(DefaultDrmSession.java:401)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.acquire(DefaultDrmSession.java:294)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSession(DefaultDrmSessionManager.java:775)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSessionWithRetry(DefaultDrmSessionManager.java:684)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSessionManager.java:563)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSession.java:510)
        at com.google.android.exoplayer2.source.SampleQueue.onFormatResult(SampleQueue.java:918)
        at com.google.android.exoplayer2.source.SampleQueue.peekSampleMetadata(SampleQueue.java:686)
        at com.google.android.exoplayer2.source.SampleQueue.read(SampleQueue.java:412)
        at com.google.android.exoplayer2.source.chunk.ChunkSampleStream.readData(ChunkSampleStream.java:398)
        at com.google.android.exoplayer2.BaseRenderer.readSource(BaseRenderer.java:395)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readSourceOmittingSampleData(MediaCodecRenderer.java:996)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:830)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:945)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:478)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:223)
        at android.os.HandlerThread.run(HandlerThread.java:67)

排查与解决步骤

1. 校验离线密钥持久化逻辑

restoreKeys调用失败90%以上由离线许可证存储异常导致,按顺序检查:

  • 下载DRM视频时,必须等onKeyStatusChange回调触发、密钥状态为USABLE之后,再持久化保存离线密钥集。如果在许可证请求未完成时提前保存空/不完整的密钥数据,恢复时必然报错。
  • 检查本地存储的密钥集字节数组是否完整,排查读写逻辑是否存在写入截断、编码转换错误(比如把字节数组转成String再转回字节数组导致数据损坏),密钥数据必须以原始字节格式存储。
  • 保存密钥时绑定的sessionId、mediaId、keySetId必须和播放时传入的参数完全一致,参数不匹配会直接导致系统DRM服务找不到对应密钥。

2. 开启DRM模块详细日志定位具体错误

ExoPlayer 2.14.2默认关闭DRM模块调试日志,初始化播放器前手动开启:

DefaultDrmSessionManager.setLogSessionIdEnabled(true);

同时给DefaultDrmSessionManager添加事件监听器,打印所有密钥状态变化、底层DRM错误码:

  • 如果错误码对应ERROR_DRM_KEY_EXPIRED,说明离线许可证已经过期,需要重新向许可证服务器申请新的离线密钥。
  • 如果错误码对应ERROR_DRM_CANNOT_HANDLE,说明设备DRM组件不支持当前加密方案的离线恢复,检查视频使用的Widevine安全级别,部分低端设备仅支持在线播放,不支持离线持久化密钥。

3. 排查系统DRM服务兼容性问题

两台测试机搭载的Android 10、11版本存在已知DRM兼容坑:

  • 检查是否在设备重启/应用清除数据后首次播放触发错误:Android 11部分厂商ROM会在设备重启后重置DRM密钥库,之前持久化的离线密钥会直接失效,这种情况需要捕获restoreKeys错误后自动触发在线许可证重请求流程,不要直接抛出播放错误。
  • 排查Widevine安全级别降级问题:如果设备解锁过Bootloader,Widevine安全级别会从L1降到L3,之前用L1级别申请的离线密钥无法在L3级别下恢复,需要重新申请对应安全级别的密钥。

4. 校验离线播放配置

播放本地DRM视频时,确认DefaultDrmSessionManager配置符合要求:

  • multiSession配置要和下载时的配置保持一致,下载时开启多会话则播放时也要开启,否则密钥恢复逻辑无法正常执行。
  • 离线播放场景不要配置强制在线许可证请求参数,DrmCallback实现中播放本地视频时要直接返回本地存储的离线密钥响应,不要走网络请求返回空数据。
  • 如果使用OfflineLicenseHelper下载密钥,确认调用downloadLicense时传入的playbackLooper和播放时使用的Looper一致,避免线程上下文错误导致密钥数据解析失败。

内容的提问来源于stack exchange,提问作者Palani A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 19:18:26