Android + exoplayer:在本地播放AES加密的视频 [英] Android + exoplayer: play AES encrypted videos, locally

查看:145
本文介绍了Android + exoplayer:在本地播放AES加密的视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux机器上,我有一个用openssl加密的MP4视频:

On a linux box, I have an MP4 video that is encrypted with openssl:

openssl enc -aes-128-ecb -a -in video.mp4 -out video.enc -K `cat aes.key`

请注意,这是一种练习,算法的强度无关紧要.

Please note, this is an exercise, the strength of the algo doesn't matter.

该文件已发送到Android应用,我正在尝试使用ExoPlayer播放它.

That file is sent to an Android app, and I'm trying to play it using ExoPlayer.

我事先对文本文件做了一些测试,以确保解密工作正常

I've done some tests beforehand with text files to make sure the decryption was working properly

fun decrypt(key: ByteArray, data: ByteArray): ByteArray {
    val spec = SecretKeySpec(key, "AES")
    val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
    cipher.init(Cipher.DECRYPT_MODE, spec)
    globalCipher.init(Cipher.DECRYPT_MODE, spec)
    return cipher.doFinal(data)
}

关于ExoPlayer, AesCipherDataSource AesCipherDataSink SimpleCache 等之间有点不知所措.播放视频.

Regarding ExoPlayer, it's a bit overwhelming between AesCipherDataSource, AesCipherDataSink, SimpleCache etc. I was not able to put together a simple way to play the video.

fun playVideo() {
    val player = SimpleExoPlayer.Builder(this).build()
    playerView.player = player

    val dataSourceFactory = DefaultDataSourceFactory? // <-- what's the factory?
    val dataSource = AesCipherDataSource(globalCipher, ?) // <-- what's the data source?
    val extractorsFactory: ExtractorsFactory = DefaultExtractorsFactory()
    try {
        val uri = Uri.fromFile(File(path, "video.enc"))
        val videoSource =
                ExtractorMediaSource(uri, dataSourceFactory, extractorsFactory, null, null)
        player.prepare(videoSource)
        player.playWhenReady = true
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

那么问题:

  1. 如何实现在本地播放此加密视频?
  2. 通过HTTP提供视频后,需要进行哪些更改?(需要添加清单吗?标头?)

推荐答案

这是解决方案.可能需要进行一些调整才能处理跳帧,快进等问题,但这会播放 AES/ECB/PKCS5Padding 加密视频

here's the solution. Might need some adjustments to handle skipping frames, fast forward etc, but this plays an AES/ECB/PKCS5Padding encrypted video

class EncryptedDataSourceFactory(
    private val key: String
) : DataSource.Factory {
    override fun createDataSource(): EncryptedDataSource =
        EncryptedDataSource(key)
}

class EncryptedDataSource(private val key: String) : DataSource {
    private var inputStream: CipherInputStream? = null
    private lateinit var uri: Uri

    override fun addTransferListener(transferListener: TransferListener) {}

    override fun open(dataSpec: DataSpec): Long {
        uri = dataSpec.uri
        try {
            val file = File(uri.path)
            val skeySpec = SecretKeySpec(key.toByteArray(), KeyProperties.KEY_ALGORITHM_AES)
            val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
            cipher.init(Cipher.DECRYPT_MODE, skeySpec)
            inputStream = CipherInputStream(file.inputStream(), cipher)
        } catch (e: Exception) {
            
        }
        return dataSpec.length
    }

    @Throws(IOException::class)
    override fun read(buffer: ByteArray, offset: Int, readLength: Int): Int =
        if (readLength == 0) {
            0
        } else {
            inputStream?.read(buffer, offset, readLength) ?: 0
        }

    override fun getUri(): Uri? =
        uri

    @Throws(IOException::class)
    override fun close() {
        inputStream?.close()
    }
}

    private fun playVideo(key: String) {
        val player = SimpleExoPlayer.Builder(this).build()
        playerView.player = player

        val dataSourceFactory: DataSource.Factory = EncryptedDataSourceFactory(key)
        val extractorsFactory: ExtractorsFactory = DefaultExtractorsFactory()
        try {
            val uri = Uri.fromFile(video)
            val videoSource: MediaSource = ExtractorMediaSource(uri, dataSourceFactory, extractorsFactory, null, null)
            player.prepare(videoSource)
            player.playWhenReady = true
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

这篇关于Android + exoplayer:在本地播放AES加密的视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆