Reputation: 605
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);
Upvotes: 2
Views: 1855
Reputation: 738
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.
Upvotes: 1
Reputation: 605
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""
Upvotes: 1