当前位置: 首页 > 知识库问答 >
问题:

Android exoplayer:本地播放AES加密视频

锺离飞飙
2023-03-14

在linux盒子上,我有一个用openssl加密的MP4视频:

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

请注意,这是一个练习,算法的强度并不重要。

该文件被发送到Android应用程序,我正在尝试使用ExoPlayer播放它。

我之前已经对文本文件进行了一些测试,以确保解密工作正常

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,在AiscipherDataSource、AiscipherDataSink、SimpleCache等之间有点势不可挡。我无法找到一种简单的方式来播放视频。

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提供,需要更改什么?(需要添加清单?标头?)

共有1个答案

越朗
2023-03-14

这是解决方案。可能需要一些调整来处理跳帧、快进等,但这会播放AES/ECB/PKCS5Padd加密视频

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()
        }
    }
 类似资料:
  • 我有一个使用AES算法加密的视频文件,但我需要在播放视频视图之前解密视频。问题是解密视频所需的时间太长。有什么办法我可以做到吗。 更新: E/ExoPlayerIMIPER内部:播放错误com.google.android.exoplayer2.upstream.2. ExoPlaybackException:源错误在com.google.android.exoplayer2. ExoPlayer

  • 请教用过阿里云视频点播VOD功能的大神以下问题: 目前阿里云视频加密有三种方式: 阿里云私有加密(IOS平台浏览器不支持播放) HLS标准加密(不知道怎么做到自适应,问客服说可以使用DRM加密) DRM商业加密(开发门槛高,苹果收费,播放好像有额外收费) 另: 文档中说要实现自适应播放,需要使用"视频打包转码模板",但是"视频打包转码模板"又不支持HLS标准加密,HLS标准加密需要使用"普通转码模

  • 我一直试图在ShakaPlayer中播放加密的。WebM媒体文件,但没有太多成功,我在这里寻求任何经历过这一点的人的建议。如果这个很棒的开发人员社区有人能在这里指导我,那就太好了。 第1轮-我所尝试的(编码和虚线): 使用ffmpeg.将.mp4文件编码为多流Video.webm(VP9)&单流Audio.webm(Vorbis)文件 使用webm_tools/webm_dash_manifest

  • 通过该接口可以获取单个视频播放密码, 地址为: http://spark.bokecc.com/api/pwd/video 参数 说明 userid 用户 id,不可为空 videoid 视频 id,不可为空 返回数据videopwd包括如下字段: 字段名 字段名 pwd 视频播放密码 返回信息如下: { "videopwd": { "pwd": “123” } }

  • 我试图在Android和PHP端使用AES加密/解密数据,并累犯空答案。 首先,我在Android中生成了对称密钥: 在服务器端,我试图解密数据。我可以解密(从RSA)秘密的AES密钥,并得到它的字符串表示。在客户端(Android)和服务器端(PHP)上是一样的。但是如何使用这个字符串AES密钥来解密数据呢?我尝试了这个(PHP): PHP中的结果: 怎么啦?

  • 我正在使用一个带有NFC的微控制器,所以我需要发送加密数据,为什么我使用AES/CBC/NOPADDING而我正在处理android应用程序,我有一个加密和解密的问题,这是我正在处理的代码 这是我的日志:-d/data ;after ;encode:-:zjsew6h+abzfkwna/pqpdzumnfhy0kmz2lxf23tdavim1c5l5oimagwxg6nrt0udciy/xeaeh