javascript 如何确定 html 视频元素的预期帧速率

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28420724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 08:57:09  来源:igfitidea点击:

How to determine the intended frame-rate on an html video element

javascripthtmlvideocanvas

提问by markE

Is there a way to determine the intended frame rate of content playing in the html video element?

有没有办法确定在 html 视频元素中播放的内容的预期帧速率?

Does the video element even know the intended FPS or frame count, or does it simply "guess" (maybe 24fps) and play at the guessed speed?

视频元素甚至知道预期的 FPS 或帧数,还是只是“猜测”(可能是 24fps)并以猜测的速度播放?

Here are my unsuccessful attempts:

以下是我失败的尝试:

  • Look for a FPS or FrameCount property on the video element itself--Nope!

  • Look for cross-video-format header info about FPS or FrameCount--Nothing consistent!

  • Look for an event that is triggered upon frame changing--Nope!

  • 在视频元素本身上查找 FPS 或 FrameCount 属性——不!

  • 查找有关 FPS 或 FrameCount 的跨视频格式标头信息——没有一致的!

  • 寻找在帧改变时触发的事件——不!

My next attempt is more complicated: Sample the video by capturing frames to a canvas element and count frames by determining when the pixels change.

我的下一次尝试更复杂:通过将帧捕获到画布元素来对视频进行采样,并通过确定像素何时发生变化来计算帧数。

Does anyone have a simpler answer before I do the complicated attempt?

在我进行复杂的尝试之前,有人有更简单的答案吗?

回答by GameAlchemist

Knowing the frame-rate of the video wouldn't be as useful as you might think.
Browsers uses of some tricks to make a match between the frame-rate of the movie and the refresh-rate of the screen, so if you look at currentTimeproperty, you'll see that the actualframe duration ( == currentTime- previous currentTime) is not a constant, it varies from frame to frame.

了解视频的帧速率并不像您想象的那么有用。
浏览器使用一些技巧来匹配电影的帧率和屏幕的刷新率,所以如果你查看currentTime属性,你会看到实际的帧持续时间(== currentTime- 前一个currentTime)不是一个常数,它因帧而异。

On this sample video : http://jsfiddle.net/3qs46n4z/3/the pattern is :
4-1-5-1 :
4 frames at 21.3 + 1 frame at 32 + 5 frames at 21.3 + 1 frame at 32.

在此示例视频中:http: //jsfiddle.net/3qs46n4z/3/模式为:
4-1-5-1:
21.3 时的 4 帧 + 32 时的 1 帧 + 21.3 时的 5 帧 + 32 时的 1 帧。

So if you want to always display the latest frame on a canvas while avoiding overdraw, the solution might be to :
- On each rAF, look at the current time of the video :
? Same ? -> do nothing.
? Changed ? -> update frame.

因此,如果您希望在避免过度绘制的同时始终在画布上显示最新帧,则解决方案可能是:
- 在每个 rAF 上,查看视频的当前时间:
?相同的 ?-> 什么都不做。
? 变了?-> 更新框架。

And whatever you want to do, comparing two currentTime === two numbers might be faster than comparing two imageDatas ;-)

不管你想做什么,比较两个 currentTime === 两个数字可能比比较两个 imageDatas 更快;-)

Edit : looking into the specifications to find evidence of my saying, i found a nuance with this Note :

编辑:查看规范以找到我所说的证据,我发现此注释有细微差别:

 Which frame in a video stream corresponds to a particular playback position is defined by the video stream's format.

(Note of 4.8.6 at http://www.w3.org/TR/2011/WD-html5-20110113/video.html)

http://www.w3.org/TR/2011/WD-html5-20110113/video.html 上的 4.8.6 注释)

So strictly saying we can only say that (the current time is the same) implies (the frames are identical).
I can only bet that the reciprocal is true => different time means different frame.
In the example above, Chrome is trying to match the 24Hz of the movie on my 60Hz computer by trying to get 45 Hz ( = 60 / 2 + 60 / 4), the nearest from 48 = 2*24. For the 21 created frames i don't know if it interpolates or merely duplicates the frames. It surely changes depending on browser/device (Gpu especially). I bet any recent desktop or powerful smartphone does interpolate.

所以严格地说我们只能说(当前时间相同)暗示(帧相同)。
我只能打赌倒数是正确的 => 不同的时间意味着不同的框架。
在上面的示例中,Chrome 试图通过尝试获得 45 Hz (= 60 / 2 + 60 / 4) 来匹配我 60Hz 计算机上电影的 24Hz,最接近 48 = 2*24。对于创建的 21 个帧,我不知道它是插入帧还是仅复制帧。它肯定会根据浏览器/设备(尤其是 Gpu)而变化。我敢打赌,任何最近的台式机或功能强大的智能手机都可以进行插值。

Anyway given the high cost of checking with the imageData, you'd much better draw twice than check.

无论如何,考虑到使用 imageData 进行检查的成本很高,您最好绘制两次而不是检查。

Rq1 : I wonder to which extent using Xor mode + testing against 0 32 bits at a time could boost the compare time. (getImageData isslow.)

Rq1:我想知道在多大程度上使用 Xor 模式 + 一次对 0 32 位进行测试可以提高比较时间。(getImageData慢。)

Rq2 : I'm sure there's a hacky way to use the playback rate to 'sync' the video and the display, and to know which frame is a genuine ( == not interpolated ) frame. ( so two pass here 1) sync 2) rewind and retrieve frames).

Rq2:我确信有一种使用播放速率来“同步”视频和显示,并知道哪一帧是真正的(== 未插值)帧的hacky 方法。(所以两个通过这里 1)同步 2)倒带和检索帧)。

Rq3 : If your purpose is to get each and every video frame and onlythe video's frame, a browser is not the way to go. As explained above, the (desktop) browsers do interpolate to match as closely as possible the display frame rate. Those frames were notin the original stream. There are even some high-end '3D' (2D+time) interpolation devices where the initial frames are not even meant to be displayed (! ). On the other hand, if you are okay with the (interpolated) output stream, polling on rAF will provide everyframes that you see (you can't miss a frame (except obviously your app is busy doing something else) .

Rq3 :如果您的目的是获取每个视频帧并且仅获取视频帧,则浏览器不是最佳选择。如上所述,(桌面)浏览器确实会进行插值以尽可能匹配显示帧速率。这些帧不在原始流中。甚至还有一些高端的“3D”(2D+时间)插值设备,其中甚至不打算显示初始帧(!)。另一方面,如果您对(内插的)输出流没问题,则轮询 rAF 将提供您看到的每一帧(您不能错过任何帧(除非您的应用程序显然正在忙于做其他事情)。

Rq4 : interpolation ( == no duplicate frames ) is 99.99% likely on recent/decent GPU powered desktop.

Rq4:插值(== 无重复帧)在最近/不错的 GPU 驱动的桌面上的可能性为 99.99%。

Rq5 : Be sure to warm your functions (call them 100 times on start) and to create no garbage to avoid jit / gc pauses.

Rq5:确保预热您的函数(在启动时调用它们 100 次)并且不创建垃圾以避免 jit/gc 暂停。