简体   繁体   中英

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. There is a class Aes128DataSource which seems to exist for that purpose, but I can't get ExoPlayer to play the file. It always returns -1 as the track duration which indicates that the file somehow is corrupt. There is not much information about what the error is since there is nothing in the logs. The mp3 just does not get played. 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[]:

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. In the next versions of ExoPlayer Aes128DataSource will be private to HLS package. See full answer on 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""

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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