能否在播放之前预加载整个HTML5视频源?

8

解决方案

我创建了一个可用的示例,使用XHR并通过进度条报告加载进度,具体请点击这里.

问题

我注意到当我创建一个带有资源的<video>元素并调用load()时,它会加载到约36%,然后停止,除非你play()它,此时它将在播放时继续加载其余的视频。

然而,我想要确保整个视频在手动播放前都已加载完毕,因为它是定时练习中的一个元素,如果在练习期间互联网连接断开,我将不得不检测到这种事件并重新开始练习。

我认为这是HTML5媒体元素的内置功能,但是否可以覆盖此本机功能?

我尝试使用XMLHttpRequest将整个视频源作为arraybuffer加载,然后将其转换为blob,并将其设置为我的<video>元素中的<source>元素的src。这确实有效,但不理想,因为我无法通过进度条向用户报告下载进度,因为XHR是同步操作,会导致我的JavaScript挂起,直到收到响应。我知道XHR2现在具有此功能,但我必须支持IE8+,因此这不是一个选项。

是否有更简单,更优雅的解决方案来解决我的问题,并报告进度?

要求

  • 需要在播放之前预加载整个<video>元素的<source>
  • 需要报告进度。

你知道IE8不支持视频标签吗? - jlowcs
@jlowcs:我正在将它包装成视频,如果需要的话会创建一个Flash回退。 - jshbrntt
1
@Oriol:是的,但是preload="auto"只会部分预加载,在某些情况下在iOS上根本不会预加载。 - jshbrntt
@PanamaJack,不幸的是,一些大公司仍然使用IE8等老旧系统,并且在推出最新软件和硬件方面进展缓慢。 - jshbrntt
@PanamaJack,事实上,他们应该在未来几个月内获得FF,但是在那之前,这个产品必须交付。是的,videojs正在处理Flash回退。 - jshbrntt
显示剩余3条评论
2个回答

13

如果您有源代码,可以在JavaScript中将数据预先下载到 blob 中,在准备好播放时直接播放。

如果视频不在您的服务器上,则会遇到 CORS 问题。

var video = document.getElementById("Your video element id")

var url = "Some video url"

var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";

xhr.onload = function(oEvent) {

    var blob = new Blob([oEvent.target.response], {type: "video/yourvideosmimmetype"});

    video.src = URL.createObjectURL(blob);

    //video.play()  if you want it to play on load
};

xhr.onprogress = function(oEvent) {

    if (oEvent.lengthComputable) {
        var percentComplete = oEvent.loaded/oEvent.total;
        // do something with this
    }
}

xhr.send();

这个可行,谢谢。我也在原帖中包含了一个可行的示例。 - jshbrntt
https://dev59.com/VYjca4cB1Zd3GeqPwWug - jshbrntt
不幸的是,当Blob超过2MB时(据我所知),Chromium会崩溃。这几乎适用于所有视频。 - Bernardo Dal Corno
我刚在Chromium 63.0.3239.132上进行了检查,使用Ubuntu 17.10 64位操作系统,在4.4 MB的视频和25 MB的视频上都可以正常工作。 - Sam
是否可以预加载视频的开头部分? - Littlee

5

以下是使用XHR预加载完整视频的示例,但您需要自行处理CORS。

var xhrReq = new XMLHttpRequest();
xhrReq.open('GET', 'yourVideoSrc', true);
xhrReq.responseType = 'blob';

xhrReq.onload = function() {
    if (this.status === 200) {
        var vid = URL.createObjectURL(this.response);
        video.src = vid;
    }
}
xhrReq.onerror = function() {
    console.log('err' ,arguments);
}
xhrReq.onprogress = function(e){
    if(e.lengthComputable) {
        var percentComplete = ((e.loaded/e.total)*100|0) + '%';
        console.log('progress: ', percentComplete);
    }
}
xhrReq.send();

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