将暂停的视频帧捕获到画布的最佳方法 [英] Best way to capture paused video frame to canvas
问题描述
我知道如何使用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.
如您在小提琴中看到的那样,您可以播放视频和画布更新,但是如果您暂停视频,则鼠标滚动会移动视频的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屋!