这是我的问题:我想播放存储在 S3 存储桶中的大型视频文件 (3.6Gb),但该文件似乎太大,加载 30 秒后页面崩溃。
这是我播放视频的代码:
var video = document.getElementById("video");
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen, { once: true });
function sourceOpen() {
URL.revokeObjectURL(video.src);
const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.f40028"');
fetch('URL_TO_VIDEO_IN_S3')
.then(response => response.arrayBuffer())
.then(data => {
// Append the data into the new sourceBuffer.
sourceBuffer.appendBuffer(data);
})
.catch(error => {
});
}
我发现 blob URL 可能是一个解决方案,但它不适用于我的 URL。
最佳答案
请对我的回答持保留态度,因为我不是专家。然而,我目前正在做一些非常类似的事情。
我怀疑您的问题是您试图立即将整个资源(视频文件)加载到浏览器中。文件大小超过 1 GB 的对象 URL 非常大。
您需要做的是使用提取请求正文中的可读流来逐 block 处理视频文件。因此,只要您不限于在 safari 浏览器中工作,您就应该在浏览器中 native 使用 Readable 和 Writeable Stream 类。
这两个类允许您形成所谓的管道。在这种情况下,您将数据从获取请求中的可读流“管道”到您创建的可写流,然后将其用作媒体源扩展及其各自的源缓冲区的基础数据源。
流管非常特殊,因为它表现出所谓的背压。您绝对应该查一下这个术语,并了解它的含义。在这种情况下,这意味着浏览器一旦有足够的数据来满足视频播放的需求,就不会请求更多的数据,它一次可以容纳的确切数量是由程序员通过称为“高水位标记”的东西指定的(您应该另请阅读相关内容)。
这使您可以控制浏览器从您的(正在进行的)获取请求请求数据的时间和数量。
注意:当您使用 .then(response => response.arrayBuffer())
时,您是在告诉浏览器等待整个资源返回,然后将响应转换为数组缓冲区.
关于javascript - 加载 HTML 格式的大型视频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57057903/