【问题标题】:Get frame numbers in HTML5 Video获取 HTML5 视频中的帧数
【发布时间】:2014-07-18 14:52:39
【问题描述】:

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

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

我已将帧编号添加到 Adob​​e After Effects 的视频的每一帧,因此我可以获得更准确的差异信息。视频以 29.97fps 的速度运行,并且 requestAnimationFrame 也设置为以相同的速率增加数量,但我不确定这种差异来自哪里。

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

【问题讨论】:

标签: javascript html video requestanimationframe popcornjs


【解决方案1】:

我为此在 github 上找到了一些东西。 https://github.com/allensarkisyan/VideoFrame

我已经在这个小提琴中实现了它:https://jsfiddle.net/k0y8tp2v/

var currentFrame = $('#currentFrame');
var video = VideoFrame({
    id : 'video',
    frameRate: 25,
    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');
    }
});

编辑:更新了新视频的小提琴,使其再次工作。

编辑: 正如所指出的,视频是 25fps,所以我对其进行了更新,并且在我在那里的时候消除了对 jQuery 的依赖。
非jQuery版本:
https://jsfiddle.net/k0y8tp2v/1/

var currentFrame = document.getElementById('currentFrame');
var video = VideoFrame({
    id : 'video',
    frameRate: 25,
    callback : function(frame) {
        currentFrame.innerHTML = frame ;
    }
});

document.getElementById('play-pause').addEventListener('click', function(e){
    if(video.video.paused){
        video.video.play();
        video.listen('frame');
        e.target.innerHTML = 'Pause';
    }else{
        video.video.pause();
        video.stopListen();
        e.target.innerHTML = 'Play';
    }
});

【讨论】:

  • 有时视频停止时会关闭 1 帧,但可以通过在视频暂停/停止时再次设置帧号 html 来解决此问题
  • 似乎该库通过设置一个计时器来完成帧率跟踪,该计时器为关注者“按预期帧率两次”轮询它:)
  • frameRate 应该与视频中的实际匹配。将其设置为 100 不会影响播放速度,但会影响帧数。
  • @2pha 感谢您的提琴。当前视频(Big Buck Bunny)的帧速率是 25,而不是 29.97。当您更正时,它会给出更准确的帧号。
  • @Dipu Raj,啊,你是对的,我更新了小提琴和代码。哇,比 5 岁还差 2 天回答,仍然在帮助人们。它给我一种温暖的模糊感觉:)
【解决方案2】:

问题在于setTimeout 并不是真正可预测的,因此您无法确定每次函数运行时都显示了一个新帧。每次更新帧显示并将其乘以帧速率时,您都需要检查视频的currentTime

这是一个有效的示例:http://jsbin.com/xarekice/1/edit 它偏离了一帧,但看起来您可能在开头有两帧标记为“000000”。

您可能希望了解的有关视频元素的一些事项:

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

  2. currentTime 并不总是完全代表屏幕上的内容。有时它会提前一点,尤其是在寻找时(这就是为什么在我的 JSBin 中,我不会在您寻找时更新框架)。

我相信currentTime 在与实际视频绘图不同的线程上更新,所以它有点像它自己的时钟一样工作,一直在走。这是视频想要的位置,不一定是它的位置。所以你可以接近,但是你需要对帧计算的结果进行四舍五入,偶尔,你可能会偏离一帧。

【讨论】:

  • 非常感谢。
【解决方案3】:

从 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

【讨论】:

    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多