javascript - 以 HTML 格式加载大型视频文件
问题描述
这是我的问题:我想播放存储在 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 非常大。
您需要做的是使用获取请求正文中的可读流来逐块处理视频文件。因此,只要您不局限于在 safari 浏览器中工作,您就应该在浏览器中本地使用 Readable 和 Writeable Stream 类。
这两个类允许您形成所谓的管道。在这种情况下,您将 fetch 请求中的可读流中的数据“管道”到您创建的可写流,然后将其用作媒体源扩展及其各自源缓冲区的底层数据源。
流管非常特殊,因为它表现出所谓的背压。您绝对应该查一下这个术语,并了解它的含义。在这种情况下,这意味着一旦浏览器有足够的数据来满足其视频播放的需求,它就不会请求更多的数据,它一次可以容纳的确切数量是由程序员通过称为“高水位标记”的东西指定的(你应该也读过这个)。
这使您可以控制浏览器何时以及从您的(正在进行的)获取请求中请求多少数据。
注意:当您使用时,.then(response => response.arrayBuffer())
您是在告诉浏览器等待整个资源返回,然后将响应转换为数组缓冲区。