使用 HTML5 和 JavaScript 从视频中捕获帧
Posted
技术标签:
【中文标题】使用 HTML5 和 JavaScript 从视频中捕获帧【英文标题】:Capture frames from video with HTML5 and JavaScript 【发布时间】:2013-10-11 02:16:35 【问题描述】:我想每 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)
//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);
我遇到的问题是第一个生成的两个图像是相同的,并且没有生成持续时间为 5 秒的图像。我发现缩略图是在特定时间的视频帧显示在< video>
标签之前生成的。
例如video.currentTime = 5
时,生成帧0s的图像。然后视频帧跳转到时间 5s。所以当video.currentTime = 10
时,会生成第5s帧的图像。
【问题讨论】:
generateThumbnail 函数中的 Canvas 是什么?您能否为这个问题提供更有用的 html 标签?我正在尝试做同样的事情,但我不确定应该如何在页面上声明 theCanvas。谢谢! 嗨,林,你问的这个问题还有源代码吗?可以给个链接吗? 【参考方案1】:原因
问题在于寻找视频(通过设置为currentTime
)是异步的。
您需要收听seeked
事件,否则它会冒着获取可能是您的旧值的实际当前帧的风险。
由于它是异步的,因此您必须不要使用setInterval()
,因为它也是异步的,并且在寻找下一帧时您将无法正确同步。无需使用setInterval()
,因为我们将使用seeked
事件来代替,这将保持一切同步。
解决方案
通过稍微重写代码,您可以使用seeked
事件来遍历视频以捕获正确的帧,因为此事件通过设置currentTime
属性确保我们实际上处于我们请求的帧.
示例
// global or parent scope of handlers
var video = document.getElementById("video"); // added for clarity: this is needed
var i = 0;
video.addEventListener('loadeddata', function()
this.currentTime = i;
);
将此事件处理程序添加到聚会中:
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 here by 5 seconds
i += 5;
// if we are not past end, seek to next interval
if (i <= this.duration)
// this will trigger another seeked event
this.currentTime = i;
else
// Done!, next action
);
【讨论】:
我尝试使用您的代码。现在我有另一个问题。由于被搜索,当我通过点击时间轴搜索视频时,图像也会生成。但我不想那样。 编辑我已经解决了这个问题。谢谢。video.currentTime = i;
不会为我触发任何搜索的事件。
@Matian2040 不,很遗憾
哦,您实际上可以比较帧并确保它们不同,然后再显示“新帧”。这是一个线索。 developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/…
@Matian2040 当然,一个简单的方法是使用“差异”混合结合饱和过滤器(0%)和计数像素> 0。使用基于百分比的阈值以避免过多的噪声/压缩影响。总是有误报的机会,但如果这是一个目标,它可以减少不同拇指的数量(或根据目的使用更长的间隔)。以上是关于使用 HTML5 和 JavaScript 从视频中捕获帧的主要内容,如果未能解决你的问题,请参考以下文章