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

摩托罗拉Moto G20离线Widevine DRM播放报错‘Crypto key not available’求助

问题分析

在摩托罗拉Moto G20上离线播放已下载的Widevine DRM保护DASH流时,触发android.media.MediaCodec$CryptoException: Crypto key not available错误,但在线播放正常,且同文件在三星Galaxy S24可正常离线播放。错误栈指向MediaCodec无法获取解密密钥,核心问题大概率是设备DRM框架兼容性或离线密钥加载配置问题。

排查与修复措施
  • 验证设备Widevine等级与密钥兼容性
    Moto G20作为中低端设备,Widevine等级通常为L3,部分DRM提供商对L3设备的离线许可证有额外限制(如绑定硬件标识)。可通过代码检查设备Widevine信息:

    val widevineUuid = UUID.fromString("edef8ba9-79d6-4ace-a3c8-27dcd51d21ed")
    val mediaDrm = MediaDrm(widevineUuid)
    val securityLevel = mediaDrm.getPropertyString(MediaDrm.PROPERTY_SECURITY_LEVEL)
    val vendor = mediaDrm.getPropertyString(MediaDrm.PROPERTY_VENDOR)
    Log.d("WidevineCheck", "Security Level: $securityLevel, Vendor: $vendor")
    mediaDrm.release()
    

    确认DRM服务器是否允许L3设备下载离线许可证,或是否需要在许可证请求时提交设备唯一标识(如Android ID)。

  • 检查离线密钥的存储与加载逻辑

    1. 验证keySetId对应的密钥是否有效存储:
      val offlineHelper = OfflineLicenseHelper.newWidevineInstance(drmLicenseUrl.url, dataSourceFactory, DrmSessionEventListener.EventDispatcher())
      val keyStatus = offlineHelper.getKeyStatus(keySetId)
      Log.d("DRMKey", "Valid keys count: ${keyStatus.size}")
      offlineHelper.release()
      
    2. 避免创建HttpMediaDrmCallback时传入null许可证URL,部分设备DRM框架需该参数初始化:
      val drmSessionManager = DefaultDrmSessionManager.Builder()
          .build(
              HttpMediaDrmCallback(
                  drmLicenseUrl.url, // 传入实际DRM许可证地址
                  false,
                  DefaultHttpDataSource.Factory()
              )
          )
      
  • 调整ExoPlayer DRM配置

    1. 添加DRM事件监听,获取密钥加载的详细日志:
      drmSessionManager.addListener(object : DrmSessionEventListener {
          override fun onDrmSessionError(sessionId: DrmSessionId, error: DrmSessionException) {
              Log.e("DRMError", "Session error: ${error.cause?.message}", error)
          }
          override fun onDrmKeysLoaded(sessionId: DrmSessionId) {
              Log.d("DRMEvent", "Keys loaded successfully")
          }
      })
      
    2. 利用DownloadRequest自带的keySetId自动处理DRM,无需手动绑定:
      val player = ExoPlayer.Builder(context)
          .setMediaSourceFactory(
              DefaultMediaSourceFactory(context)
                  .setDataSourceFactory(cacheDataSourceFactory)
                  .setDrmSessionManagerProvider {
                      DefaultDrmSessionManager.Builder()
                          .build(HttpMediaDrmCallback(drmLicenseUrl.url, DefaultHttpDataSource.Factory()))
                  }
          )
          .build()
      // 直接使用download.request.toMediaItem(),无需手动设置keySetId
      player.setMediaSource(mediaSource)
      
  • 检查设备DRM框架状态

    1. 升级设备系统到最新版本,修复可能存在的DRM框架bug;
    2. 清除应用的DRM存储:进入设置 -> 应用 -> 你的应用 -> 存储 -> 清除媒体DRM数据,重新下载许可证测试;
    3. 测试其他分辨率/编码格式的离线视频,确认是否为当前AVC编码(avc1.42C028)的解密兼容性问题。
  • 确认下载媒体文件完整性
    检查缓存文件是否完整,对比下载文件大小与在线流大小:

    val download = downloads.download
    Log.d("DownloadCheck", "Total size: ${download.totalBytes}, Downloaded: ${download.downloadedBytes}")
    

    若文件不完整,重新触发下载流程。

内容的提问来源于stack exchange,提问作者Thomas Joulin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 12:59:53