我正在寻找一种逐帧查看HTML5 <video>
的方法。
场景:有一个视频,有一个额外的按钮,按下时会跳到下一帧。
您认为最好的方法是什么?
timeUpdate
event, which on FireFox is called for every frame,然后暂停视频。但是,其他浏览器的行为与Firefox不同。currentTime
元素更改为+1/24秒,其中“24”是帧速率。但是,我不知道如何获取FPS。我找到了this very useful HTML5 test page,它可以跟踪所有浏览器实现精确寻帧的能力。
答案 0 :(得分:27)
似乎大多数浏览器都允许使用第二种方法,尽管您需要知道帧速率。然而,Opera是例外,需要一种类似于你的第一种方法(结果并不完美)。这是一个使用29.97帧/秒视频(美国电视标准)的demo page I came up with。请注意,它尚未经过广泛测试,因此可能无法在IE 9,Firefox 4或任何浏览器的未来版本中使用。
HTML:
<p id="time"></p>
<video id="v0" controls tabindex="0" autobuffer preload>
<source type="video/webm; codecs="vp8, vorbis"" src="http://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.webm"></source>
<source type="video/ogg; codecs="theora, vorbis"" src="http://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.ogv"></source>
<source type="video/mp4; codecs="avc1.42E01E, mp4a.40.2"" src="http://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.mp4"></source>
<p>Sorry, your browser does not support the <video> element.</p>
</video>
JavaScript(在页面加载时运行并为了简洁起见使用jQuery 1.4.4):
var vid = $('#v0')[0];
vid.onplay = vid.onclick = function() {
vid.onplay = vid.onclick = null;
setTimeout(function() {
vid.pause();
setInterval(function() {
if($.browser.opera) {
var oldHandler = vid.onplay;
vid.onplay = function() {
vid.pause();
vid.onplay = oldHandler;
};
vid.play();
} else {
vid.currentTime += (1 / 29.97);
}
}, 2000);
}, 12000);
setInterval(function() {
$('#time').html((vid.currentTime * 29.97).toPrecision(5));
}, 100);
};
答案 1 :(得分:7)
刚刚解决了同样的问题,我采用蛮力方法来找到帧速率。知道帧速率永远不会超过60帧,我会以1/60秒的步长搜索视频。通过将视频放到canvas元素上然后使用getImageData获取像素数据,将每个帧与最后一帧进行比较。我在一秒钟的视频中执行此操作,然后计算唯一帧的总数以获得帧速率。
您无需检查每个像素。我抓住视频内部的大约2 / 3rds,然后检查每个第8个像素的横向和向下(取决于大小)。你可以用一个不同的像素来停止比较,这样这个方法相当快速可靠,与读取frameRate属性相比,不如猜测。
答案 2 :(得分:1)
在标准得到确认和实施(这将是年龄!)之前,您可以做的最好的事情就是猜测帧速率和那个时间的增量。除非你处于受控环境中,否则我建议不要严重依赖HTML5 ......尽管我喜欢它的功能,但它不会得到可靠的支持。
答案 3 :(得分:1)
这是我用来查找没有控件的视频的小 keyPress
处理程序。
如果视频是 paused
,它会按帧跳过。
const video = document.querySelector('#yourVideo')
const expectedFramerate = 60 // yourVideo's framerate
function handleKey(ev) {
let d = 0;
switch (ev.key) {
case ",": d = -5; break; // normal
case ".": d = +5; break;
case "?": d = -10; break; // shift
case ":": d = +10; break;
case "<": d = -2; break; // rightAlt
case ">": d = +2; break;
case " ": togglePlayback(); break;
}
if (d) {
if (video.paused) video.currentTime += Math.sign(d) * 1/expectedFramerate
else video.currentTime += d
}
}
document.onkeypress = handleKey
function togglePlayback() {
video.paused
? video.play()
: video.pause()
}
请注意,您可以轻松添加键绑定来动态增加/减少/切换 expectedFramerate
以满足您的需要。