HTML5视频:跳转到特定帧而不是时间位置?或者将暂停的视频步进到下一帧或上一帧?

问题描述 投票:0回答:2

当我有一个 HTML5 视频对象时,我可以设置其

currentTime
属性来跳转(寻找)到特定的时间位置。

还有一种方法可以跳转或寻找特定的帧编号吗?

或相关:有没有办法让暂停的视频步进或跳到下一帧或上一帧?
我的意思是,当它当前暂停或冻结在某个任意位置时,导致视频跳转到后一帧或前一帧。

javascript html html5-video video-processing frame-rate
2个回答
2
投票

正如评论中提到的,据我所知,除了提到的“seekToNextFrame”之外,没有定义标准来支持 HTML5 视频标签本身的帧精确搜索,该标准并未得到广泛支持,如下所示:https:// developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seekToNextFrame

有商业 Javascript HTMl5 播放器提供此功能 - 例如:

您还可以在开源 Shaka 玩家讨论组中找到有关此主题的讨论。

它并不简单的原因是它通常需要播放器或浏览器(或客户端)首先找到最近的“I”帧,然后从中向前和/或向后解码以到达您想要的确切帧想。正如上面的示例实现所证明的那样,这在技术上当然是可行的,但我猜想浏览器或开源玩家社区中还没有优先考虑此功能的需求。


0
投票

我有两种处理需要预扫描整个视频的帧的解决方案。

设置:

let video = document.getElementById("my-video")
视频是
HTMLMediaElement

我们的工具包:

  • video.play()
    video.pause()
  • video.currentTime
    (以秒为单位)是我们视频的位置以及更改它的最佳方法。 (还有)。
  • video.duration
    (以秒为单位)是视频的总长度。
  • video.playbackRate
    默认1.0,最大16.0(至少对我来说)。
  • video.getVideoPlaybackQuality()
    给出
    totalVideoFrames
    droppedVideoFrames
    corruptedVideoFrames
  • 的计数
  • let vfcId = video.requestVideoFrameCallback((now,metadata)=>{})
    video.cancelVideoFrameCallback(vfcId)
    在显示框架时调用该函数。
  • video.onended = (event) => {}
    (本质上是视频结束时的事件侦听器。)

其他无用的工具:

  • video.fastSeek()
    currentTime
    准确但速度更快。
  • video.muted = true
    可以避免被烦人
  • video.ontimeupdate
    /
    "timeupdate"
    事件。无用,因为仅每隔几帧激活一次,这还不够好。

解决方案 1:VideoPlaybackQuality(速度超过(一点)质量)

策略:找到帧速率并用它来计算帧时间。

video.getVideoPlaybackQuality().totalVideoFrames
为我们提供了视频中迄今为止播放的帧总数,因此我们不能在视频中跳来跳去,而必须完整观看。尽管如此,totalVideoFrames / video.duration
仍将为我们提供帧速率。

let framerate = None; function getFrameRate() { video.playbackRate = 16; video.currentTime = 0; video.play(); video.onended = (event) => { framerate = video.getVideoPlaybackQuality().totalVideoFrames / video.currentTime; video.onended = (event) => (None); //could be cleaner }; } function timeForFrame(n) { return Math.round(n/framerate *1000)/1000; } function goToFrame(n=currentFrame) { video.currentTime = timeForFrame(n); }
请注意,我将 

playbackRate

 设置为 x16 以使扫描速度更快。这使得视频播放器
丢帧,但是,它们仍然按totalVideoFrames计算

优点:x16播放速度相对较快,并且可以将预扫描变成加载预览。对于长视频,您可以使用超时来估计前几秒的帧速率。

缺点:如果视频帧速率随时间变化,此方法可能不准确。

解决方案 2:VideoFrameCallback(质量好但速度很慢)

策略:为每一帧创建一个带有

frame_times

 的列表 (
currentTime
)。

VideoFrameCallback

回调每个
显示的帧,其中包含大量时间元数据。 metadata.mediaTime
 是框架的 
currentTime

注意:

requestVideoFrameCallback

 
不是事件监听器,您需要在每一帧中一次又一次地请求它。

let frame_times = []; let vfcId = 0; function getFrametimes() { video.playbackRate = 1; // will start dropping frames if higher. video.currentTime = 0; video.requestVideoFrameCallback(frameTimePusher); video.play(); video.onended = { video.cancelVideoFrameCallback(vfcId); video.onended = (event) => (None); } } function frameTimePusher(now,metadata) { frame_times.push(metadata.mediaTime); //mediaTime is currentTime video.requestVideoFrameCallback(frameTimePusher); // !! you need to request again. } function goToFrame(n) { video.currentTime = frame_times[n]; }
请注意,

playbackRate

 设置为 x1。这是因为如果设置得更高,视频将开始
丢帧,并且 VideoFrameCallback 仅针对非丢帧激活。

优点:非常准确(如果以 x1 播放速率运行)

缺点:慢(如果您以 x1 播放速率运行)

解决方案 1 可以说更好。

© www.soinside.com 2019 - 2024. All rights reserved.