如何确定视频帧是不是已准备好进行合成?

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 playon timeupdate,没想到on playing 如此不同。

它在第一帧可用于合成后触发,现在我不再有那些 WebGL 错误。在 android 10 设备以及 iOS 14.5 iPhone 7 设备上进行了测试。

【讨论】:

以上是关于如何确定视频帧是不是已准备好进行合成?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 YT.Player 对象是不是已准备好?

如何理解 Spring Boot 应用程序已准备好工作?

云原生视频时代已开启,华为云准备好了

如何将多张图片合成mp4视频格式,并加入背景音乐...

如何让 Hls.js 在准备好后自动播放视频?

UIImageView 是不是具有指示 setImage 已完成且动画已准备好的属性?