在HTML5视频中获取帧编号

时间:2014-07-18 14:52:40

标签: javascript html5 video requestanimationframe popcornjs

我正在尝试捕获视频的每个帧编号,但看起来似乎没有办法实现它。所以我开始使用自己的时钟来匹配视频的帧数,但它们从不匹配,随着视频的进展,差异也在不断增加。

请看看我的垃圾箱。 http://jsbin.com/dopuvo/4/edit

我已经在Adobe After Effects的视频的每一帧中添加了帧编号,因此我可以获得更准确的差异信息。视频以29.97fps运行,requestAnimationFrame也设置为以相同的速率增加数量,但我不确定这种差异来自何处。

有时他们匹配,有时他们不匹配。我也尝试离线,但我得到相同的结果。任何帮助。

3 个答案:

答案 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”的帧。

您可能想要了解的有关视频元素的一些内容:

  1. 正如您似乎发现的那样,没有可靠的方法来确定帧速率,因此您必须在其他地方发现它并对其进行硬编码。 video metrics有一些有趣的事情,但它们是非标准的,没有得到广泛支持,而且根据我的经验,在确定实际帧速率时完全无效。

  2. currentTime并不总是完全代表屏幕上的内容。有时它会领先一点,特别是在寻找时(这就是为什么在我的JSBin中,我不会在你寻找的时候更新框架。)

  3. 我相信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