【问题标题】:How do you make Media Source work with timestampOffset lower than appendWindowStart?如何使 Media Source 使用低于 appendWindowStart 的 timestampOffset 工作?
【发布时间】:2018-02-13 15:43:55
【问题描述】:

我想使用 appendBuffer 并仅附加我拥有的媒体片段。 为了从最后切下一块,我使用 appendWindowEnd 并且它可以工作。 要从头开始切割,我必须将 timestampOffset 设置为低于 appendWindowStart。我见过 shaka-player 做类似的事情。

var appendWindowStart = Math.max(0, currentPeriod.startTime - windowFudge);
var appendWindowEnd = followingPeriod ? followingPeriod.startTime : duration; 
...
var timestampOffset = currentPeriod.startTime -mediaState.stream.presentationTimeOffset;

根据我的测试,它在 timestampOffset 为时有效

  • 与 appendWindowStart 相同
  • 降低 1/10 秒

当 timestampOffset 低于此值时不起作用。该段没有被添加。这与我的媒体有关还是规范/实施不允许?

来自 MDN 网络文档:

SourceBuffer 接口的 appendWindowStart 属性控制追加窗口开始的时间戳,一个时间戳范围,可以用来过滤哪些媒体数据被追加到 SourceBuffer。时间戳在此范围内的编码媒体帧将被附加,而超出范围的将被过滤掉。

刚刚在规范中找到了这个,所以我正在更新问题:

如果表示时间戳小于 appendWindowStart,则将需要随机访问点标志设置为 true,丢弃编码帧,并跳转到循环顶部开始处理下一个编码帧。

一些实现可能会选择收集其中一些表示时间戳小于 appendWindowStart 的编码帧,并使用它们在第一个表示时间戳大于或等于 appendWindowStart 的编码帧处生成拼接,即使该帧不是随机接入点。支持这一点需要多个解码器或比实时解码更快,因此目前这种行为不会成为规范要求。

如果帧结束时间戳大于 appendWindowEnd,则将需要随机访问点标志设置为 true,丢弃编码帧,并跳转到循环顶部开始处理下一个编码帧。

某些实现可能会选择收集呈现时间戳小于 appendWindowEnd 且帧结束时间戳大于 appendWindowEnd 的编码帧,并使用它们在收集时在附加窗口内生成跨收集的编码帧部分的拼接,并且稍后处理的帧的开始部分,仅与收集的编码帧的结尾部分重叠。支持这一点需要多个解码器或比实时解码更快,因此目前这种行为不会成为规范要求。结合收集跨越 appendWindowStart 的编码帧,实现可以因此支持无缝音频拼接。

如果磁道缓冲区上的需要随机访问点标志为真,则运行以下步骤: 如果编码帧不是随机访问点,则丢弃编码帧并跳转到循环的顶部以开始处理下一个编码帧。 将轨道缓冲区上的需要随机访问点标志设置为 false。

和

随机接入点 媒体片段中的一个位置,可以在该位置开始解码和连续播放,而无需依赖片段中的任何先前数据。对于视频,这往往是 I 帧的位置。在音频的情况下,大多数音频帧可以被视为一个随机访问点。由于视频轨道往往具有更稀疏的随机访问点分布,这些点的位置通常被认为是多路复用流的随机访问点。

这是否意味着,对于视频,我必须选择 timeOffset,它位于“I”帧上?

【问题讨论】:

    标签: media-source


    【解决方案1】:

    使用 timestampOffset 不需要 I-Frame。它只是将每帧的时间戳移动该值。该班次计算在其他任何事情之前执行(在 appendWindowStart 参与之前)

    影响 I 帧所在位置的是 appendWindowStart 的使用。

    appendWindowStart 和 appendWindowEnd 在您要添加的数据上充当 AND。

    MSE 不会重新处理您的数据,通过设置 appendWindowStart 您告诉源缓冲区在该时间之前包含的任何数据都将被排除 MSE 也适用于 GOP(图片组)的基础级别:从一个 I 帧到另一个。

    让我们想象这组图像,由 16 帧 GOP 组成,每帧持续时间为 1 秒。

    .IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP

    现在假设您将 appendWindowStart 设置为 10 在理想的世界里,你会:

    . PPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP

    所有之前的 9 帧都已被丢弃。

    但是,现在这些 P 帧无法解码,因此 MSE 在规范中将“需要随机访问点标志”设置为 true,因此添加到源缓冲区的下一帧只能是 I 帧 所以你最终在你的源缓冲区中:

    . IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP

    能够在 appendWindowStart 和下一个 I-Frame 之间添加帧将非常困难且耗时。 它需要在将所有帧添加到源缓冲区之前解码所有帧,将它们存储为原始 YUV 数据,或者如果硬件加速存储 GPU 支持的图像。

    源缓冲区在任何给定时间都可以包含超过一分钟的视频。想象一下,如果它现在必须处理解压缩数据而不是压缩数据。

    现在,如果我们想保留与现在相同的内存限制(每个源缓冲区的最大数据约为 100MiB),则必须在将内容添加到源缓冲区之前动态重新压缩内容。

    不会发生。

    【讨论】:

    • 感谢您的回答。但是,我相信开发人员应该选择(通过一些选项)他们希望 appendWindowStart 的工作方式。就我而言,我希望它能够作为搜索功能工作并处理 I 帧之后的约 10 个 P 帧,因此它可以重新创建我正在寻找的确切 P 帧。当前获得相同功能的骇人听闻的解决方法是资源密集型的。是的,这可能不是一个普遍要求的功能,所以我没有抱太大希望
    猜你喜欢
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 2014-01-12
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多