Html5 视频帧准确
Html5 Video frame accurate
我正在尝试将 html5 视频标签源元素设为 return 准确的帧编号。
Whosebug answers.
附近的东西
我的目标是显示准确的时间码。
我一直在看 VideoFrame and many others, but none of them are accurate. If you play a video containing burned-in timecode or frame count, like the one I'm using video_keyframes12_24p_Mbits1.8.mp4 我自己做的。你最终会看到一帧。
有人对此有什么提示吗?
非常感谢!
问题
不幸的是没有帧 API 供我们使用 - Firefox has some experimental features,但除此之外我们只能处理时间以及浏览器如何处理帧解码作为帧速率转换。请参阅下面的更新。
例如,浏览器可能会或可能总是 convert/normalize 到 30 fps,如果是这样可能会或可能不会假定掉帧(对于 29.97/59.94 fps/NTSC)。随着时间的推移,这将影响帧数并最终显示为偏移量,因为时间和帧数之间没有真正的 link。
此外,由于基于整数的转换以及视频中的起始位置,可能存在舍入误差。根据浏览器的不同,视频在引擎盖下的解码方式也有不同的解决方案,例如,Chrome 在底层使用 FFMpeg,Firefox 使用 OS* 中可用的任何内容(对于 MP4 编码的视频)和等等。
可能的解决方案
(更新: 忘了说-) 还有就是Media Source Extensions API which support the VideoPlaybackQuality
object。目前 Chrome 和 IE(Windows 8+)以及 Firefox [支持]。
直接在HTMLVideoElement上调用即可使用:
var q = video.getVideoPlaybackQuality();
然后使用其属性读出值:
var frames = q.totalVideoFrames;
请注意,无论实际播放位置如何,此值可能会累积所有帧。您也许可以直接使用 MSE 来解决这个问题。设置和处理有点繁琐,但 this link 提供了一个很好的起点,以防您不熟悉 MSE。
另一种想法是在视频中编码一个特殊的条形码,然后使用 canvas 读取它。这在实际的 SMPTE 时间码上是等效的,但这将需要在视频中某种程度上可见的叠加层(就像将电文编码到视频的过扫描区域的旧方法一样)。如果视频是全帧,则会出现其他问题,例如根据用于编码的颜色(或为其制作纯色背景)进行错误检测。
*) 可能在 Cisco 免费发布他们的 mp4 解决方案后在最近的版本中发生了变化。
我在你引用的 link 上发布了这个答案,但我认为它也可能与这里相关:
从 M83 开始,Chromium 有一个 requestVideoFrameCallback() API,它可能会解决您的问题。
您可以使用 mediaTime 获得一致的时间戳,如 this Github issue 中所述。从那里,你可以尝试这样的事情:
var frameCounter = (time, metadata) => {
let count = metadata.mediaTime * frameRate;
console.log("Got frame: " + Math.round(count));
// Display timecode code here.
video.requestVideoFrameCallback(frameCounter);
}
video.requestVideoFrameCallback(frameCounter)
这只会在新帧上触发,但您有时可能会错过一帧(您可以从 metadata.presentedFrames
计数的不连续性中检测到)。您捕获帧的时间也可能稍晚(通常是 16 毫秒,或者比视频帧可用时晚调用 window.requestAnimationFrame()
一次)。
如果您对 API、here's a blogpost, or you can take a look at the API's offical github 的高级概述感兴趣。
我正在尝试将 html5 视频标签源元素设为 return 准确的帧编号。
Whosebug answers.
附近的东西
我的目标是显示准确的时间码。
我一直在看 VideoFrame and many others, but none of them are accurate. If you play a video containing burned-in timecode or frame count, like the one I'm using video_keyframes12_24p_Mbits1.8.mp4 我自己做的。你最终会看到一帧。
有人对此有什么提示吗?
非常感谢!
问题
不幸的是没有帧 API 供我们使用 - Firefox has some experimental features,但除此之外我们只能处理时间以及浏览器如何处理帧解码作为帧速率转换。请参阅下面的更新。
例如,浏览器可能会或可能总是 convert/normalize 到 30 fps,如果是这样可能会或可能不会假定掉帧(对于 29.97/59.94 fps/NTSC)。随着时间的推移,这将影响帧数并最终显示为偏移量,因为时间和帧数之间没有真正的 link。
此外,由于基于整数的转换以及视频中的起始位置,可能存在舍入误差。根据浏览器的不同,视频在引擎盖下的解码方式也有不同的解决方案,例如,Chrome 在底层使用 FFMpeg,Firefox 使用 OS* 中可用的任何内容(对于 MP4 编码的视频)和等等。
可能的解决方案
(更新: 忘了说-) 还有就是Media Source Extensions API which support the VideoPlaybackQuality
object。目前 Chrome 和 IE(Windows 8+)以及 Firefox [支持]。
直接在HTMLVideoElement上调用即可使用:
var q = video.getVideoPlaybackQuality();
然后使用其属性读出值:
var frames = q.totalVideoFrames;
请注意,无论实际播放位置如何,此值可能会累积所有帧。您也许可以直接使用 MSE 来解决这个问题。设置和处理有点繁琐,但 this link 提供了一个很好的起点,以防您不熟悉 MSE。
另一种想法是在视频中编码一个特殊的条形码,然后使用 canvas 读取它。这在实际的 SMPTE 时间码上是等效的,但这将需要在视频中某种程度上可见的叠加层(就像将电文编码到视频的过扫描区域的旧方法一样)。如果视频是全帧,则会出现其他问题,例如根据用于编码的颜色(或为其制作纯色背景)进行错误检测。
*) 可能在 Cisco 免费发布他们的 mp4 解决方案后在最近的版本中发生了变化。
我在你引用的 link 上发布了这个答案,但我认为它也可能与这里相关:
从 M83 开始,Chromium 有一个 requestVideoFrameCallback() API,它可能会解决您的问题。 您可以使用 mediaTime 获得一致的时间戳,如 this Github issue 中所述。从那里,你可以尝试这样的事情:
var frameCounter = (time, metadata) => {
let count = metadata.mediaTime * frameRate;
console.log("Got frame: " + Math.round(count));
// Display timecode code here.
video.requestVideoFrameCallback(frameCounter);
}
video.requestVideoFrameCallback(frameCounter)
这只会在新帧上触发,但您有时可能会错过一帧(您可以从 metadata.presentedFrames
计数的不连续性中检测到)。您捕获帧的时间也可能稍晚(通常是 16 毫秒,或者比视频帧可用时晚调用 window.requestAnimationFrame()
一次)。
如果您对 API、here's a blogpost, or you can take a look at the API's offical github 的高级概述感兴趣。