【问题标题】:Is it possible to run a javascript proxy that proxy the video's media request on the client side?是否可以在客户端运行代理视频媒体请求的 javascript 代理?
【发布时间】:2022-01-20 04:46:19
【问题描述】:

我在 CDN 上托管了视频文件,视频文件已加密。所以我需要在浏览器中播放之前解密它。但是web video标签没有修改媒体流的接口。

所以我想用javascript在客户端运行一个代理来代理媒体流请求,并将英尺之前的流解密到视频标签。

有可能吗?


math-chen's answer,我尝试了下面的代码,但是当我播放它时,视频会保持旋转并且不会像下图那样渲染帧。

我使用了一个很小的未加密视频文件out.mp4,所以可以一次加载。

<html>
    <video id="video" controls src="out.mp4">
    </video>

    <script>
        const video = document.querySelector('#video');
        const mediaSource = new MediaSource();
        video.src = URL.createObjectURL(mediaSource);
        mediaSource.addEventListener('sourceopen', sourceOpen);
        function sourceOpen() {
            var mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
            var sourceBuffer = mediaSource.addSourceBuffer(mime);
            fetchBuffer('out.mp4', buffer => {
                sourceBuffer.appendBuffer(buffer)
            })
        }

        function fetchBuffer (url, callback) {
            var xhr = new XMLHttpRequest;
            xhr.open('get', url);
            xhr.responseType = 'arraybuffer';
            xhr.onload = function () {
                callback(xhr.response);
            };
            xhr.send();
        }
    </script>    
</html>

【问题讨论】:

  • 你是如何解密的(它是一个需要字节数组或其他东西的函数)?你得到(返回)什么作为解密的输出,又是一个数组/缓冲区?您是否可能在问“如何使用视频标签播放字节值数组(缓冲区)”?
  • 视频是你自己加密后上传到CDN的吗?如果是,那么fragment加密前的mp4。还是 CDN 以加密格式提供视频?如果是,那么您需要在播放前检查 CDN 是否提供了他们的视频播放器或 JavaScript API 来在客户端解码视频。
  • “我想代理媒体流请求,并在馈送到视频标签之前解密流” (1) 为什么不使用FetchXMLHttpRequest API 接收流数据(它只能作为字节缓冲区进入数组,我不知道这是否适合您的解密系统)。 (2) 如果您有一个完整的视频文件解密(作为数组),那么您可以转换为 blob 并将 blob 用作视频标签的.src。如果您一次只获得部分,则使用 MSE 播放解密后的可用内容。但是 MSE 需要额外的工作(了解 fMP4 格式结构)。
  • PS:如果 Javascript 无法从 CDN 获取字节,请尝试使用 PHP(eg: 使用 readFile)(例如,如果您在读取来自外部服务器的文件)。

标签: javascript html proxy html5-video mediastream


【解决方案1】:

它不需要代理

const video = document.querySelector('#video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
//you can implement logic in function sourceOpen
function sourceOpen() {
  //mime is type of video
  const sourceBuffer = mediaSource.addSourceBuffer(mime);
  fetch(videoUrl).then(function(response) {
     //decrypt
     return response.arrayBuffer();
  }).then(buffer => {
    sourceBuffer.appendBuffer(arrayBuffer);
  });
}

【讨论】:

  • 这是正确的方法。你能添加更多的细节。谢谢。
  • 你能检查我的代码,在我的编辑中,我哪里做错了吗?
  • @LF00 PS:您不能将常规 MP4 与 MediaSource API 一起使用。它必须被编码为 fMP4(分段 MP4)。
  • @VC.One 谢谢。是否可以从客户端进行转换?
  • @LF00 我不知道你到目前为止尝试了什么,但也许可以尝试谷歌搜索mux.js。如果我没记错的话,它应该使用数组将 MP4 转换为 fMP4。 PS 关于您的问题,您为什么关心通过 MSE 播放 MP4? MSE 用于将字节解密为可播放的视频数据(我假设加密的字节不可用)...由于您不会一次拥有完整的文件,因此每个解密的块可能只提供几秒钟的视频所以使用 MSE 在获得时动态添加更多视频数据。你甚至从解密过程中得到任何字节???不明显是怎么回事……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 2013-04-26
相关资源
最近更新 更多