探索 HLS 动态片头广告和中插广告
Explore dynamic pre-rolls and mid-rolls in HLS
2021年6月11日
一句话判断
如果你在做视频广告插播系统,HLS 的 #EXT-X-DATERANGE 加上新引入的 #EXT-X-SERVER-CONTROL 已经能实现广播级的片头和中插广告无缝切换——不必再靠客户端硬切了。
这场 Session 讲了什么
Session 介绍了 HTTP Live Streaming(HLS)在广告插播方面的能力更新,重点是如何在直播和点播流中动态插入 pre-roll(片头广告)和 mid-roll(中插广告)。过去在 HLS 中做广告插播主要有两个痛点:一是广告和正片的切换不够丝滑,用户会看到明显的黑帧或卡顿;二是直播场景下广告时机难以控制。
Apple 的方案是将广告插播点(Ad Insertion Point)用 #EXT-X-DATERANGE 标签在 playlist 中标记,播放器看到标签后自动请求广告内容。对于直播流,新增的 #EXT-X-SERVER-CONTROL 标签让服务器可以控制播放器的缓冲行为,在广告窗口期间提前预加载广告内容,确保切换时零延迟。Session 还讨论了广告内容的编码匹配问题——广告和正片的编码参数(分辨率、码率、codec)越接近,切换越流畅。
值得深挖的点
CUE-OUT / CUE-IN 标记与 DATERANGE 的结合
传统广播系统用 SCTE-35 标记广告窗口。HLS 通过 #EXT-X-DATERANGE 的 SCTE35-OUT 和 SCTE35-IN 属性来承载这些标记。但 Apple 新增了一种更简洁的方式:直接用 END-DATE 属性标记广告窗口的结束时间。播放器看到 START-DATE 后就知道接下来 N 秒是广告时段,可以提前准备。关键是 PLANNED-DURATION 属性——它让播放器在广告还没实际到达时就能预留正确的缓冲窗口,避免因缓冲不足导致的卡顿。
Bitrate 和 Codec 匹配对无缝切换的影响
广告素材和正片内容的编码参数差异是广告切换不丝滑的根源。Session 给出了一个很实用的建议:广告素材的 HLS variant 列表应该和正片的 variant 列表使用完全相同的编码参数——同样的分辨率阶梯、同样的码率范围、同样的 codec profile。这样播放器在切换时不需要重新选择 variant,解码器也不需要重新初始化。做不到完全匹配的情况下,至少保证 GOP(Group of Pictures)对齐,让切换点落在 I-frame 上。
代码片段
# 使用 EXT-X-DATERANGE 标记直播流中的广告窗口
# 播放器看到此标记后请求广告内容
#EXT-X-DATERANGE:ID="ad-break-001",
CLASS="com.apple.hls.interstitial",
START-DATE="2021-06-11T15:30:00.000Z",
DURATION=30.000,
X-ASSET-URI="https://ads.example.com/preroll.m3u8",
X-RESUME-OFFSET=0.0
# 服务器控制标签——告诉播放器预加载策略
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,
CAN-SKIP-UNTIL=30.0,
PART-HOLD-BACK=3.0
# 直播 playlist 中标记广告时机
#EXT-X-PROGRAM-DATE-TIME:2021-06-11T15:29:50.000Z
#EXTINF:10.0,
segment-001.ts
#EXT-X-DATERANGE:ID="cue-out-1",
SCTE35-OUT=0xFC002E...,START-DATE="2021-06-11T15:30:00Z",
DURATION=120.000
# 广告内容的 variant playlist 应与正片编码参数一致
# 确保切换时无需重新初始化解码器
# 正片 variant
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.640028"
main_1080p.m3u8
# 广告 variant——相同的编码参数
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.640028"
ad_1080p.m3u8
最佳实践
- 广告和正片使用完全相同的编码配置文件(encoding profile),包括分辨率阶梯、码率、帧率和 GOP 大小。这是实现无缝切换的前提条件。
- 在直播场景中使用
CAN-BLOCK-RELOAD=YES让服务器控制 playlist 更新节奏,配合PART-HOLD-BACK参数确保播放器在广告窗口前有足够的缓冲。 - 广告素材预生成多个码率版本并缓存到 CDN 边缘节点,避免用户等待广告内容下载而看到空白画面。
还有什么值得关注
- AVPlayer 的
currentItemInterstitialTimeRangesAPI 可以让你监听广告时段的开始和结束,用来更新 UI(比如显示”广告中”提示)。 - macOS Monterey 的 Safari 15 也支持了 HLS interstitial 的标准标记,Web 端和原生端的广告插播行为趋于一致。
- Apple 推荐使用 Media Source Extensions(MSE)作为 Web 端广告插播的备选方案,当原生 HLS 播放不可用时。