Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Online encrypted streaming video files with AES in exoplayer android

I have video files encrypted with AES stored on server. How to stream them online in exoplayer? I don't want to download the file and decrypt it: waiting for the download to complete and then play decrypted file.

like image 301
akshay_shahane Avatar asked Jun 09 '17 12:06

akshay_shahane


1 Answers

I would suggest taking a look at the UriDataSource or the DataSource interface. You can derive from DataSource and provide an implementation very similar to UriDataSource and pass that into ExoPlayer. That class has access to the read() method which all the bytes pass through. That method allows you to decrypt the files on the fly one buffer at a time.

In ExoPlayer 2.0, you supply your own custom DataSource from your own custom DataSource.Factory which can be passed to an ExtractorMediaSource (or any other MediaSource).

If you're not on ExoPlayer 2.0, you pass the DataSource to the ExtractorSampleSource and then to the VideoRenderer and the AudioRender in the buildRenderers() of a custom RendererBuilder that you implement. (Also you can Google "custom datasource exoplayer" and that should give more info if what I provided isn't enough - or I can clarify if you can't find anything).

Here's a code snippet of the read() method:

@Override
public int read(byte[] buffer, int offset, int readLength) throws IOException {
    if (bytesRemaining == 0) {
        return -1;
    } else {
        int bytesRead = 0;
        try {
            long filePointer = randomAccessFile.getFilePointer();
            bytesRead =
                    randomAccessFile.read(buffer, offset, (int) Math.min(bytesRemaining, readLength));
            // Supply your decrypting logic here
            AesEncrypter.decrypt(buffer, offset, bytesRead, filePointer);
        } catch (EOFException eof) {
            Log.v("Woo", "End of randomAccessFile reached.");
        }

        if (bytesRead > 0) {
            bytesRemaining -= bytesRead;
            if (listener != null) {
                listener.onBytesTransferred(bytesRead);
            }
        }
        return bytesRead;
    }
}

[EDIT] Also just found this SO post which has a similar suggestion.

like image 70
Kyle Venn Avatar answered Oct 26 '22 17:10

Kyle Venn