Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 加密密钥不可用-ExoPlayer_Android_Exoplayer_Mpeg Dash_Exoplayer2.x - Fatal编程技术网

Android 加密密钥不可用-ExoPlayer

Android 加密密钥不可用-ExoPlayer,android,exoplayer,mpeg-dash,exoplayer2.x,Android,Exoplayer,Mpeg Dash,Exoplayer2.x,因此,我试图播放Dash文件(.mpd)中的加密内容,该文件用Shaka Packager打包,并用CENC方法加密。媒体在Shaka播放器上的播放效果绝对不错,但我无法在Android的ExoPlayer上播放。播放时,Logcat显示以下错误: Caused by: android.media.MediaCodec$CryptoException: Crypto key not available at android.media.MediaCodec.native_queueSec

因此,我试图播放Dash文件(.mpd)中的加密内容,该文件用Shaka Packager打包,并用CENC方法加密。媒体在Shaka播放器上的播放效果绝对不错,但我无法在Android的ExoPlayer上播放。播放时,Logcat显示以下错误:

Caused by: android.media.MediaCodec$CryptoException: Crypto key not available
    at android.media.MediaCodec.native_queueSecureInputBuffer(Native Method)
    at android.media.MediaCodec.queueSecureInputBuffer(MediaCodec.java:2699)
    at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:1188)
    at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:719) 
    at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:599) 
    at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:329) 
    at android.os.Handler.dispatchMessage(Handler.java:103) 
    at android.os.Looper.loop(Looper.java:237) 
    at android.os.HandlerThread.run(HandlerThread.java:67) 
Gradle的最小Sdk限制为API 21,因此可以签出,使用的代码是:

    player = new SimpleExoPlayer.Builder(this).build();
    ep.setPlayer(player);

    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "AppName"));
    Uri uri = Uri.parse(Tools.baseAddress+"VIDEO/"+i.getStringExtra("ModuleID")+"/index.php").buildUpon().appendQueryParameter("token", Tools.token).build();

    String keyString = "{\"keys\":[{\"kty\":\"oct\",\"k\":\"76a6c65c5ea762046bd749a2e632ccbb\",\"kid\":\"a7e61c373e219033c21091fa607bf3b8\"}],'type':\"temporary\"}";

    LocalMediaDrmCallback drmCallback = new LocalMediaDrmCallback(keyString.getBytes());
    DrmSessionManager manager=null;
    manager = new DefaultDrmSessionManager.Builder()
            .setPlayClearSamplesWithoutKeys(true)
            .setMultiSession(false)
            .setUuidAndExoMediaDrmProvider(C.CLEARKEY_UUID, FrameworkMediaDrm.DEFAULT_PROVIDER)
            .build(drmCallback);

    MediaSource dashMediaSource = new DashMediaSource.Factory(dataSourceFactory).setDrmSessionManager(manager).createMediaSource(uri);

    player = new SimpleExoPlayer.Builder(this).build();

    ep.setPlayer(player);
    player.prepare(dashMediaSource);
使用Shaka Packager打包MP4视频时使用的命令是:

.\packager input=videoplayback.mp4,stream=video,output=video.mp4 input=videoplayback.mp4,stream=audio,output=audio.mp4 --enable_raw_key_encryption --keys key_id=a7e61c373e219033c21091fa607bf3b8:key=76a6c65c5ea762046bd749a2e632ccbb --clear_lead 0 --mpd_output dash.mpd
我不确定密钥格式是否正确,或者DRM会话管理器是否正确初始化。 如果有任何帮助,我将不胜感激。

提前感谢。

最可能的原因是LocalMediaDrmCallback方法希望密钥和密钥id采用base64url编码

您可以使用以下在线工具将您的密钥和密钥id转换为:


您也可以在GitHub问题讨论中看到一个编程示例:

我花了很长时间研究“CryptoKey not available”异常

我发现这个例外发生在一些错误的事情上

  • MediaDrmCallback坏了。当使用ClearKey系统时,使用LocalMediaDrmCallback或子类,不能与网络连接

  • 密钥响应(kid&k)base64url实现错误,不包括'/''=''\n'+'

  • 一些媒体文件用clearlead时间加密,我的视频设置参数是30秒,所以总是发生异常,我认为Android DRM会话或密钥在内存中超时

  • DrmSessionManager配置设置错误。使用“setMultiSession”时请注意,它会破坏您的设置

  • 我用以下方法解决此问题:

  • setMultiSession(true),true表示一个请求返回一个键,不要使用“false”
  • 替换并实现其他MediaDrmCallback,使用Map实现“一个Req返回一个键”
  • 原因:

  • 我认为,如果您的视频有clearlead时间,一些设备或DRM会话实现会超时,DRM将播放清晰内容和加密内容。当视频加载开始播放和第一次加密内容播放时,DRM会话将获得两次密钥。因此,使用的第一个密钥无法加载视频加载密钥

  • 当您的DASH manifest文件包含一些具有不同密钥、音频、HD、SD或其他的视频时,当网络速度低或高时,播放的视频将发生更改,DRM会话将使用其他密钥解密,但我认为更改将找不到正确的密钥

  • 当我使用setMultiSession(false)->这意味着“一个请求-响应-所有密钥”,并且使用LocalMediaDrmCallback(responseJson)很简单时,我的视频将播放错误或良好,我认为有一段时间设备加载json并找到第一个密钥,或者其他时间使用坏密钥

  • 我在我的网站上写了一些关于这个问题的代码和信息:(中文),请看它来解决这个问题

    我认为“CryptoKey not available”(加密密钥不可用)异常非常糟糕,请为您写下此回复