Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在HTML5视频中获取帧编号_Javascript_Html_Video_Requestanimationframe_Popcornjs - Fatal编程技术网

Javascript 在HTML5视频中获取帧编号

Javascript 在HTML5视频中获取帧编号,javascript,html,video,requestanimationframe,popcornjs,Javascript,Html,Video,Requestanimationframe,Popcornjs,我试图捕捉视频的每一帧编号,但似乎没有办法实现它。所以我启动了我自己的时钟来匹配视频的帧数,但它们从不匹配,而且随着视频的进展,差异不断增加 请看一下我的垃圾箱 我在AdobeAfter Effect视频的每一帧中都添加了帧数,这样我就有了更准确的差异信息。视频以29.97fps的速度运行,requestAnimationFrame也设置为以相同的速率增加该数字,但是我不确定这种差异来自何处 有时他们匹配,有时不匹配。我也尝试过离线操作,但得到了相同的结果。任何帮助。我在github上找到了有关

我试图捕捉视频的每一帧编号,但似乎没有办法实现它。所以我启动了我自己的时钟来匹配视频的帧数,但它们从不匹配,而且随着视频的进展,差异不断增加

请看一下我的垃圾箱

我在AdobeAfter Effect视频的每一帧中都添加了帧数,这样我就有了更准确的差异信息。视频以29.97fps的速度运行,requestAnimationFrame也设置为以相同的速率增加该数字,但是我不确定这种差异来自何处


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

我在github上找到了有关此的内容

我在这把小提琴中实现了它:

编辑:将小提琴更新为新视频,使其再次工作

编辑:如前所述,视频速度为25fps,因此我对其进行了更新,并在那里消除了对jQuery的依赖。
非jQuery版本:


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

这里有一个工作示例:它关闭了一帧,但看起来您可能在开头有两帧标记为“000000”

关于视频元素,您可能需要注意以下几点:

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

  • currentTime
    并不总是完全代表屏幕上的内容。有时它会向前一点,特别是在搜索时(这就是为什么在我的JSBin中,我不会在搜索时更新帧)


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

    从M83开始,Chromium有一个requestVideoFrameCallback()API,它可能会解决您的问题。 您可以使用mediaTime获得一致的时间戳,如中所述。从那里,您可以尝试以下内容:

    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
    count中的不连续性中检测到)。您也可能在捕获帧时稍晚(通常为16ms,或者比视频帧可用时晚一次调用
    window.requestAnimationFrame()


    如果您对API的高级概述感兴趣,或者您可以看看。

    谢谢Samuel,是的,事实上这是我遵循的解决方案,但我需要随着视频的发展不断获取帧编号。我也尝试过不舍入总帧数,但没有运气。可能(如果你控制它正在绘制的画布)会在那里保留一个计数器:虽然从我的角度看这也像是黑暗魔法LOL,请看,有时视频停止时,它也会间隔1帧,但这可能是通过在视频暂停/停止时再次设置帧号html来解决的。看起来该库通过设置一个计时器来完成帧速率跟踪,该计时器为跟随者“每个预期帧速率轮询两次:)
    framerate
    应该与视频中的实际帧速率匹配。将其设置为100不会影响播放速度,但会影响帧计数。@2pha感谢您的小提琴。当前视频(大公兔)的帧率是25,而不是29.97。当你纠正它是给一个更准确的帧编号。@Dipu Raj,啊,你是正确的,我更新了小提琴和代码。哇,回答距离5岁还有2天,仍然在帮助人们。它给我一种温暖而模糊的感觉:)谢谢,真是太好了。
    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';
        }
    });
    
    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)