以HTML加载大型视频文件

时间:2019-07-16 13:02:41

标签: javascript html video media-source

这是我的问题:我想播放存储在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不能很好地配合。

2 个答案:

答案 0 :(得分:1)

因为我不是专家,所以以一小撮盐回答我。但是,我目前正在从事非常相似的工作。

我怀疑您的问题是您正在尝试将整个资源(视频文件)一次加载到浏览器中。文件大小超过GB的对象URL非常大。

您需要做的是使用提取请求正文中的可读流来逐块处理视频文件。因此,只要您不局限于在Safari浏览器中工作,就应该在浏览器中本机使用Readable和Writeable Stream类。

这两个类使您可以形成所谓的管道。在这种情况下,您要将数据从获取请求中的可读流“插入”到您创建的可写流,然后将其用作媒体源扩展及其各自的源缓冲区的基础数据源。

流管的特殊之处在于它表现出所谓的背压。您绝对应该查一查该术语,并了解其含义。在这种情况下,这意味着浏览器一旦有足够的能力来满足视频播放的需求,便不会再请求更多数据,程序员可以通过“高水位标记”来指定一次可容纳的确切数量(您应该另请参阅)。

这使您可以控制浏览器从(正在进行的)获取请求中请求的时间和数据量。

注意:当您使用.then(response => response.arrayBuffer())时,是在告诉浏览器等待整个资源返回,然后将响应转换为数组缓冲区。

答案 1 :(得分:-2)

选项1

使用CloudFront为这些资源创建RTMP分发。

它将以流媒体方式分发您的视频。

  

使用Adobe Flash Media Server的RTMP协议创建RTMP分发,以加快流媒体文件的分发。


请注意,HTML5默认情况下不支持RTMP格式(不带Flash)。

在此处检查options


JWPlayer支持使用Flash进行RTMP播放。 SO Question

---

选项2

使用Elastic Transcoder创建HLS视频( .m3u8 格式)。同样,同一JWPlayer可以轻松处理它。

此外,原生HTML5大多支持该功能。选中compatibility with H.264