如何确定视频帧是不是已准备好进行合成?
Posted
技术标签:
【中文标题】如何确定视频帧是不是已准备好进行合成?【英文标题】:How to determine if video frame is ready for composition?如何确定视频帧是否已准备好进行合成? 【发布时间】:2021-10-11 18:51:27 【问题描述】:我在 *** 上找到了一些 similar question,但它并没有真正解决我的问题。
我正在将多个视频一个接一个地播放到 WebGL 纹理中。它基于用户输入,类似于基于 Web 的 VJ 工具。
复制很容易完成,而且我的内部时钟与我正在播放的视频(例如 30 fps)一样与相同的 fps 同步,并且帧被正确更新。与上述问题中提供的答案之一完全相同。一切都很好。
纹理更新为:
gl.texSubImage2D(gl.TEXTURE_2D,0,0,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,video);
我的问题是如何检测第一帧何时可用于合成。视频在真实环境中不会立即开始播放(例如平均4G,CDN上的视频),但有时需要1s或更长时间才能开始播放(以缓冲足够的数据)。
如果我尝试在第一帧可用之前开始更新纹理,则会引发 WebGL 错误:
WebGL: INVALID_VALUE: texSubImage2D: no video
我知道可以提前调用video.load();
方法(例如在用户交互时),但是我有大约 50 个视频文件需要播放(顺序未知,因为它取决于用户输入),当我这样做时,旧手机(如 iPhone 7)的性能会大幅下降,以至于 Safari 有时会崩溃。
我正在寻找一种可靠的方法来确定视频何时开始实际播放。当第一帧可用时,onplay
等事件似乎不会触发,但要早得多。
我也尝试过ontimeupdate
事件,但是当第一帧可用于合成时似乎不会触发,但更早时也会触发,就像onplay
一样。我可以看到事件被触发,并且在第一次触发时开始更新纹理,但在更新开始时它会生成 WebGL 错误(大约 0.5-1 秒,取决于网络速度),直到视频实际显示第一帧。缓冲后,不会引发任何错误。
此问题在 4G/移动网络中更为明显。还在 Chrome 中以节流速度进行了测试。在显示第一帧之前,不受限制的速度会给我 1-4 个 WebGL 警告,而例如。节流 12mbps 会给我 100-200 条警告,显示之前的视频帧。
我看过requestVideoFrameCallback,但它没有我需要的覆盖范围(ios Safari 甚至没有计划很快)。
如果视频帧尚未准备好合成,我会尽量避免更新纹理,但找不到可靠的方法来确定何时准备好。
非常感谢任何帮助!
【问题讨论】:
【参考方案1】:好的,我在监听on playing 事件时找到了解决方案。
我在听on play
和on timeupdate
,没想到on playing
如此不同。
它在第一帧可用于合成后触发,现在我不再有那些 WebGL 错误。在 android 10 设备以及 iOS 14.5 iPhone 7 设备上进行了测试。
【讨论】:
以上是关于如何确定视频帧是不是已准备好进行合成?的主要内容,如果未能解决你的问题,请参考以下文章