简体   繁体   English

使用 ExoPlayer 播放本地 aes128 cbc 加密的 mp3

[英]Play local aes128 cbc encrypted mp3 with ExoPlayer

I wonder what the best way is to play a local aes128-cbc encrypted mp3 file with ExoPlayer.我想知道使用 ExoPlayer 播放本地 aes128-cbc 加密的 mp3 文件的最佳方法是什么。 There is a class Aes128DataSource which seems to exist for that purpose, but I can't get ExoPlayer to play the file.有一个类 Aes128DataSource 似乎为此目的而存在,但我无法让 ExoPlayer 播放该文件。 It always returns -1 as the track duration which indicates that the file somehow is corrupt.它总是返回 -1 作为轨道持续时间,这表明文件不知何故已损坏。 There is not much information about what the error is since there is nothing in the logs.由于日志中没有任何内容,因此没有太多关于错误是什么的信息。 The mp3 just does not get played.只是没有播放 mp3。 I guess the file is not decrypted correctly.我猜文件没有正确解密。 Can somebody give an example of how to do it?有人可以举例说明如何做到这一点吗? Here is what I do:这是我所做的:

Key and iv:关键和四:

private byte[] iv = hexToBytes("..."); //32 hex symbols here as String
private byte[] key = hexToBytes("..."); //32 hex symbols here as String

hexToBytes function which converts the given key and iv from hex String to byte[]: hexToBytes 函数将给定的键和 iv 从十六进制字符串转换为字节 []:

private byte[] hexToBytes(String str) {
    if (str == null) {
        return null;
    }
    else if (str.length() < 2) {
        return null;
    }
    else {
        int len = str.length() / 2;
        byte[] buffer = new byte[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);
        }
        return buffer;
    }
}

And here what I do to play the encrypted file:在这里,我如何播放加密文件:

Uri uri = Uri.parse("android.resource://" + context.getPackageName() + File.separator + R.raw.track01_cbc);
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
String userAgent = getUserAgent(context, ...);
DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
Aes128DataSource aes128DataSource = new Aes128DataSource(dataSource, key, iv);
SampleSource sampleSource = new ExtractorSampleSource(uri, aes128DataSource, new Mp3Extractor(), RENDERER_COUNT, 5000);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
exoPlayer.prepare(audioRenderer);
exoPlayer.setPlayWhenReady(true);

According to the developer of ExoPlayer Aes128DataSource is only meant as part of using HLS streaming.根据 ExoPlayer 的开发者的说法,Aes128DataSource 只是作为使用 HLS 流媒体的一部分。 In the next versions of ExoPlayer Aes128DataSource will be private to HLS package.在 ExoPlayer 的下一版本中,Aes128DataSource 将为 HLS 包私有。 See full answer on github .github上查看完整答案。 What you have to do is create your own DataSource and implement the decryption yourself.您需要做的是创建自己的数据源并自己实现解密。

"If you can make a DataSource that will return correctly decrypted data at the offsets requested, then ExoPlayer will "just work"" “如果您可以制作一个数据源,该数据源将在请求的偏移量处正确返回解密数据,那么 ExoPlayer 将“正常工作””

I just posted an answer on a different but similar question that might solve your problem.我刚刚发布了一个不同但类似的问题的答案,可能会解决您的问题。 You need to create a custom DataSource that skips the cipher stream at the beginning, and the cipher needs to update itself to use the previous block's ciphertext as IV to start decrypting from an arbitrary position and on.您需要创建一个在开始时跳过密码流的自定义数据源,并且密码需要自我更新以使用前一个块的密文作为 IV 从任意位置开始解密等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM