[DASH] SegmentTimeline V.S. SegmentTemplate
本文总结于 un
SegmentTemplate with number sequence: 简称序号模式
<SegmentTemplate duration="2" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/$Number$.m4s" startNumber="0" />
它的meida 资源请求url通过Number序号递增来实现。
SegmentTemplate with timeline 简称 时间线模式
<SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/t$Time$.m4s" timescale="48000">
<SegmentTimeline>
<S d="96000" t="0" />
<S d="96000" r="2" />
<S d="48000" />
<S d="96000" t="4800000" />
<S d="48000" />
</SegmentTimeline>
</SegmentTemplate>
先说说 SegmentTemplate with number 的缺陷:对于 @type="dynamic" (也就是 live) 的场景,player 必须依靠wall-clock 来确定最近的一个segment 是否可用。而 时间线模式则不需要,player 只需要根据 manifest 中的信息,就能得到最近一个 segment 是否可用的结论。
显然,序号模式会导致404.
为什么呢?分析以下序列模式拿最近一个segment的过程:
最近segment序列号 = (当前player的 wall_clock - manifest中第一个segment的可用时间) / (duration / timescale ) + 1
这里存在一个难点:上式的准确性要求 player 和 服务器 的 wall clock 必须一致,但是常常存在一些问题使得该问题出现,比如:播放器无法获得准确的时间,播放器的时钟与系统时钟偏移,加之不够频繁地同步以及缓存会延迟媒体段的可用性,从而破坏了与播放器的定时同步。
看看时间线模式怎么知道最近的segment 是否可用:
根据最近一个 t, 加上后续的segment 的所有 duration,就可以得到最近的segment的t,不需要 wall-clock 同步。因此,使用时间线模式,很容易招到 live 场景下的最近一个segment。
另外,它还有其他优势:
- duration 可变的segment
- segment 可以有不连续性: 通过 t 来实现
- 提供准确的时间戳
序号模式 与 404
首先,player wall-clock 与 服务器不匹配
序号模式下,最近segment的序号不可能进行可靠的计算。如果player的时间来源早于origin的时间来源,则会请求尚未提供的时间的segment。
其次,关于manifest中未发出不连续性信号导致错误的请求
player将假设不连续性时间范围内的分段可用,直到对该分段的请求证明不成立,然后返回HTTP 404响应。
第三,关于无法发出变化信号和分段的可用性
如果某个segment的时间比设置的持续时间长两秒钟,则下一个segment将比player的计算晚两秒钟。如果player随后立即请求第二段,则这将再次导致404。
而使用 时间线模式时,上述三个问题都不存在。