首页 > 解决方案 > SourceBuffer.remove(start, end) 删除整个缓冲的 TimeRange(如何使用 MSE 处理实时流?)

问题描述

我有一个SourceBuffer.buffered. 我有一个实时的原始 h.264 数据流到达,我将其编码为 mp4 并推入SourceBufferwith .appendBuffer(data)。由于这是一个实时数据流,我需要不断清除缓冲区,但这是我遇到问题的地方。(即我遇到一个QuotaExceededError

例如,我的单个条目SourceBuffer.buffered的时间范围为 0-10 秒。我整理缓冲区的尝试是调用SourceBuffer.remove(0, 8). 我的期望是我的缓冲区会被清除,我的时间范围是 8-10。然而,整个时间范围(我唯一的范围)被删除,从这一点开始,所有进一步的 appendBuffer 调用似乎什么都不做。

与此问题相关的三个问题:

  1. 我该如何 a) 停止 .remove 出现这种行为或 b) 在我的缓冲区中强制使用新的时间范围,以便只删除“旧”范围。
  2. 为什么后面的appendBuffer调用什么都不做?我希望他们重新填充SourceBuffer.
  3. 有没有更好的“MSE”方式来处理我从不关心回到过去的实时流?IE。所有渲染的数据都可以丢弃。

如果出现一些奇怪的浏览器/平台问题,我会在 Ubuntu 上使用 Chrome。

另外,我的代码基于https://github.com/xevokk/h264-converter

标签: javascriptvideo-streaminghtml5-videomedia-source

解决方案


这一切都在 MSE 规范中。

http://w3c.github.io/media-source/#sourcebuffer-coded-frame-removal

步骤 3.3:从此轨道缓冲区中删除所有包含大于或等于 start 且小于删除结束时间戳的开始时间戳的媒体数据。

所以用户代理会删除你请求的所有数据,从 0 到 8s

然后步骤 3.4:通过从该轨道缓冲区中移除上一步中移除的那些帧与那些移除的帧之后的下一个随机访问点之间的所有编码帧,移除对上一步中移除的编码帧的所有可能的解码依赖性。

用户代理将删除所有依赖于您刚刚删除的帧的帧。由于 h264 的工作方式(以及所有现代视频编解码器),所有帧都在最后一个关键帧之后直到下一个关键帧,因为现在这些帧都不能被解码。

8到10s范围内没有关键帧,所以全部去掉

为什么后面的 appendBuffer 调用什么都不做?我希望他们重新填充 SourceBuffer。

您已删除数据,根据规范,您添加的下一帧必须是关键帧。如果您添加的片段不包含关键帧,则不会添加任何内容。

如果您添加的数据在开始时由单个关键帧组成,然后是 P 帧,那么您无法删除中间的任何帧,而不会使后面的所有帧都无法使用


推荐阅读