M3U8 協定原理
從传输方式上看,HLS 做的事情並不神秘:用普通 HTTP,把一段長影片拆成很多小檔案,一块块地往外推。m3u8 只是负责把這些小檔案“串起來”。
從推流到播放,大致链路是這樣的
- 编碼器:把音影片编碼成 H.264/H.265 + AAC 等碼流。
- 切片器:每幾秒切一片,生成 TS / fMP4 小檔案。
- m3u8 生成器:不断更新播放列表,把最新分片追加进去。
- CDN:负责把 m3u8 和分片稳稳地“托运”到离使用者最近的節點。
- 播放器 / SDK:循环下載 m3u8 和分片,解碼後渲染到屏幕。
主播放列表和多碼率子列表
為了适配不同網路环境,HLS 允許你為同一路內容准备多套畫質,每一套都有自己的 m3u8。然後再用一個“总表”把它們串在一起,類似下面這種结构:
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1600000,RESOLUTION=1280x720
mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=1920x1080
high/index.m3u8
播放器拿到這個“主播放列表”後,會先選擇一條合适的碼率(比如從中档開始),播放過程中再根据实時帶寬情况决定是否切換到高碼率或低碼率。
客户端是怎麼“追著最新片段跑”的
在直播场景下,m3u8 並不是一次性寫完的,而是不断被更新。客户端通常會:
- 每隔幾秒重新請求一次 m3u8;
- 比對新旧列表,找出還沒拉過的新分片;
- 把這些新分片按顺序拉取、解碼、播放;
- 根据缓冲区情况,适當“追赶”到更接近实時的位置。
這也是為什麼你在抓包時會看到播放器不断地去拉同一個 index.m3u8 檔案。
為什麼要理解這些原理
知道協定大致怎麼运轉,有幾個很直接的好處:
- 排查問題時,你能很快判断到底是 m3u8 寫得不對,還是分片有問題;
- 设计业务時,能更有意識地去设计碼率層級、切片長度和快取策略;
- 遇到「能播但很卡」「快進不流畅」之類的問題時,也有更明確的优化方向。