如何使媒体源使用低于 appendWindowStart 的 timestampOffset?

How do you make Media Source work with timestampOffset lower than appendWindowStart?

我想使用 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 为

时有效

当 timestampOffset 低于该值时不起作用。该段不会被添加。这与我的媒体有关还是 spec/implementation 不允许?

来自 MDN 网络文档:

The appendWindowStart property of the SourceBuffer interface controls the timestamp for the start of the append window, a timestamp range that can be used to filter what media data is appended to the SourceBuffer. Coded media frames with timestamps within this range will be appended, whereas those outside the range will be filtered out.

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

If presentation timestamp is less than appendWindowStart, then set the need random access point flag to true, drop the coded frame, and jump to the top of the loop to start processing the next coded frame.

Some implementations may choose to collect some of these coded frames with presentation timestamp less than appendWindowStart and use them to generate a splice at the first coded frame that has a presentation timestamp greater than or equal to appendWindowStart even if that frame is not a random access point. Supporting this requires multiple decoders or faster than real-time decoding so for now this behavior will not be a normative requirement.

If frame end timestamp is greater than appendWindowEnd, then set the need random access point flag to true, drop the coded frame, and jump to the top of the loop to start processing the next coded frame.

Some implementations may choose to collect coded frames with presentation timestamp less than appendWindowEnd and frame end timestamp greater than appendWindowEnd and use them to generate a splice across the portion of the collected coded frames within the append window at time of collection, and the beginning portion of later processed frames which only partially overlap the end of the collected coded frames. Supporting this requires multiple decoders or faster than real-time decoding so for now this behavior will not be a normative requirement. In conjunction with collecting coded frames that span appendWindowStart, implementations may thus support gapless audio splicing.

If the need random access point flag on track buffer equals true, then run the following steps: If the coded frame is not a random access point, then drop the coded frame and jump to the top of the loop to start processing the next coded frame. Set the need random access point flag on track buffer to false.

Random Access Point A position in a media segment where decoding and continuous playback can begin without relying on any previous data in the segment. For video this tends to be the location of I-frames. In the case of audio, most audio frames can be treated as a random access point. Since video tracks tend to have a more sparse distribution of random access points, the location of these points are usually considered the random access points for multiplexed streams.

这是否意味着,对于视频,我必须选择落在 'I' 帧上的 timeOffset?

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

appendWindowStart 的使用会影响到 I-frames 所在的位置。

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

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

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

.IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP

假设您现在将 appendWindowStart 设置为 10 在理想的世界中,您将拥有:

. PPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP

时间开始于 appendWindowStart 之前的所有前 9 帧都已被删除。

然而,现在那些 P-Frames 无法解码,因此 MSE 在规范中将 "need random access point flag" 设置为 true,因此添加到源缓冲区的下一帧只能是 I-Frame 所以你最终在你的源缓冲区中:

. IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP IPPPPPPPPPPPPPPP

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

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

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

不会发生。