从内存源播放HTML5视频

4
我正在使用一些ajax查询来检索多个加密数据,并进行一些操作,将所有这些加密块转换为有效的视频。现在,我已经将视频的二进制数据存储在内存中,但是我遇到了问题。如何显示它呢?
为了确认,我已经在服务器端复制了所有这些步骤,并且最终输出确实是可播放的视频。因此,我的唯一问题是如何将我的javascript二进制对象显示为视频。
我正在尽力只使用Web技术(html5、video标签、javascript),并希望避免开发自己的Flash自定义播放器,这是我最后的解决方案。
如果您有任何想法,我很感兴趣。对于我而言,我已经想不出更好的办法了。

3
您的意思是视频加密后的分块通过网络传输到浏览器,然后使用JavaScript进行解密?如果是这样的话,那么这种解密方式并没有比把钥匙留在车里,然后在挡风玻璃上放置一张“请不要偷我”的牌子更安全。话虽如此,只要视频的长度不太长,您可以将Base64编码的DataURL直接放入video元素的src属性中,这样就可以正常播放了。虽然我不确定它的大小限制是多少,但52MB的MP4文件是可以的,而350MB的则不行。 - enhzflep
是的,就是这样。除了页面访问受限和解密密钥由用户定义之外。 我真的很喜欢Base64的想法,我会尝试一下。它可能有效。 - blaazzze
1
事实上,加密并不是为了保护内容本身。一旦用户可以访问页面,他可以随心所欲地进行任何操作。安全级别是为了确保服务器无法访问视频内容。这是用户的财产,我们断言即使我们想要查看他们的文件,我们也不能这样做。因此,在进入服务器之前,所有内容都会被加密。 - blaazzze
啊,我明白了。这种情况和我想象的有些不同。也许下面的答案会给你一些启示和思路。 :) - enhzflep
2个回答

2
要显示您的视频,您需要获取其URL,以便能够传递给视频元素的引用。
有一个URL.createObjectURL函数,它应该为您提供这样的URL以引用您的数据。请参见https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL进行进一步的解释,并注意兼容性表格。
Mozilla在https://developer.mozilla.org/samples/domref/file-click-demo.html上托管了一个示例,用于显示本地文件。应该可以将其适应于设置视频元素的src属性。根据您存储数据的方式,应该可以通过这种方式播放您的视频。
我在Firefox中尝试使用File对象中的数据,结果得到了一个URL(blob:https://developer.mozilla.org/ed2e4f2f-57a6-4b06-8d56-d0a1a47a9ffd),我可以用它来播放视频。

2
这里是一个快速示例,它只使用文件输入而不是通常使用的 AJAX。注意第一个输入被连接到一个函数,该函数将读取文件并返回数据 URL。
然而,由于你没有一个文件对象,而是有一个表示文件内容的数据流,所以你不能使用这种方法。因此,我包括了第二个输入,它连接到一个函数,仅将文件加载为二进制字符串。然后,这个字符串被手动用浏览器函数进行 base64 编码,然后转换为数据 URL。为了做到这一点,你需要知道正在处理的文件类型,以便正确构造 URL。
即使在这台 i7 笔记本电脑上,加载速度也相当缓慢,并且可能会像没人的事情一样占用内存——移动电话可能会晕倒(我还没有测试过)。
你应该能够获取数据流并从我有原始数据的地方继续进行处理(var rawResult = evt.target.result;
错误检查留给读者作为练习。
<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}

// callback gets data via the .target.result field of the param passed to it.
function loadFileObject(fileObj, loadedCallback)
{
    var reader = new FileReader();
    reader.onload = loadedCallback;
    reader.readAsDataURL( fileObj );
}

// callback gets data via the .target.result field of the param passed to it.
function loadFileAsBinary(fileObj, loadedCallback)
{
    var reader = new FileReader();
    reader.onload = loadedCallback;
    reader.readAsBinaryString( fileObj );
}


window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
    byId('fileInput1').addEventListener('change', onFileInput1Changed, false);
    byId('fileInput2').addEventListener('change', onFileInput2Changed, false);
}

function onFileInput1Changed(evt)
{
    if (this.files.length != 0)
    {
        var curFile = this.files[0];
        loadFileObject(curFile, onVideoFileReadAsURL);

        function onVideoFileReadAsURL(evt)
        {
            byId('vidTgt').src = evt.target.result;
            byId('vidTgt').play();
        }
    }
}

function onFileInput2Changed(evt)
{
    if (this.files.length != 0)
    {
        var curFile = this.files[0];
        loadFileAsBinary(curFile, onVideoFileReadAsBinary);

        function onVideoFileReadAsBinary(evt)
        {
            var rawResult = evt.target.result;
            var b64Result = btoa(rawResult);

            var prefaceString = "data:" + curFile.type + ";base64,";
//          byId('vidTgt').src = "data:video/mp4;base64," + b64Result;
            byId('vidTgt').src = prefaceString + b64Result;
            byId('vidTgt').play();
        }
    }
}
</script>
<style>
</style>
</head>
<body>
    <input type='file' id='fileInput1'/>
    <input type='file' id='fileInput2'/>
    <video id='vidTgt' src='vid/The Running Man.mp4'/>
</body>
</html>

你的回答非常有帮助。我有类似的问题,我卡在了将多个块连接成唯一的 blob 上。但是当这个问题解决后,我认为它会起作用。我会保持联系。谢谢。 - blaazzze
由于您的回答完全符合我的问题,我将把您的消息标记为答案。但在我的情况下,我最终将创建自己的定制Flash播放器,因为我将对工作流程进行一些更改,以流式传输加密视频,而不是必须将完整视频保留在内存中(可以从2MB到超过1GB)。但是您的答案完全符合我的原始问题,所以谢谢。 - blaazzze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接