WWDC Quick Look 💓 By SwiftGGTeam
Optimize live streams with HLS Playlist Delta Updates

Optimize live streams with HLS Playlist Delta Updates

观看原视频

Highlight

Apple 为 HLS 直播 playlist 提供 Delta Updates 与 2020 年新增的 DATERANGE 跳过能力,让客户端在重载大 DVR 窗口时只下载最近变化,减少 playlist 带宽并提升播放稳定性。

核心内容

直播播放器有一个很朴素的动作:反复请求 media playlist,确认有没有新 segment。窗口很小时,这件事成本不高。窗口变成一场长赛事、一个大 DVR 回看区,playlist 会越来越长;即使用 gzip,每次把完整文件重新拉一遍,也会消耗时间和带宽。

这个成本会反过来影响播放质量。网络差时,playlist reload 本身占掉吞吐,播放器可能切到更低码率的 variant。用户实际感受到的是画质下降、追直播变慢、广告或事件 metadata 跟不上。

Playlist Delta Updates 解决的是重载方式。客户端先拿一次完整 playlist,后续请求带上 HLS skip delivery directive。服务器返回一个 delta playlist,只包含新变化和一个 #EXT-X-SKIP 标签。客户端把 delta 和本地旧 playlist 合并,得到服务器上的当前完整 playlist。

WWDC20 的新增点落在 #EXT-X-DATERANGE。很多直播会把广告、事件、章节或计时信息写进 DATERANGE;segment 可以跳过,metadata 仍然很大。2020 年的扩展让服务器声明 CAN-SKIP-DATERANGES=YES,客户端用 _HLS_skip=v2 请求,delta 里再用 RECENTLY-REMOVED-DATERANGES 告诉客户端哪些旧 DATERANGE 已被删除。

详细内容

1. 先让服务器声明可以跳过旧 segment

01:11)Delta Updates 是可选能力。服务器必须在 #EXT-X-SERVER-CONTROL 里声明 CAN-SKIP-UNTIL。这个值是 skip limit,表示 playlist 中多老的内容可以被 delta update 跳过。session 明确说它至少是六个 target duration。

# media playlist advertises delta support
#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=36

# transcript example:
# target duration: 6 seconds
# skip limit: 36 seconds
# visible window starts at segment 0 and ends at segment 20

关键点:

  • CAN-SKIP-UNTIL=36 对应六个 target duration,满足 session 给出的最低要求。
  • 这个声明放在 server control tag 中,客户端看到后才会尝试请求 delta update。
  • skip limit 表示 playlist 中多老的内容可以被 delta update 跳过。
  • transcript 的例子从 segment 0 到 segment 20,用来说明客户端已经拿到一个完整窗口。
  • 客户端至少要先下载一次完整 playlist,再开始请求 delta。

2. 客户端用 _HLS_skip=YES 请求 delta playlist

01:3503:31)客户端下一次重载时,在 playlist URL 上加入 HLS skip delivery directive。服务器返回带 #EXT-X-SKIP 的 delta playlist,不再重复发送完整 playlist。

GET /live/stream.m3u8?_HLS_skip=YES
# delta update returned by the server
#EXT-X-VERSION:9
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-SKIP:SKIPPED-SEGMENTS=19
segment 20
segment 21

关键点:

  • _HLS_skip=YES 是客户端请求 delta update 的 delivery directive。
  • #EXT-X-MEDIA-SEQUENCE:1 告诉客户端,完整 playlist 里的 segment 0 已经移出窗口。
  • #EXT-X-SKIP:SKIPPED-SEGMENTS=19 代替一批客户端已经见过的 segment URL 行,以及附着在这些行上的媒体 segment tags。
  • segment 20 和新加入的 segment 21 是 skip limit 之后仍需要返回的最近内容。
  • 客户端拿本地旧 playlist 删除已滚出窗口的条目,再补上 delta 中的新条目,重建当前 playlist。

3. 用 CAN-SKIP-DATERANGES 处理大量 metadata

04:1204:38)2019 年的 Delta Updates 对 segment 很有效。问题是长直播经常还有很多 #EXT-X-DATERANGE。WWDC20 的扩展允许服务器声明自己也能跳过 DATERANGE,客户端用 v2 形式请求。

# media playlist advertises DATERANGE skipping
#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=36,CAN-SKIP-DATERANGES=YES

# client asks for the v2 form
GET /live/stream.m3u8?_HLS_skip=v2

# returned delta uses playlist version 10
#EXT-X-VERSION:10

关键点:

  • CAN-SKIP-DATERANGES=YES 是服务器对客户端的能力声明。
  • _HLS_skip=v2 是客户端请求跳过 DATERANGE 的新形式。
  • #EXT-X-VERSION:10 表示这个 delta update 使用了 DATERANGE skipping。
  • DATERANGE 可以出现在 playlist 的任意位置,session 示例把它们放在底部只是作者选择。
  • 服务器会跳过早于 skip limit 加入的 DATERANGE,避免 metadata 把 delta 再次撑大。

4. 用 RECENTLY-REMOVED-DATERANGES 同步删除事件

05:0206:02)DATERANGE 不只会新增,也会被作者从 playlist 删除。v2 delta 通过 RECENTLY-REMOVED-DATERANGES 把这些删除同步给客户端。

# v2 delta update with removed DATERANGE IDs
#EXT-X-VERSION:10
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-SKIP:SKIPPED-SEGMENTS=19,RECENTLY-REMOVED-DATERANGES="1"
segment 21
#EXT-X-DATERANGE:ID="P"
#EXT-X-DATERANGE:ID="Q"

关键点:

  • RECENTLY-REMOVED-DATERANGES="1" 告诉客户端,本地缓存里的 DATERANGE ID 1 要删除。
  • DATERANGE P 出现在 delta 中,表示它是在 skip limit 之后加入的近期 DATERANGE。
  • DATERANGE Q 是新 DATERANGE,客户端合并后会保留它。
  • DATERANGE 2 早于 skip limit 且仍有效,客户端需要从本地旧 playlist 保留。
  • 合并结果要包含仍有效的 DATERANGE,并排除已删除的 ID。

核心启发

1. 给体育直播做大 DVR 窗口

  • 做什么:保留几十分钟到数小时的回看窗口,让用户能拖回关键回合。
  • 为什么值得做:playlist 变长后,Delta Updates 让客户端重载时只拿最近变化,降低大窗口的重复传输。
  • 怎么开始:在 media playlist 的 #EXT-X-SERVER-CONTROL 加上 CAN-SKIP-UNTIL,确认客户端先拿完整 playlist,再观察 _HLS_skip=YES 请求的返回大小。

2. 给带广告的直播减少 metadata 压力

  • 做什么:把广告机会、广告段和追踪事件继续写入 #EXT-X-DATERANGE,但让 delta 跳过过早的 metadata。
  • 为什么值得做:WWDC20 的 CAN-SKIP-DATERANGES_HLS_skip=v2 专门处理大量 DATERANGE 的场景。
  • 怎么开始:为支持该能力的流加 CAN-SKIP-DATERANGES=YES,在 delta 的 #EXT-X-SKIP 中返回 RECENTLY-REMOVED-DATERANGES,用测试播放器检查删除事件是否同步。

3. 给弱网用户保住更高画质

  • 做什么:在现有自适应码率阶梯之外,优化 playlist reload 的字节数,减少控制面流量对媒体吞吐的挤压。
  • 为什么值得做:session 明确指出,大 playlist 的反复下载会让播放器在差网络下降到更低质量 tier。
  • 怎么开始:记录完整 playlist 和 delta playlist 的压缩后大小,按 variant、网络类型和 DVR 窗口长度比较 reload 成本。

4. 给 HLS 服务端增加合并一致性测试

  • 做什么:自动验证“完整 playlist”与“旧 playlist 加 delta”得到同一个结果。
  • 为什么值得做:delta playlist 不能单独解析,客户端播放正确性依赖合并结果。
  • 怎么开始:在服务端测试里保存一个旧 playlist,请求 _HLS_skip=YES_HLS_skip=v2,模拟删除 media sequence、保留近期 segment、移除 RECENTLY-REMOVED-DATERANGES 指定的 ID。

关联 Session

评论

GitHub Issues · utterances