第一次接觸 M3U8 的人,常見的理解是「打開看起來就是一堆網址列表,逐行下載就好」。這個理解在最簡單的情境下成立,但 M3U8 這份索引清單其實帶著不少中繼資料,忽略它們會在後面幾天陸續踩到坑。
一份最基本的 Media Playlist 大致長這樣:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:8.0,
segment000.ts
#EXTINF:8.0,
segment001.ts
#EXT-X-ENDLIST
拆開來看:
#EXTM3U:檔案格式宣告,第一行固定要有#EXT-X-VERSION:這份清單使用的 HLS 協定版本,會影響哪些標籤是合法的#EXT-X-TARGETDURATION:片段的目標長度上限(秒),用來讓播放器預估緩衝策略#EXTINF:緊接在片段網址前面,宣告這一段片段實際的播放長度#EXT-X-ENDLIST:宣告這是一份完整、不會再新增片段的清單(點播內容通常會有這個標籤;直播串流則沒有,因為片段還在持續產生)#EXT-X-ENDLIST 這個標籤,決定了「這份清單到底是不是已經完整」——如果程式邏輯只認片段數量,沒去檢查這個標籤,遇到直播型態的清單(片段還在持續新增)就會誤判成「已經抓完了」,實際上內容還沒真正結束。#EXTINF 宣告的片段長度,也是驗證下載完整性的一個線索:如果某個片段下載下來的實際長度跟宣告的落差過大,代表這個片段可能有問題。
M3U8 有明確的規格(RFC 8216),標籤種類跟語法規則不少,自己用字串處理去解析容易漏掉邊界情況。實務上會用現成的 M3U8 解析函式庫,把「這份清單解析出的物件結構長什麼樣」這件事交給函式庫負責,程式碼只需要專注在「怎麼使用解析結果」。
如果你的程式碼曾經處理過某種有明確規格的格式(設定檔、資料交換格式),你是自己刻解析邏輯,還是用現成的規格解析器?自己刻的部分,有沒有涵蓋到規格裡你當初沒注意到的邊界情況?
明天講 M3U8 的巢狀結構:Master playlist 跟 Media playlist 的差別,為什麼有時候要多繞一層才拿得到真正的片段清單。