HLS 的延迟是设计出来的:约等于「切片时长 × (回溯数 + 缓冲数)」。 它用这个代价换来规模、兼容和穿墙能力。
5.1.2 走完了流程,这一节把流程的代价算清楚。 5.1.4 再拿这个代价去对照各种场景,看哪些能接受、哪些不能。
一、延迟到底花在哪
HLS 的延迟不是「网络慢」,而是「设计上就要攒」: ① 切片时长:一个切片要录满才发,比如 4 秒。 这一笔是硬成本,绕不过去。 ② 列表回溯数:客户端一般从倒数第 3 个切片开始播, 为的是万一某个切片下载失败还能往前退。 ③ 客户端缓冲:自己再攒 1 到 2 个切片。
所以端到端延迟约等于「切片时长 × (回溯数 + 缓冲数)」。 4 秒切片、回溯 3 个、缓冲 1 个,就是 16 秒左右。
实测这张表能看清代价的走向: 2 秒切片约 6~8 秒,4 秒约 12~16 秒,10 秒就到 30~40 秒。 切片时长是唯一的乘数,改它一个就能整体缩放。
二、把延迟压下去要付什么
切到 2 秒能把延迟压到 6 到 8 秒,代价很实在: ① 请求数翻倍:同样时长,切片多一倍,HTTP 请求也多一倍。 ② 头部开销上升:每个切片都是一段独立的 TS,PAT/PMT 要重发。 切片越短,这份固定开销摊得越薄不了。 ③ CDN 缓存效率下降:文件小了,命中率会掉。 热门片还好,长尾片会明显吃亏。
还有一个隐性代价:切片越短,编码质量越难保证。 因为每个切片都得以关键帧开头,关键帧一密,同码率下画质就下降。
想既要低延迟又要画质,就得换路子: LL-HLS 用「部分切片」把等待时间切成小段, 或者干脆换 HTTP-FLV 与 WebRTC。
三、优势也很硬
① 就是普通 HTTP:任何 CDN、任何防火墙都放行,不用开特殊端口。 这一条在企业内网里的价值常常被低估。 ② 天然支持大规模:切片是静态文件,缓存命中率极高。 一百万观众和一万观众的服务器压力差不多,只是 CDN 多花点钱。 ③ 自适应码率成熟:主列表多档位,客户端可以平滑切换。 ④ 客户端兼容性最好:iOS 原生支持,浏览器用 hls.js 也能播。
一句话:HLS 用延迟换规模和兼容性。 所以「大流量、能忍几秒延迟」选 HLS; 「要低延迟、观众不多」选 WebRTC 或 HTTP-FLV。
四、动手 Demo:延迟等于切片数乘切片时长
按「切片时长 × (回溯数 + 缓冲数)」算四种配置的延迟。 算完再反过来看:压延迟的代价是请求数翻倍。
combos = [(2, 3, 1), (4, 3, 1), (6, 3, 1), (10, 3, 1)]
print("切片秒 回溯 缓冲 延迟下限 延迟上限")
for seg, back, buf in combos:
lo = seg * back
hi = seg * (back + buf)
print("%6d %4d %4d %8d %8d" % (seg, back, buf, lo, hi))
# 压延迟的代价:同样一小时,切片数与请求数成正比
print()
print("一小时 3600 秒,切片时长与请求数的关系:")
for seg in (2, 4, 6, 10):
n = 3600 // seg
print(" %2d 秒切片 -> %4d 个切片、%4d 次请求、标题占 %d 次"
% (seg, n, n, n))
实跑输出:
--------------------------------------------------------------------
优劣势——延迟等于切片数乘切片时长
--------------------------------------------------------------------
**① 延迟的组成**
**HLS 的延迟不是「网络慢」,而是「设计上就要攒」:**
**① 切片时长**:**一个切片要等录满才发,比如 4 秒。**
**② 列表里保留几个**:**客户端通常从倒数第 3 个开始播。**
**③ 客户端缓冲**:**自己再攒 1 到 2 个切片。**
**所以端到端延迟约等于「切片时长 × (列表回溯数 + 缓冲数)」。**
**4 秒切片、从倒数第 3 个起播、再缓冲 1 个,就是 16 秒左右。**
**② 不同切片时长的延迟**
切片时长 回溯 3 个 加缓冲 1 个 实际起播
----------------------------------------------------------
2 秒 6 秒 8 秒 约 6~8 秒
4 秒 12 秒 16 秒 约 12~16 秒
6 秒 18 秒 24 秒 约 18~24 秒
10 秒 30 秒 40 秒 约 30~40 秒
**切到 2 秒能把延迟压到 6 到 8 秒,但代价很实在:**
**① 请求数翻倍**:**同样时长,切片多一倍,HTTP 请求也多一倍。**
**② 头部开销上升**:**每个切片都是一段独立的 TS,PAT/PMT 要重发。**
**③ CDN 缓存效率下降**:**文件小了,命中率会掉。**
**③ 优势也很硬**
**① 就是普通 HTTP**:**任何 CDN、任何防火墙都放行,不需要开特殊端口。**
**② 天然支持大规模**:**切片是静态文件,缓存命中率极高。**
**一百万观众和一万观众的服务器压力差不多。**
**③ 自适应码率成熟**:**主列表多档位,客户端可以平滑切换。**
**④ 客户端兼容性最好**:**iOS 原生支持,浏览器用 hls.js 也能播。**
**一句话:HLS 用延迟换规模和兼容性。**
**所以「大流量、能忍几秒延迟」选 HLS;「要低延迟、观众不多」选 WebRTC 或 HTTP-FLV。**
延迟下限只看回溯数,缓冲数只影响上限:这就是「先下 3 片」的真正含义。 10 秒切片的下限就 30 秒,已经超过大多数直播能忍的范围。 切片数与时长的关系是整数除法,3600/7 会丢掉余数,算出来的片数偏少。
30 秒实验
- 把回溯数从 3 改成 2,看下限怎么变——少一个切片时长,但抗抖动能力也弱了一档。
- 把切片改成 1 秒,看请求数——3600 次请求,但延迟能压到 2~4 秒,这就是低延迟 HLS 的做法。
- 把缓冲数改成 3,看上限变化——上限涨两个切片,下限一点没动。
常见误区
- 「HLS 延迟高是因为 TCP 慢」——不是,是切片机制本身要攒。
- 「切片越短越好」——请求数、头部开销、画质三项都要付代价。
- 「缓冲越多越流畅」——越多越抗抖动,但延迟上限也跟着涨。
自测三问(点开对答案)
1. 延迟的公式是什么? —— **切片时长 × (回溯数 + 缓冲数)**,下限只看回溯数。 2. 砍切片时长有哪三项代价? —— **请求数翻倍、头部开销上升、CDN 命中率下降**,另外画质也会受影响。 3. HLS 最硬的优势是什么? —— **纯 HTTP**,任何 CDN 与防火墙都放行,规模几乎不受服务端限制。- ☐ (本节完,下一节 5.1.4 HLS 主要的应用场景)