繁体   English   中英

获取 HTML5 视频中的帧数

[英]Get frame numbers in HTML5 Video

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

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

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

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

为此,我在 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';
    }
});

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

这是一个工作示例: http : //jsbin.com/xarekice/1/edit它已关闭一帧,但看起来您可能在开头有两帧标记为“000000”。

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

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

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

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

从 M83 开始,Chromium 有一个 requestVideoFrameCallback() API,它可能会解决您的问题。 您可以使用 mediaTime 获得一致的时间戳,如此 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 的高级概述感兴趣,请参阅博客文章,或者您可以查看API 的官方 github

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM