延迟是直播业务绕不开的话题。一场电商带货直播里,主播已经讲完商品开始回复评论,观众端却还停留在几秒前的画面,弹幕和画面完全对不上,这种割裂感会直接拉低转化率。传统的HLS协议基于ts切片加m3u8索引的结构,切片通常在3到10秒,播放器还要缓冲多个切片防止卡顿,延迟叠加后轻松超过15秒。腾讯云CDN针对这个问题给出了两条低延迟路径:一是改进版的LL-HLS,走HTTP体系,兼容性好;二是WebRTC推流加播放,延迟可以压到1秒以内。这两条路线各有取舍,本文详细拆解。

直播延迟到底是怎么产生的
要理解低延迟方案,先得弄清楚延迟从哪来。一套典型的直播链路是:推流端编码压缩,经过推流协议上行到源站,源站转码处理后切片打包,CDN分发到边缘节点,播放器拉流解码渲染。每一环都会引入延迟,但大头集中在三处。
第一处是编码端的GOP结构。视频编码为了压缩率,采用I帧、P帧、B帧的组合,播放端必须从I帧开始解码。GOP越长压缩率越高,但观众等待下一个I帧的时间也越长。低延迟场景通常把GOP设为1到2秒,甚至要求编码器输出关键帧间隔与切片时长对齐。
第二处是切片和缓冲。传统HLS把直播流切成固定时长的ts文件,播放器需要至少缓存3个切片才能起播,切片6秒的话光缓冲就是18秒。LL-HLS的核心改进就是把切片进一步拆成小分块,让播放器不必等完整切片下载完就能开始解码。
第三处是协议交互开销。RTMP和HLS都基于TCP,TCP的队头阻塞、三次握手、慢启动都会增加延迟,而WebRTC直接走UDP加RTP,配合SRTP加密,把传输层的开销压到最低,这就是它能做到亚秒级延迟的根本原因。
LL-HLS在腾讯云CDN上的原理与配置
LL-HLS是Apple在HLS基础上扩展的低延迟版本,协议版本号7以上。它保留了m3u8加ts的基础结构,但引入了几个关键机制:PART标签把一个大切片拆成多个小分块,通常每个分块只有200到500毫秒的内容;播放器通过阻塞式请求EXT_X_PRELOAD_HINT指定的分块,服务端在分块生成后才返回响应,实现准实时拉取;再加上EXT_X_SERVER_CONTROL里的CAN-BLOCK-RELOAD和PART-HOLD-BACK参数控制播放器追帧位置。
腾讯云CDN在控制台的域名管理中提供了LL-HLS能力,需要在播放域名下开启低延迟HLS配置。开启后CDN边缘节点会实时接收上游的流数据,按配置的分块时长切出fMP4分片,并动态生成包含PART信息的m3u8播放列表。一个典型的LL-HLS响应列表如下:
#EXTM3U #EXT-X-TARGETDURATION:4 #EXT-X-VERSION:9 #EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=1.5,CAN-SKIP-UNTIL=12.0 #EXT-X-PART-INF:PART-TARGET=0.4 #EXT-X-MEDIA-SEQUENCE:266 #EXT-X-MAP:URI="init.mp4" #EXT-X-PROGRAM-DATE-TIME:2024-05-20T08:30:00.000Z #EXT-X-PART:DURATION=0.4,URI="filePart273.4.mp4" #EXT-X-PART:DURATION=0.4,URI="filePart273.5.mp4" #EXT-X-PRELOAD-HINT:TYPE=PART,URI="filePart273.6.mp4" #EXTINF:4.0, fileSequence273.mp4
播放器侧拿到这个列表后,会直接请求PRELOAD-HINT指向的分块并保持长连接等待,服务端在400毫秒左右的分块生成后立即返回。这样播放器始终追在直播边缘附近,配合1.5秒左右的PART-HOLD-BACK参数,端到端延迟一般能控制在2到4秒。相比传统HLS动辄15秒以上的延迟,改善非常明显,同时它仍然是标准HTTP流量,天然穿透各种防火墙和企业网络,CDN分发也复用现有节点和缓存体系,成本几乎不变。
需要注意的是,LL-HLS的延迟下限受分块时长约束,想再往下压延迟就需要推流端GOP足够短、分块切得更细,但这会增加请求数量和源站切片压力。实践中0.4秒的分块是比较均衡的选择。
WebRTC推流的实践与调优
如果说LL-HLS是渐进式改良,WebRTC就是为实时通信而生的方案,端到端延迟可以做到500毫秒到1秒。腾讯云直播的快直播(Lean HLS之外的另一条线)底层正是基于WebRTC的UDP传输。它的优势在于:RTP包级别的时间戳和序列号支持精细的丢包重传(NACK)、前向纠错(FEC)以及抖动缓冲(JitterBuffer),播放器可以根据网络状况动态调整缓冲深度,而不是像HLS那样固定缓存。
推流端接入腾讯云快直播,推荐使用腾讯云的 LiteAV SDK,它会处理好编码、打包、NACK、带宽估计这些细节。如果需要自己实现,可以用WHIP协议向腾讯云的推流地址发起WebRTC协商。下面是一段基于浏览器的推流示例代码:
// 从摄像头和麦克风采集音视频
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 1280, height: 720, frameRate: 30 },
audio: true
});
// 创建RTCPeerConnection并添加轨道
const pc = new RTCPeerConnection();
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// 生成SDPOffer并通过WHIP接口推送到腾讯云
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const response = await fetch('https://push.example.whip地址/v1/whip', {
method: 'POST',
headers: { 'Content-Type': 'application/sdp' },
body: offer.sdp
});
// 用服务端返回的SDP完成协商
await pc.setRemoteDescription({
type: 'answer',
sdp: await response.text()
});推流参数上有几个调优点值得注意。编码建议使用H264,硬编硬解兼容性最好,GOP设置为1秒并开启B帧为0,B帧会引入解码顺序依赖,增加延迟。音频用Opus编码,码率控制在64kbps左右即可。浏览器推流时务必使用HTTPS页面,getUserMedia在非安全上下文中会被禁用。
播放端同样用WebRTC拉流,腾讯云提供whep风格的播放地址,也可以直接用LiteAV播放SDK。抖动缓冲的设置直接影响延迟和流畅度的平衡:缓冲设置小,延迟低但弱网下容易卡顿;缓冲设置大则相反。一般互动场景把播放端缓冲设置在200到500毫秒之间。
两种方案怎么选:对比与组合策略
LL-HLS和WebRTC并不是非此即彼的关系,关键看业务对延迟的容忍度和终端环境。下面这个表格汇总了核心差异:
| 对比维度 | LL-HLS | WebRTC快直播 |
|---|---|---|
| 端到端延迟 | 2至4秒 | 500毫秒至1秒 |
| 传输协议 | HTTP/TCP | UDP(RTP/SRTP) |
| 并发承载能力 | 极高,复用CDN缓存 | 高,但边缘节点资源消耗更大 |
| 防火墙穿透 | 极好,标准HTTP流量 | 部分企业网络限制UDP |
| 播放器兼容性 | Safari原生支持,其他端需LL-HLS播放器 | 需集成WebRTC播放能力 |
| 成本 | 与普通HLS接近 | 略高,计费按流量或带宽 |
从表格可以看出,如果是单向的千人、万人级大场面直播,比如赛事直播、发布会直播,观众只看不互动,2到4秒的LL-HLS延迟完全够用,而且它扛并发的能力和成本优势非常突出。如果是连麦、语聊房、在线教育小班课这类强互动场景,几百毫秒的感知差异都影响体验,那就必须上WebRTC。
实际业务中还有一种常见组合:主播端用WebRTC推流实现低延迟上行,云端转码后同时输出LL-HLS和标准HLS两路流,互动观众走快直播,普通观众走LL-HLS或HLS。这种分层分发策略在腾讯云上可以通过一个推流域名配置多个播放域名来实现,既照顾了体验又控制了成本。
最后提醒一点,低延迟是全链路的工程,协议只是其中一环。推流端的GOP设置、编码器延迟、CDN回源链路质量、播放器缓冲策略,任何一环配置不当都会把辛苦省下来的延迟又吃回去。上线前建议用腾讯云控制台提供的延迟监测工具做全链路压测,把每一跳的延迟量化出来,才能真正稳住最终的观看体验。