使用媒体源扩展逐帧解码

Posted

技术标签:

【中文标题】使用媒体源扩展逐帧解码【英文标题】:Frame by frame decode using Media Source Extension 【发布时间】:2016-07-21 18:26:57 【问题描述】:

我一直在研究 Internet 上的媒体源扩展示例,但还没有完全找到一种方法来使它们适应我的需求。

我希望获取本地缓存的 MP4/WebM 视频(具有 100% 的关键帧和 1:1 的簇/原子与关键帧的比率)并以非顺序方式解码/显示它们(即第 10 帧、第 400 帧、 2、100 等),并能够以 0-60fps 的速率按需渲染这些非连续帧。使用 currentTime 属性的简单非 MSE 方法由于设置此属性和显示帧的延迟而失败。

我意识到这完全超出了视频播放的正常预期,但我的应用程序需要这种类型的非连续高速播放。理想情况下,我可以使用 h264 来实现 GPU 加速,但我意识到可能有一些特定于平台的 GPU 缓冲区需要处理,尽管零帧缓冲区似乎应该是可能的(参见here)。我希望 MSE 可以完成这种非连续的高帧率低延迟播放,但我知道我要求很多。

问题:

    appendBuffer 是否会接受由单个关键帧组成的单个 WebM 集群/MP4 Atom,并且还能够以高频率 (60fps) 解码?

    你认为我想要做的事情在浏览器中可行吗?

任何帮助、见解或代码建议/示例将不胜感激。

谢谢!

2016 年 4 月 5 日更新

我能够让 MSE 主要在 Firefox、Edge 和 Chrome 中处理单帧 MP4 片段。但是,Chrome 似乎遇到了上面链接的帧缓冲区问题,我还没有找到一种方法来预处理 MP4 以调用这种“低延迟”模式。任何人都知道是否可以使用 MP4Box 等现有工具创建这样的文件?

Firefox 和 Edge 立即解码/显示各个帧,延迟非常小,但是当我将此视频加载到 Three.js WebGL 项目中时(没有视频输出,没有错误),当然会出现问题。我暂时忽略了这一点,因为我更希望在 Chrome 上运行,因为我也将针对 android

【问题讨论】:

关于 currentTime:您是否尝试过“搜索”事件?如果没有,这可能对您有用:***.com/questions/19175174/… 从未尝试过,我认为只有最新的 Chrome 版本才能实现它,但我认为您可以在 SourceBuffer 上使用段 appendMode。见w3.org/TR/media-source/#idl-def-AppendMode.sequence。 @K3N 实际上我没有。它肯定会让事情变得更加一致,因为它不会在仍在寻找时尝试更新 currentTime(这可能会导致进一步的延迟)。我在我的 Surface Pro 2 上设置了一个快速测试,使用 1080p h264 MP4 使用“搜索”事件尽可能快地增加 currentTime。结果 - Firefox 为 30fps,Microsoft Edge 为 60fps,但 Chrome 远远落后于 6fps。我会尝试在 Android 上测试 Chrome,看看它是否同样糟糕。 @PabloMontilla sourceBuffer.mode = 'sequence' 听起来确实像是我需要用于 MSE 实现的东西。感谢您的建议。 @K3N 我明白了为什么 Chrome 在上面的测试中表现如此糟糕。 Chrome 中似乎存在一个错误,导致它在分辨率 > 1080p - bugs.chromium.org/p/chromium/issues/… 时回退到软件解码 【参考方案1】:

我能够很好地完成这项工作。关键是通过使用修改后的 mp4box 源混合特制 MP4 文件,让 Chrome 进入其“低延迟”模式。我在movie_fragments.c 中添加了一行,因此显示为:

        if (movie->moov->mvex->mehd && movie->moov->mvex->mehd->fragment_duration) 
            trex->track->Header->duration = 0;
            Media_SetDuration(trex->track);
            movie->moov->mvex->mehd->fragment_duration = 0;
        

现在创建的每个 MP4 都将 MEHD 片段持续时间设置为 0,这会导致 Chrome 将其作为实时流处理。

我还有一个与 timestampOffset 属性相关的剩余问题,它与媒体片段中设置的 FPS 结合控制播放速度。由于我希望直接控制 FPS,我不希望 MSE 播放引擎增加任何延迟。我将在这里发布一个单独的问题来解决这个问题。

谢谢, 达斯汀

【讨论】:

我知道您在那个 C 文件中将持续时间设置为 0,您知道是否有任何方法可以使用现有工具进行设置?像 MP4Box 或 FFMpeg。你在用 gpac 吗? @Zip,不幸的是我不相信有任何现成的工具。 那么你是在修改 gpac 然后用它来删除持续时间吗? 是的,我正在修改 gpac mp4box 源并强制持续时间 = 0

以上是关于使用媒体源扩展逐帧解码的主要内容,如果未能解决你的问题,请参考以下文章

如何使用媒体源扩展 (MSE) 低延迟模式

使用媒体源扩展符合DOMException:无法加载,因为找不到支持的源

媒体基金会 AMR 解码

媒体基础:在没有容器的情况下解码和显示 H264 帧

如何正确检测、解码和播放无线电流?

音视频常见播放器框架分析