我正在尝试捕获视频的每个帧编号,但看起来似乎没有办法实现它。所以我开始使用自己的时钟来匹配视频的帧数,但它们从不匹配,随着视频的进展,差异也在不断增加。
请看看我的垃圾箱。 http://jsbin.com/dopuvo/4/edit
我已经在Adobe After Effects的视频的每一帧中添加了帧编号,因此我可以获得更准确的差异信息。视频以29.97fps运行,requestAnimationFrame也设置为以相同的速率增加数量,但我不确定这种差异来自何处。
有时他们匹配,有时他们不匹配。我也尝试离线,但我得到相同的结果。任何帮助。
答案 0 :(得分:13)
我在github上找到了一些东西。 https://github.com/allensarkisyan/VideoFrame
我已经在这个小提琴中实现了它:http://jsfiddle.net/Ck6Zq/184/
var currentFrame = $('#currentFrame');
var video = VideoFrame({
id : 'video',
frameRate: 29.97,
callback : function(frame) {
currentFrame.html(frame);
}
});
$('#play-pause').click(function(){
if(video.video.paused){
video.video.play();
video.listen('frame');
$(this).html('Pause');
}else{
video.video.pause();
video.stopListen();
$(this).html('Play');
}
});
编辑:更新了新视频,以便再次运行。
答案 1 :(得分:7)
问题是setTimeout
实际上不可预测,所以每次运行函数时都无法确定是否显示了一个新帧。每次更新帧显示时都需要检查视频的currentTime
,然后将其乘以帧速率。
这是一个有效的例子:http://jsbin.com/xarekice/1/edit它关闭一帧,但看起来你可能在开头有两个标记为“000000”的帧。
您可能想要了解的有关视频元素的一些内容:
正如您似乎发现的那样,没有可靠的方法来确定帧速率,因此您必须在其他地方发现它并对其进行硬编码。 video metrics有一些有趣的事情,但它们是非标准的,没有得到广泛支持,而且根据我的经验,在确定实际帧速率时完全无效。
currentTime
并不总是完全代表屏幕上的内容。有时它会领先一点,特别是在寻找时(这就是为什么在我的JSBin中,我不会在你寻找的时候更新框架。)
我相信currentTime
在实际视频绘制的单独线程上更新,所以它有点像它自己的时钟一样继续前进。这是视频想要的地方,而不一定是它的位置。所以你可以靠近,但是你需要对帧计算的结果进行舍入,偶尔,你可能会偏离一帧。
答案 2 :(得分:4)
从M83开始,Chromium具有requestVideoFrameCallback()API,这可能会解决您的问题。 您可以使用mediaTime获得一致的时间戳,如this Github issue所述。从那里,您可以尝试这样的事情:
var frameCounter = (time, metadata) => {
let count = metadata.mediaTime * frameRate;
console.log("Got frame: " + Math.round(count));
// Capture code here.
video.requestVideoFrameCallback(frameCounter);
}
video.requestVideoFrameCallback(frameCounter)
这只会在新帧上触发,但是您可能偶尔会错过其中一个(您可以从metadata.presentedFrames
计数的不连续中检测到)。捕获帧也可能会稍晚一些(通常是16毫秒,或者比视频帧可用时晚打一次window.requestAnimationFrame()
)。
如果您对API的高级概述感兴趣,here's a blogpost,或者可以看看API's offical github。