HTML中的HTML5视频完全预加载

时间:2012-03-08 10:34:26

标签: javascript jquery html5 video html5-video

我有一个高质量的视频,我不能压缩太多,因为它将成为大量图像分析的基础,每个帧将被重新绘制到画布然后进行操作。

我试图在播放之前预先加载整个内容,因为我无法将视频停止,缓冲并继续。是否有一个我可以收听的事件,表示在开始播放之前整个视频已预先加载?

以下是我在JS / jQuery中的表现:

this.canvas            = this.el.find("canvas")[0];
this.video             = this.el.find("video")[0];
this.ctx               = this.canvas.getContext("2d");
this.video.autoplay    = false;

this.video.addEventListener("play",this.draw)
this.video.addEventListener("timeupdate",this.draw)
this.video.addeventlistener("ended",this.trigger("complete",this))

7 个答案:

答案 0 :(得分:22)

这将在JavaScript中加载整个视频

var r = new XMLHttpRequest();
r.onload = function() {
    myVid.src = URL.createObjectURL(r.response);
    myVid.play();
};
if (myVid.canPlayType('video/mp4;codecs="avc1.42E01E, mp4a.40.2"')) {
    r.open("GET", "slide.mp4");
}
else {
    r.open("GET", "slide.webm");
}

r.responseType = "blob";
r.send();

答案 1 :(得分:7)

canplaythrough是在没有缓冲的情况下下载足够的数据时应该触发的事件。

来自Opera团队非常出色(尽管现在可能非常过时)资源Everything you need to know about HTML5 video and audio

  

如果加载成功,无论是使用src属性还是使用源元素,那么在下载数据时,会触发进度事件。加载足够的数据以确定视频的尺寸和持续时间后,会触发loadedmetadata事件。如果加载了足够的数据来渲染帧,则会触发loadeddata事件。当加载了enugh数据以便能够播放一些视频时,会触发canplay事件。当浏览器确定它可以播放整个视频而不停止下载更多数据时,会触发canplaythrough事件;如果视频具有自动播放属性,也会在视频开始播放时播放。

请注意,iOS设备不支持'canplaythrough'事件,如weweplayingyet.org所述:http://areweplayingyet.org/event-canplaythrough

您可以通过将load元素绑定到同一个函数来绕过支持限制,因为它会触发它们。

答案 2 :(得分:1)

到目前为止,我们发现最值得信赖的解决方案是播放它并等待缓冲区完全加载。

这意味着如果视频很长,则必须等待几乎所有视频长度。

这不酷,我知道。

想知道某人是否已经找到了其他神奇可靠的方法(理想情况下使用像PreloadJS这样的东西,当不支持HTML5视频时会自动回退到闪存)。

答案 3 :(得分:1)

你可以使用这个漂亮的插件: https://github.com/GianlucaGuarini/jquery.html5loader 在其API中,有一个onComplete事件,当插件完成加载所有源时会触发

答案 4 :(得分:0)

这有用吗?

video.onloadeddata = function(){
  video.onseeked = function(){
    if(video.seekable.end(0) >= video.duration-0.1){
      alert("Video is all loaded!");
    } else {
      video.currentTime=video.buffered.end(0); // Seek ahead to force more buffering
    }
  };
  video.currentTime=0; // first seek to trigger the event
};

答案 5 :(得分:0)

希望这可以帮到你

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();

然后,如果你的视频src有另一个域,你必须处理CORS。

答案 6 :(得分:0)

  1. 使用 fetch 下载视频
  2. 将响应转换为 blob
  3. 从 blob 创建对象 URL(例如 blob:http://localhost:8080/df3c4336-2d9f-4ba9-9714-2e9e6b2b8888)
async function preloadVideo(src) {
  const res = await fetch(src);
  const blob = await res.blob();
  return URL.createObjectURL(blob);
}

用法:

const video = document.createElement("video");
video.src = await preloadVideo("https://example.com/video.mp4");