基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角

本文介绍了 TikTok Live 中基于 HTTP-FLV 的自适应码率直播实现与部署经验。HTTP-FLV 不像 HLS 和 DASH 等基于分段的流媒体协议那样将媒体流划分为独立分段。因此,现有文献中占主导地位的客户端 ABR 控制逻辑,会在新旧码率版本切换过程中引发带宽争抢。为验证这一点,我们分别实现了由客户端执行和由服务器执行的 ABR 切换,并通过大规模线上 A/B 测试进行比较。实验表明,由服务器执行的 ABR 切换能够提供更好的 QoE。此外,我们还通过服务端拥塞控制状态反馈等通用优化方案进一步增强了 ABR 实现。我们希望这些实践经验能为类似系统提供参考,特别是那些采用社区正在积极讨论的新兴流媒体协议的系统。

文章来源:ACM SIGCOMM 2026 Experience Track
论文题目:Adaptive Bitrate Live Streaming over HTTP-FLV: A Practical System Perspective
论文作者:Le Zhang, Tong Meng, Bingcong Lu, Jinghao Yuan, Lu Chen, Huanting Liu, Lei Xiao, Nailiang Wu, Zhou Sha, Changqing Yan, Jianrong Zhang, Jianxin Kuang, Li Song (SJTU Medialab)
原文链接:https://doi.org/10.1145/3789240.3829169
内容整理:卢冰聪

一、引言

TikTok Live 每天向数亿用户分发直播。源流会被转码为多个码率档位,客户端在观看过程中动态选择变体,以提高可用带宽利用率,并在拥塞时降低卡顿风险。

大量 ABR 研究默认 HLS 或 DASH:媒体被切成边界对齐的分段,客户端选中某个分段,服务器按请求返回有限长度的响应。HTTP-FLV 不同,一个 URL 对应一条持续产生数据的码率流,只要主播继续推流,单个 HTTP 响应就没有天然终点。客户端发起新码率请求时,旧流仍可能在发送,新流也可能已经进入同一条受限接入链路。

论文解决的不是一种新的 ABR 选码算法 。它比较了客户端执行与服务器执行两种切换机制,并通过十亿级会话 A/B 实验验证:对连续流协议,更合理的职责分工是“客户端决定码率,服务器执行切换”。

本文的主要贡献如下:

  • 我们基于客户端侧控制逻辑和混合控制逻辑,分别提出了两种面向 HTTP-FLV 的 ABR 实现。两种实现都由客户端负责做码率自适应决策,区别在于 ABR 切换由谁执行。因此,本文将其分别称为客户端执行的 ABR 切换和服务器执行的 ABR 切换。
  • 我们通过两项通用优化进一步提升了 ABR 性能。第一,将服务端准确的拥塞控制状态反馈作为客户端 ABR 算法的输入;第二,在从源站向边缘获取所请求码率流时采用一致性哈希,从而减少向上游服务器发起的请求数量,并提高边缘缓存命中率。
  • 我们给出了基于数十亿次观看会话的 A/B 测试结果。服务器执行的 ABR 切换使每次切换期间的平均视频卡顿时长降低了 13% 。此外,与未启用 ABR 的场景相比,在 HTTP-FLV 上部署 ABR 不仅使视频卡顿率降低了 4.7% ,还使每个客户端的日均观看时长提高了 0.2% 。

这些结果说明,ABR 流媒体的 QoE 收益也可以通过改进非算法机制获得。论文还从实践角度讨论了下一代流媒体协议中的持续订阅特性,以及服务端拥塞控制反馈是否应成为 QUIC 乃至更一般传输层协议扩展的问题。

二、动机

HTTP-FLV 把传统分段协议里隐含的切换共识拆开了:从新流哪里开始、何时真正换过去、旧流何时停止,三件事都需要显式协调。

1. 分段式协议与 HTTP-FLV 的本质差异

HLS/DASH 中,URL 最小寻址单位是分段。不同码率的分段边界对齐,响应结束也天然意味着旧分段传完。服务器通常不必识别同一观看会话的两个请求,更不必理解关键帧或时间戳。HTTP-FLV 按连续 FLV Tag 组织媒体,一个请求可以持续整个直播。切换粒度可细到任意 GOP 开头,反应更快,却没有现成的切换边界。新变体的起播位置不能太靠后,否则降码率救火来不及;也不能贴得太近,否则请求和数据受网络抖动影响,可能赶不上播放进度。

图 1 给出三种典型情况:理想情况下,新旧变体在指定 GOP 对齐;请求延迟时,旧变体的同一 GOP 可能已大量进入在途队列;保守地请求更远的 GOP,又会拉长切换时间。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图1:HTTP-FLV 客户端控制 ABR 的三个问题(理想切换、请求延迟与起点过远)

2. 客户端执行切换为何造成带宽争抢

客户端执行方案在决定换码率后立即请求新变体,并以最近收到视频帧的 PTS 为 ts,设置 start_pos=ts+1。旧流继续发送,直到客户端确认目标旧 GOP 播放完成、且新流关键帧完整到达,再重置旧 QUIC 流。

问题出在 等待窗口 。为了避免画面回退,客户端通常要同时接收旧流和新流;而在最需要降码率的弱网中,这两条流恰好争抢同一瓶颈带宽。若新流未及时到达,客户端会在旧 GOP 剩余未播放时长低于 100 ms ,或 ABR 再次改变目标时,取消旧切换请求并重试。重试能提高容错,却无法消除重叠传输。

三、HTTP-FLV 自适应码率直播系统

1. 端到端架构

在我们的直播系统中,主播侧通过 RTC 服务器完成多人连麦混流,再封装为 FLV 并推入 CDN。CDN 入口节点把源流送往中心源站转码,生成多个码率变体;边缘节点按需从源站或中间层拉取。系统同时接入自建与第三方 CDN,单个变体可在故障时独立切到备用路径。直播链路实时经历采集、转码、源站到边缘拉取和最后一公里分发。不同变体独立转码,边缘只缓存最近数秒,冷门变体还会被淘汰。因此,多码率的“直播边缘”未必按 GOP 对齐,新变体也可能缓存未命中。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图2:TikTok Live 端到端 HTTP-FLV 直播架构(RTC 混流、多码率转码、多 CDN 与边缘分发)

2. 客户端 ABR 决策

客户端 ABR 算法由三个模块组成。第一个模块负责在客户端请求新的源流时选择初始码率。如果这不是应用进入前台后请求的第一条流,该模块可以使用最近的网络估计,例如服务端反馈;否则,它会参考客户端的历史观看情况,并为初始码率设置上限,以降低观看会话早期发生卡顿的风险。在未启用 ABR 的场景中,该模块也会采用更保守的初始码率策略。第二个模块负责周期性码率调整,定期判断客户端是否需要切换到其他码率版本。这是 ABR 控制逻辑的核心部分,主要借鉴已有 ABR 研究。执行周期可以根据 GOP 长度、设备电量等因素进行配置。第三个模块基于经验规则,在预设条件满足时立即触发。例如,当播放缓冲区即将耗尽,或客户端在数秒内连续发生多次卡顿时,客户端会立即请求更低码率的版本。该模块与周期性调整模块相互补充,使系统能够更快地响应网络波动。

3. 客户端执行切换

第一版 HTTP-FLV ABR 采用了与分段式协议类似的客户端侧控制逻辑。这样可以快速支持 HTTP-FLV 上的 ABR,同时尽量减少多家第三方 CDN 服务商的开发工作。

(1)新码率版本的起点

当 ABR 算法决定改变码率后,客户端立即请求相应的新版本。假设客户端最近收到的视频帧的呈现时间戳为 ts,请求 URL 中会加入 start_pos=ts+1。边缘服务器收到请求后,从本地缓存或上游拉取的数据中,选择 PTS 不小于 start_pos 的第一个关键帧开始发送。客户端因此不需要预测未来某个 GOP 中关键帧的精确时间戳。start_pos 遵循避免播放回退的经验原则,但系统并不保证每次切换都严格无缝。例如,下行拥塞可能使旧版本的传输进度落后于边缘节点上新版本最早的缓存帧。此时,边缘服务器可以直接发送已有的新版本内容。客户端可能看到 PTS 时间线上的间隔,但可以避免继续等待,并降低卡顿风险。

(2)实际切换点

发送切换请求时正在接收的 GOP,被视为旧版本的最后一个目标 GOP。客户端会继续渲染旧版本直到该 GOP 结束;即使新版本提前到达,也不会更早切换。同时,客户端还必须等待新版本的完整关键帧到达。由于 GOP 长度可能变化,客户端只有在完整收到下一个 GOP 的关键帧后,才能确认目标 GOP 已经结束。开发过程中曾尝试用启发式方法预测目标 GOP 的结束帧,但测试环境中的 QoE 收益有限。原因是实际切换完成前,服务器仍不能停止旧版本,因此这些方法无法明显减少旧版本的冗余传输。

如果客户端即将播放完旧版本的目标 GOP,而新版本仍未及时到达,它会继续播放旧版本,并在以下任一条件满足时重新发送切换请求:目标 GOP 中尚未渲染的帧少于配置的时长阈值,例如 100 ms ;或者 ABR 算法在此之前选择了其他码率。客户端会中止上一次请求,例如重置相应的 QUIC 流,并根据旧版本最新的接收进度重新设置 start_pos。新的请求不一定仍指向与上一次请求相同的 GOP。如果 ABR 算法在等待期间重新选择了当前旧版本,客户端会放弃本次切换,直到收到下一次码率调整决定。

(3)旧版本的终止

客户端完成切换后,立即重置旧版本对应的传输流。

4. 服务器执行切换

客户端执行切换的一个关键问题,是新旧码率版本之间不可避免的带宽争抢。在带宽受限的接入链路上,这种争抢可能在切换期间引发拥塞和卡顿。为此,我们尝试将 ABR 切换的执行移到服务器侧:边缘服务器独立决定切换点,该位置同时是新版本的起点和旧版本的终止点;客户端只需渲染服务器发送的媒体帧。

(1)会话令牌

服务器执行切换的前提,是边缘服务器能够把切换请求关联到已有观看会话。仅根据同一连接上复用的相同源流无法可靠识别会话,因为位于复用代理后的多个客户端可能产生多个这样的会话。因此,每次观看会话中的 HTTP 请求被分为初始源流请求和后续 ABR 切换请求。边缘服务器在初始请求的响应中返回 session token,客户端在后续切换请求中携带该 token。不同 CDN 服务商可以采用不同的计算方式,但 token 必须能唯一标识观看会话,例如同时到达的不同初始请求必须获得不同 token。

(2)切换过程

服务端切换的基本要求,是新版本的第一个关键帧不能引起 PTS 回退和播放倒退。切换请求成功关联到现有会话后,如果新版本未命中本地缓存,边缘服务器先向上游请求该版本。此后,服务器在发送旧版本的每个关键帧前执行切换检查。对于切换开始后的第一个旧版本关键帧,边缘服务器先以休眠方式等待新版本进入缓存,再等待新版本收到 DTS 不小于当前旧版本关键帧 DTS 的音频帧或视频帧。两段等待分别受 MaxCacheWaitTime 和 MaxWaitTime 约束,超过阈值后服务器停止等待。

满足以下任一条件时,服务器执行切换:第一,本地缓存中存在与当前旧版本关键帧具有相同 PTS 的新版本关键帧,此时时间线上没有 PTS 间隔;第二,当前旧版本关键帧的 PTS 小于新版本缓存中最老关键帧的 PTS,这表示旧版本的传输已经落后,并且不一定能很快追上。若两个条件都不满足,服务器继续发送旧版本,并在下一个 GOP 开始时再次检查。

(3)切换失败处理

不同 CDN 服务商可以分别设置超时阈值,超过阈值后切换被判定为失败。边缘服务器会在旧版本的 FLV 流中插入 script tag 通知客户端。客户端在收到失败标记、长时间未收到新版本,或 ABR 算法选择了其他码率时,发起新的请求。

如果切换进行期间收到的新请求仍指向同一目标版本,服务器继续当前切换;如果新请求指向当前旧版本,服务器撤销此前的切换请求;如果新请求指向第三个版本,服务器覆盖此前请求并重新开始切换过程。

(4)传输流复用

客户端 SDK 使用 QUIC,并将发往同一边缘服务器的 HTTP 请求复用在同一 QUIC 连接上。初始请求和同一源流的 ABR 切换请求可以借助本地状态完成关联。切换期间,CDN 服务商需要把旧版本和新版本流水化地发送在同一条 QUIC 流上。在新版本的第一个关键帧之前,服务器插入 FLV script tag 和序列头,例如 SPS 和 PPS,以启动客户端侧的解码与渲染。

与维护各码率版本的边缘媒体缓存相比,session token 的计算和存储成本几乎可以忽略;在等待新版本从源站获取时,服务器也不会让 CPU 持续忙等。因此,服务器执行切换增加的复杂度主要来自保证切换平滑所需的工程工作,并不会明显影响边缘服务器容量。

5. CCTK

准确的带宽估计会直接影响 ABR 算法的表现。许多已有方法通过客户端近期媒体分块的下载速度估算吞吐量;边缘服务器运行拥塞控制,因此能够直接提供更细粒度的带宽样本。系统据此建立了专用反馈通道,让客户端 ABR 算法使用服务端拥塞控制器的估计结果。系统在 QUIC 中定义了 CCTK(Congestion Control ToKen)控制帧。客户端 SDK 在握手消息中通过 transport parameter 声明是否需要拥塞反馈及反馈周期,边缘服务器在传输媒体数据时周期性发送 CCTK 帧。该机制已由主要 CDN 服务商支持多年,目前是客户端 ABR 算法默认的带宽估计来源。相比客户端自行观察吞吐量,CCTK 可以降低客户端网络估计的复杂度;由于反馈以连接为粒度,客户端同时请求多条源流时也不必逐会话观测。除带宽外,拥塞控制器还可以反馈 RTT、丢包率等传输层指标,为 ABR 决策提供更多输入。

CCTK 相关 IETF 提案:https://datatracker.ietf.org/doc/draft-yuan-quic-congestion-data/

6. 一致性哈希

自建 CDN 采用分层架构,并可在边缘与源站之间部署中间层,以降低源站流量压力。服务器拉取未缓存的码率版本时,不直接请求上游,而是先把请求发送给集群内代理节点。代理节点依据码率流名称通过一致性哈希确定,使同一集群不会同时向上游请求同一个码率版本。系统会定期发现集群内节点并分发服务器 IP 列表,各节点使用本地 IP 数据库计算代理节点,无需像跨层请求那样查询逻辑中心化的调度系统。该设计减少了容量更受限、成本更高的跨集群链路流量。虽然增加了一次集群内转发,但相对于跨层路径,其额外时延通常可以忽略;同时,中心调度器只需按集群粒度计算覆盖路由,并能改善小型集群的入口负载均衡。

四、大规模线上评估

1. 实验口径

服务器执行与客户端执行的代表性 A/B 实验持续 2 周 ,每天涉及超过 20 亿 观看会话。另一次在 2025 年 12 月进行的 ABR 开关实验中,开启与关闭两组每天各超过 10 亿 会话。观看会话指一名用户连续观看一个直播源,其间可能发生多次码率切换。

平滑切换定义为新变体首帧与旧变体末帧的 PTS 间隔小于 100 ms 。弱网筛选口径为带宽 2~5 Mbps 、RTT 50~200 ms 、丢包率 0.5%~5% 。论文因商业保密对 QoE 数据做了归一化,图中展示相对趋势与相对变化;视频和音频结论相近,正文只报告视频。

2. 服务器切换

全量会话中,服务器执行只改变短暂的切换阶段,整体卡顿率与频次仍分别下降 0.14% 和 0.21% ,且达到 95% 置信水平。弱网子集中效果被明显放大:卡顿率下降 28.7% ,卡顿频次下降 19.1% 。降码率时,切换成功率提高 1.6% ,平滑切换率提高 35.5% ,单次切换卡顿时长下降 13.3% 。升码率对应变化为 0.38% 、0.22% 和下降 13.2% 。降档收益更大,辅助印证带宽争抢在拥塞时最为危险。图 3 把升档与降档的成功率、平滑率和单次卡顿时长并列展示,可以发现服务器执行切档在六项指标上均优于客户端执行。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图3:服务器执行(SES)与客户端执行(CES)的切换指标对比(升档与降档)

3. ABR 整体收益

与关闭 ABR 相比,完整 HTTP-FLV ABR 使整体视频卡顿率下降 4.7% 、卡顿频次下降 3.3% ,平均码率提升 10.8% 。图 4 显示两周内三项归一化指标的日趋势。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图4:HTTP-FLV 启用 ABR 后的整体 QoE(卡顿率、卡顿频次与平均码率)

网络良好时,ABR 仍能处理短时波动,并把平均码率提高 14.5% ;弱网时,它选择更低码率换取稳定播放,卡顿率降低 9.8% ,平均码率相应下降 6.6% 。这说明评价 ABR 不能只看“码率是否更高”,而要看其是否在不同网络区间做出合理交换。

用户侧结果是 ABR 直播的人均日观看时长增加 0.2% ,达到 95% 置信水平。相对增幅看似不大,在全球流量规模下对应每天至少数千小时新增观看。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图5:启用 ABR 后,人均日观看时长提升 0.2%

4. CCTK 与缓存

CCTK 在 HTTP-FLV ABR 开发前已全量部署,因此论文没有“关闭 CCTK”的独立对照实验。一个联合实验案例显示,激进初始发送速率让 1080P 请求比例增加 0.49% ,却使 1080P 视频卡顿率上升 2.1% 。它证明了反馈准确性会影响 ABR,但不能单独量化 CCTK 的净收益。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图6:CCTK 案例——激进初始速率提高 1080P 请求比例,也抬高 1080P 卡顿率

缓存命中带来的收益更直接。客户端请求命中边缘缓存时,卡顿率比未命中低 35.9% ;集群内请求经一致性哈希后命中边缘缓存时,服务器侧估算的卡顿率低 50.3% 。两组数据来自单一国家的代表性线上结果,说明直播 ABR 不能假设所有变体已经在边缘就绪。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图7:边缘缓存命中与未命中的卡顿率差异

五、实践经验与开放问题

1. QUIC 发送缓冲区

服务器决定切换并不等于新流立刻上网。早期实现中,旧变体的若干帧已堆在 QUIC 发送缓冲区;降码率通常伴随拥塞,新变体只能继续排队。当前实现每个 GOP 写入关键帧前检查缓冲深度,未发送数据降到较小阈值后再写入,只在每个 GOP 执行一次,以免链路利用率过低。

2. 负 start_pos

初始播放和服务器向上游拉流时,系统允许使用负数 start_pos,单位为毫秒。若本地缓存足够,服务器从直播边缘之前指定时长的关键帧开始发送。它用少量端到端延迟换取更短首帧时间和更厚的初始缓冲,参数需要结合业务延迟目标调节。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图8:负数 start_pos 的语义——从直播边缘之前的关键帧开始发送

3. 多 CDN 容错

服务端执行没有取消客户端跨缓存、跨 CDN 逃生的能力。切换连续失败时,客户端可换域名向另一 CDN 发起新的初始请求,目标码率仍由客户端 ABR 决定。多 CDN 的故障切换还可细化到单个码率变体,避免一个转码配置问题拖累整条直播。

4. 本地中间层

中间层越靠近边缘,边缘到中间层链路越稳定。论文选取一个国家,将原本跨国访问的中间层改为本地部署后,单会话视频卡顿率下降 7.9% 。但每个国家都部署中间层并不经济,实际策略是当地及周边用户规模达到阈值后再建设。

基于 HTTP-FLV 的自适应码率直播流:一种实用系统视角
图9:本地中间层上线后,单会话视频卡顿率下降 7.9%

5. 适用边界

  • 单一平台: 结论来自 TikTok Live 及其自建、第三方 CDN 组合,不能直接外推到所有直播业务。
  • 归一化数据: 绝对 QoE 值因商业保密未披露,读者只能核验相对变化与实验口径。
  • 工程复杂度: 边缘服务器需要会话 token、媒体时间戳、关键帧识别、超时重试与跨 CDN 处理,第三方 CDN 也要配合改造。

六、结论

HTTP-FLV 把切换粒度做得更细,也让传统客户端控制失去天然分段边界。TikTok Live 的生产实践给出了一条清晰分工: 客户端决定码率,服务器执行切换 。服务器掌握新旧变体、GOP、缓存和上游拉流状态,能把新流起点、旧流终点与实际切换点合并为一个决定,从机制上缩短带宽争抢窗口。十亿级 A/B 实验说明,非算法机制足以带来可测的 QoE 与观看时长收益;CCTK、一致性哈希和本地中间层又表明,ABR 表现取决于传输反馈与 CDN 缓存路径,而不只是客户端公式。代价同样明确:边缘从无状态内容分发节点变成切换控制环的一部分,工程复杂度和跨 CDN 协作成本必须纳入设计。对正在设计 HTTP-FLV、长连接推流或 MOQT 开放订阅的团队,该文章最值得复用的不是某个阈值,而是职责判断:让最了解用户状态的一侧选码率,让最了解媒体与传输进度的一侧完成切换。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

赞 (0)

相关推荐