如何确定 html 视频元素上的预期 frame-rate
How to determine the intended frame-rate on an html video element
有没有办法确定 html 视频元素中播放内容的预期帧速率?
视频元素是否知道预期的 FPS 或帧数,或者只是 "guess"(可能是 24fps)并以猜测的速度播放?
以下是我未成功的尝试:
在视频元素本身上寻找 FPS 或 FrameCount 属性——不!
查找有关 FPS 或 FrameCount 的 cross-video-format header 信息——没有一致的信息!
寻找帧变化时触发的事件--不!
我的下一次尝试更复杂:通过将帧捕获到 canvas 元素来对视频进行采样,并通过确定像素何时发生变化来计算帧数。
在我进行复杂的尝试之前,有没有人有更简单的答案?
了解视频的帧率并没有您想象的那么有用。
浏览器使用一些技巧来匹配电影的帧率和屏幕的刷新率,所以如果你查看 currentTime
属性,你会看到 actual 帧持续时间(== currentTime
- 之前的 currentTime
)不是一个常数,它因帧而异。
在此示例视频中:http://jsfiddle.net/3qs46n4z/3/ 模式为:
4-1-5-1 :
21.3 时 4 帧 + 32 时 1 帧 + 21.3 时 5 帧 + 32 时 1 帧。
因此,如果您想始终在 canvas 上显示最新帧同时避免透支,解决方案可能是:
- 在每个 rAF 上,查看视频的当前时间:
• 相同的 ? -> 什么也不做。
• 改变了吗? -> 更新框架。
无论您想做什么,比较两个 currentTime === 两个数字可能比比较两个 imageData 更快;-)
编辑:查看规范以找到我所说的证据,我发现了这个注释的细微差别:
Which frame in a video stream corresponds to a particular playback position is defined by the video stream's format.
(4.8.6 注释 http://www.w3.org/TR/2011/WD-html5-20110113/video.html )
严格来说只能说(当前时间相同)表示(帧相同)
我只能打赌倒数是真的=>不同的时间意味着不同的帧。
在上面的示例中,Chrome 试图通过尝试获得 45 Hz ( = 60 / 2 + 60 / 4) 来匹配我 60Hz 计算机上电影的 24Hz,最接近 48 = 2*24。
对于创建的 21 个帧,我不知道它是插值还是只是复制帧。它肯定会根据 browser/device(尤其是 Gpu)而改变。我敢打赌任何最新的台式机或功能强大的智能手机都会进行插值。
无论如何,鉴于检查 imageData 的成本很高,您最好绘制两次而不是检查。
Rq1:我想知道在多大程度上使用 Xor 模式 + 一次针对 0 32 位进行测试可以缩短比较时间。 (getImageData 慢。)
Rq2:我确定有一种 hacky 方法可以使用 'sync' 视频和显示器的播放速率,并知道哪一帧是真正的(== 未插值)帧。 (所以两个通过这里 1)同步 2)倒带和检索帧)。
Rq3 :如果您的目的是获取每个视频帧 并且仅获取 视频帧,则浏览器不是最佳选择。如上所述,(桌面)浏览器会进行插值以尽可能接近显示帧速率。这些帧在原始流中 而不是 。甚至还有一些高端“3D”(2D+时间)插值设备,其中甚至不打算显示初始帧(!)。
另一方面,如果您对(插值的)输出流没问题,则对 rAF 的轮询将提供您看到的 每个 帧(您不会错过任何一帧(显然您的应用程序除外)正忙着做别的事情)。
Rq4:插值(== 无重复帧)在 recent/decent GPU 驱动的桌面上的可能性为 99.99%。
Rq5:确保预热您的函数(在启动时调用它们 100 次)并且不创建垃圾以避免 jit / gc 暂停。
这是我用来计算视频 fps 的代码。它有时确实有±1的误差。
function getframerat(){
document.getElementsByClassName("vid-info")[0].textContent = "Calculating..."
//first timeout is your choise, you can replace this timeout with any other conditional checks.
//Just make sure video is playing, that's the important part.
setTimeout(function(){
let getframerates = document.getElementsByClassName("video")[0].getVideoPlaybackQuality().totalVideoFrames
setTimeout(function(){
getframerates = document.getElementsByClassName("video")[0].getVideoPlaybackQuality().totalVideoFrames - getframerates;
if(getframerates < 11) getframerat()
else if(getframerates%2 != 0) getframerat()
else document.getElementsByClassName("vid-info")[0].textContent = getframerates;
},1000)
},1000)
}
有没有办法确定 html 视频元素中播放内容的预期帧速率?
视频元素是否知道预期的 FPS 或帧数,或者只是 "guess"(可能是 24fps)并以猜测的速度播放?
以下是我未成功的尝试:
在视频元素本身上寻找 FPS 或 FrameCount 属性——不!
查找有关 FPS 或 FrameCount 的 cross-video-format header 信息——没有一致的信息!
寻找帧变化时触发的事件--不!
我的下一次尝试更复杂:通过将帧捕获到 canvas 元素来对视频进行采样,并通过确定像素何时发生变化来计算帧数。
在我进行复杂的尝试之前,有没有人有更简单的答案?
了解视频的帧率并没有您想象的那么有用。
浏览器使用一些技巧来匹配电影的帧率和屏幕的刷新率,所以如果你查看 currentTime
属性,你会看到 actual 帧持续时间(== currentTime
- 之前的 currentTime
)不是一个常数,它因帧而异。
在此示例视频中:http://jsfiddle.net/3qs46n4z/3/ 模式为:
4-1-5-1 :
21.3 时 4 帧 + 32 时 1 帧 + 21.3 时 5 帧 + 32 时 1 帧。
因此,如果您想始终在 canvas 上显示最新帧同时避免透支,解决方案可能是:
- 在每个 rAF 上,查看视频的当前时间:
• 相同的 ? -> 什么也不做。
• 改变了吗? -> 更新框架。
无论您想做什么,比较两个 currentTime === 两个数字可能比比较两个 imageData 更快;-)
编辑:查看规范以找到我所说的证据,我发现了这个注释的细微差别:
Which frame in a video stream corresponds to a particular playback position is defined by the video stream's format.
(4.8.6 注释 http://www.w3.org/TR/2011/WD-html5-20110113/video.html )
严格来说只能说(当前时间相同)表示(帧相同)
我只能打赌倒数是真的=>不同的时间意味着不同的帧。
在上面的示例中,Chrome 试图通过尝试获得 45 Hz ( = 60 / 2 + 60 / 4) 来匹配我 60Hz 计算机上电影的 24Hz,最接近 48 = 2*24。
对于创建的 21 个帧,我不知道它是插值还是只是复制帧。它肯定会根据 browser/device(尤其是 Gpu)而改变。我敢打赌任何最新的台式机或功能强大的智能手机都会进行插值。
无论如何,鉴于检查 imageData 的成本很高,您最好绘制两次而不是检查。
Rq1:我想知道在多大程度上使用 Xor 模式 + 一次针对 0 32 位进行测试可以缩短比较时间。 (getImageData 慢。)
Rq2:我确定有一种 hacky 方法可以使用 'sync' 视频和显示器的播放速率,并知道哪一帧是真正的(== 未插值)帧。 (所以两个通过这里 1)同步 2)倒带和检索帧)。
Rq3 :如果您的目的是获取每个视频帧 并且仅获取 视频帧,则浏览器不是最佳选择。如上所述,(桌面)浏览器会进行插值以尽可能接近显示帧速率。这些帧在原始流中 而不是 。甚至还有一些高端“3D”(2D+时间)插值设备,其中甚至不打算显示初始帧(!)。 另一方面,如果您对(插值的)输出流没问题,则对 rAF 的轮询将提供您看到的 每个 帧(您不会错过任何一帧(显然您的应用程序除外)正忙着做别的事情)。
Rq4:插值(== 无重复帧)在 recent/decent GPU 驱动的桌面上的可能性为 99.99%。
Rq5:确保预热您的函数(在启动时调用它们 100 次)并且不创建垃圾以避免 jit / gc 暂停。
这是我用来计算视频 fps 的代码。它有时确实有±1的误差。
function getframerat(){
document.getElementsByClassName("vid-info")[0].textContent = "Calculating..."
//first timeout is your choise, you can replace this timeout with any other conditional checks.
//Just make sure video is playing, that's the important part.
setTimeout(function(){
let getframerates = document.getElementsByClassName("video")[0].getVideoPlaybackQuality().totalVideoFrames
setTimeout(function(){
getframerates = document.getElementsByClassName("video")[0].getVideoPlaybackQuality().totalVideoFrames - getframerates;
if(getframerates < 11) getframerat()
else if(getframerates%2 != 0) getframerat()
else document.getElementsByClassName("vid-info")[0].textContent = getframerates;
},1000)
},1000)
}