使用HTML5和JavaScript从视频中捕获帧 [英] Capture frames from video with HTML5 and JavaScript
问题描述
我想要每5秒从视频捕获一帧。
这是我的JavaScript代码:
video.addEventListener loadeddata',function(){
var duration = video.duration;
var i = 0;
var interval = setInterval(function(){
video。 currentTime = i;
generateThumbnail(i);
i = i + 5;
if(i> duration)clearInterval(interval);
},300);
});
function generateThumbnail(i){
//生成缩略图URL数据
var context = thecanvas.getContext('2d');
context.drawImage(video,0,0,220,150);
var dataURL = thecanvas.toDataURL();
//创建img
var img = document.createElement('img');
img.setAttribute('src',dataURL);
//在容器中追加img div
document.getElementById('thumbnailContainer')appendChild(img);
}
我遇到的问题是生成的第一个两个图像是相同的, -5不产生第二图像。我发现缩略图是在特定时间的视频帧显示在< video>
标记。
例如,当 video.currentTime = 5
时,会生成帧0的图像。然后视频帧跳到时间5s。因此,当 video.currentTime = 10
时,会生成帧5s的图像。
原因
问题是寻求视频(设置 currentTime
)是异步的。
您需要监听 seeked
事件,否则将采用您的旧值的实际当前帧。
由于它是异步的,你不能使用 setInterval
,因为它是异步的,你将无法正确同步下一帧被寻找。没有必要使用 setInterval
,因为我们将使用 seeked
事件,这将保持一切同步。 p>
解决方案
通过重写代码,您可以使用 示例 将此事件处理常式加入政党: I want to capture a frame from video every 5 seconds. This is my JavaScript code: The problem I have is the 1st two images generated are the same and the duration-5 second image is not generated. I found out that the thumbnail is generated before the video frame of the specific time is displayed in For example, when The problem is that seeking video (setting it's You need to listen to the As it is asynchronous you must not use the By re-writing the code a little you can use the Example Add this event handler to the party:
这篇关于使用HTML5和JavaScript从视频中捕获帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! seeked
事件通过视频捕获正确的帧,因为此事件确保我们实际上是在我们请求的框架,通过设置
currentTime
属性。 / p>
是全局的(或绑定到一个唯一的对象/实例),所以它
//可用于所有事件处理程序
var i = 0;
video.addEventListener('loadeddata',function(){
video.currentTime = i;
},false)
video.addEventListener('seeked',function(){
//现在视频已经获取,当前帧将显示
//时间,如我们所期望的
generateThumbnail(i);
//捕获帧时,增加
i + = 5;
//如果我们未通过结束,寻找下一个间隔
if(i <= video.duration){
//这将触发另一个被寻找的事件
video.currentTime = i;
} else {
// DONE !, next action
}
},false);
video.addEventListener('loadeddata', function() {
var duration = video.duration;
var i = 0;
var interval = setInterval(function() {
video.currentTime = i;
generateThumbnail(i);
i = i+5;
if (i > duration) clearInterval(interval);
}, 300);
});
function generateThumbnail(i) {
//generate thumbnail URL data
var context = thecanvas.getContext('2d');
context.drawImage(video, 0, 0, 220, 150);
var dataURL = thecanvas.toDataURL();
//create img
var img = document.createElement('img');
img.setAttribute('src', dataURL);
//append img in container div
document.getElementById('thumbnailContainer').appendChild(img);
}
< video>
tag. video.currentTime = 5
, image of frame 0s is generated. Then the video frame jump to time 5s. So when video.currentTime = 10
, image of frame 5s is generated.Cause
currentTime
) is asynchronous.seeked
event or else it will take the actual current frame which is your old value.setInterval
as it is asynchronous too and you will not be able to properly synchronize when the next frame is seeked to. There is no need to use setInterval
as we will utilize the seeked
event instead which will keep everything is sync.Solution
seeked
event to go through the video to capture the correct frame as this event ensures us that we are actually at the frame we requested by setting the currentTime
property.// this must be global (or bound to a unique object/instance) so it
// is available for all event handlers
var i = 0;
video.addEventListener('loadeddata', function() {
video.currentTime = i;
}, false);
video.addEventListener('seeked', function() {
// now video has seeked and current frames will show
// at the time as we expect
generateThumbnail(i);
// when frame is captured, increase
i += 5;
// if we are not passed end, seek to next interval
if (i <= video.duration) {
// this will trigger another seeked event
video.currentTime = i;
} else {
// DONE!, next action
}
}, false);