繁体   English   中英

在视频HTML5中获取帧更改

[英]Get frame change in video HTML5

我需要检测HTML 5中视频的所有帧更改,我尝试了以下代码,但我无法获得所有更改,只有我每秒可以获得8或9次更新..

<body>
    <canvas id="Canvas" width="800" height="450" style="position:absolute; left:5; top:5">Can't Load Canvas</canvas>
    <video id="videoPlay" muted controls>
        <source src="assets/soccer.webm" type="video/webm">
            <source src="assets/soccer.mp4" type="video/mp4">
            Your browser does not support the video tag.
    </video>
</body>
<script type="text/javascript">
            videoPlay.addEventListener('timeupdate', function (){
                putOverlay();
            });
            function putOverlay(){                  
                console.log(videoPlay.currentTime);
                console.log("another frame");
            }
    </script>
</html>

我也尝试了以下代码,但是随着时间的推移,使用定时器会导致帧与定时器给出的值之间失去同步。

<body>
        <canvas id="LeCanvas" width="800" height="450" style="position:absolute; left:5; top:5">Can't Load Canvas</canvas>
        <!-- Video -->
        <video id="videoPlay"  controls>
            <source src="assets/soccer.webm" type="video/webm">
            <source src="assets/soccer.mp4" type="video/mp4">
            Your browser does not support the video tag.
        </video>
    </body>
    <!-- Play Video-->  
    <script>
        //Play Damn Video
        var videoPlay = $('#videoPlay')[0];
        videoPlay.play(1);
    </script>
    <!-- Canvas Animation  -->
    <script>
        //Animation
        function animate() {
            console.log("frame change");
        }       
        setInterval(animate, 1000/29.97); 
    </script>

对我的问题有什么建议吗?

对不起我的英文

亚历克斯

如上面的评论所述, timeupdate每15-2550 timeupdate才会触发,实际上它似乎接近250毫秒。 它好像timeupdate旨在提供足够的精度,以显示currentTime每一秒。 所以你最好的选择是运行一个以你想要的速度运行的计时器,并在每次迭代时查询currentTime

但是,您应该使用requestAnimationFrame ,而不是使用setInterval甚至setTimeout 这将大约每16毫秒(60fps)运行,但它将与视频卡刷新率同步。 如果使用setTimeout ,您可能会在某些设备上看到闪烁或屏幕撕裂,尤其是移动设备。 它还允许浏览器在选项卡不可见时节省帧速率,以节省CPU周期(因此节省电池使用量)。

它也比setInterval好,因为如果由于某种原因你的渲染代码花费的时间超过了你所分配的30或16ms, setInterval可能会堆积调用并导致计时问题,但requestAnimationFrame将跳过帧以使你回到正轨。

假设您已经使用了上面的polyfill,代码看起来像这样:

var video = document.getElementById('videoPlay'),
    lastTime = -1;
function draw() {
    var time = video.currentTime;
    if (time !== lastTime) {
        console.log('time: ' + time);
        //todo: do your rendering here
        lastTime = time;
    }

    //wait approximately 16ms and run again
    requestAnimationFrame(draw);
}

draw();

上面的代码检查时间,以确保您不会连续两次绘制相同的帧。 真的不需要它,但它会节省你几个CPU周期。 但是当将视频绘制到画布时,该帧比currentTime报告的帧落后几毫秒。 因此,如果您暂停视频然后跳过,您几乎肯定会落后一帧。 通常情况下,如果currentTime在我上一次抽奖后没有改变,但是视频暂停了,我会继续画每个周期半秒钟左右。 或者你可以花点时间退房。

暂无
暂无

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

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