获取视频 HTML5 中的帧变化
Posted
技术标签:
【中文标题】获取视频 HTML5 中的帧变化【英文标题】:Get frame change in video HTML5 【发布时间】:2013-06-07 07:55:00 【问题描述】:我需要检测 html 5 中视频的所有帧变化,我尝试了以下代码,但我无法获得所有变化,我每秒只能获得 8 或 9 次更新..
<body>
<canvas id="Canvas" 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" 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>
对我的问题有什么建议吗?
对不起我的英语
问候 亚历克斯
【问题讨论】:
信息可能不再是 100% 最新的,但请参阅 How often does the timeupdate event fire for an html5 video?,并查看链接的 Bugzilla 页面。 根据 HTML5 规范,浏览器必须每隔 15 到 250 毫秒触发一次 timeupdate 事件——但这与您的帧数无关。 setInterval 不会同步 1 到 1。如果您绝对需要帧精度,您可以尝试尽可能快地运行 setInterval。请注意,登录到控制台可能会减慢速度,具体取决于浏览器。 这就是我对我的第二个代码所做的事情。问题是,随着时间的推移,差异会越来越大.. 【参考方案1】:如上面的 cmets 所述,timeupdate
仅每 15-250 毫秒触发一次,实际上它似乎更接近 250 毫秒。似乎timeupdate
旨在提供足够的精度以每秒显示currentTime
。因此,您最好的选择是运行一个以您想要的速率运行的计时器,并在每次迭代时查询 currentTime
。
但是,您应该使用requestAnimationFrame,而不是使用setInterval
甚至setTimeout
。这将大约每 16 毫秒 (60fps) 运行一次,但它会与视频卡刷新率同步。如果您使用setTimeout
,您可能会在某些设备上看到闪烁或屏幕撕裂,尤其是移动设备。它还允许浏览器在选项卡不可见时限制帧速率,以节省 CPU 周期(从而节省电池使用量)。
它也比setInterval
好,因为如果由于某种原因您的渲染代码花费的时间超过了您分配的 30 或 16 毫秒,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 没有改变但视频已暂停,我将在每个周期再绘制半秒左右。或者你可以花时间检查一下。
【讨论】:
以上是关于获取视频 HTML5 中的帧变化的主要内容,如果未能解决你的问题,请参考以下文章