将暂停的视频帧捕获到画布的最佳方法 [英] Best way to capture paused video frame to canvas

查看:82
本文介绍了将暂停的视频帧捕获到画布的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何使用2D上下文将正在播放的HTML5视频逐帧复制到画布.

I know how to copy on frame by frame basis from a playing HTML5 video to a canvas using 2D context.

但是我想使用暂停的视频,对其名称进行currentTime更改,然后将当前视频帧复制到画布上.

But I want to work with a paused video, change dinamically its currentTime and copy current frame of video to canvas.

我的猜测是,当视频位置使用currentTime属性设置时,尚未调用某些过程,尽管视频本身确实会更新显示的图像(但不会显示在画布上).

My guess is some process is not called yet when video position is set with currentTime property, although the video itself does update the image it shows (but not to the canvas).

我发现可以通过在下一步中设置setTimeout来完成画布"drawImage"来克服这一问题.

I've found that it's posible to overcome this by setting a setTimeout to do the canvas ´drawImage´ in the next step.

您可以在此处看到证明这一点的jsfiddle .

如您在小提琴中看到的那样,您可以播放视频和画布更新,但是如果您暂停视频,则鼠标滚动会移动视频的currentTime.在那里,需要"seTimeout"来更新画布,如果我直接调用drawImage方法,则画布不会更新.

As you can see in the fiddle you can play the video, and canvas updates, but if you pause the video, mouse scroll moves currentTime of video. There, a ´seTimeout´ is needed to update the canvas, if I call the drawImage method directly, canvas doesn't update.

简而言之,我的问题是:

是否有更好的方法可以做到这一点?是否可以在没有setTimeout和内部de loop本身的情况下执行此操作?利与弊缺点?

Is there a better way to do this? Is it posible to do this without setTimeout and inside de loop itself? Pros & Cons?

非常感谢您在这里通读!

Thank you very much for reading through here!

推荐答案

每次更改VideoElement的currentTime时,都会

Every time you change the currentTime of your VideoElement, a seeked Event will trigger when the video actually changed its position.

var vid = document.getElementById("v");
var canvas = document.getElementById("c");
var context = canvas.getContext('2d');
var targetFrame = document.getElementById('t');
var cw = canvas.width = 200;
var ch = canvas.height = Math.round(cw / 1.7777);
var targetOffset = 0;

window.addEventListener('wheel', function(e) {
  e.preventDefault();
  targetOffset = targetOffset + (e.deltaY / 1000);
  targetFrame.value = targetOffset;
  seek(); // for demo purpose, we only listen to wheel
  return false;
});
// that's all is needed
vid.addEventListener('seeked', function() {
  context.drawImage(vid, 0, 0, cw, ch);
});
// for demo
// removed the rendering loop
// now it only changes the video's currentTime property
function seek() {
  targetOffset = targetOffset * 0.9;
  targetFrame.value = Math.round(targetOffset * 100) / 100;
  var vct = vid.currentTime - targetOffset;
  if (vct < 0) {
    vct = vid.duration + vct;
  } else if (vct > vid.duration) {
    vct = vct - vid.duration;
  }
  vid.currentTime = vct;
}

.column {
  float: left;
  width: 50%;
}
.row:after {
  content: "";
  display: table;
  clear: both;
}
#c {
  border: 1px solid black;
}

<h3>
  scroll up is forward
</h3>
<div class="row">
  <div class="column">
    <div>
      Video element:
    </div>
    <video controls height="120" id="v" tabindex="-1" autobuffer="auto" preload="auto">
    <source type="video/webm" src="https://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.webm"/>
</video>
  </div>
  <div class="column">
    <div>
      Canvas element:
    </div>
    <canvas id="c"></canvas>
    <div>
      Momentum: <input type=text id="t">
    </div>
  </div>
</div>

这篇关于将暂停的视频帧捕获到画布的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆