今天來介紹 HLS 直播協議。

HLS 全名 HTTP Live Streaming ,是由蘋果提出的媒體傳輸協議,看到 HTTP 一詞,就知道這個協議是走HTTP協定的。

HLS的影片不一定要是直播影片,也可以是非直播 (具有明確片長、完整的影片),其核心是 .m3u8.ts 這兩個檔案,與其說 m3u8 是個影片檔案,倒不如說, .m3u8 只是個文件,這個文件記錄了影片檔的位置與其設定。

而 HLS 的原理,其實是將影片拆成一個一個的.ts檔案,每個.ts 就是幾秒影片片段,.ts封裝了影像與聲音,透過 HTTP 協定扔給前端,藉此連續播放一個個不同的片段,來達成影片的播放 ( 注意這裡的 .ts 不是指 TypeScript )。

一個 HLS 的影片連結會是這樣:
https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8

我們用Chrome 擴充套件 Native HLS Playback來播放這個連結

播放後,打開 Chrome 開發者工具到 Network 去,會發現前端不斷獲得一個一個.ts檔案

所以若是播放 HLS 時影片卡住,即可能代表當前 .ts 已經播完,但瀏覽器端還未獲取下個 .ts 檔案。

前面有說過 .m3u8 比較像個文件,我們也可以把它載回來看看:下載的方式很簡單,直接在瀏覽器端輸入.m3u8連結,瀏覽器就會自動下載下來。

但因為我們現在裝了 Native HLS Playback , 所以我們改用在無痕模式輸入.m3u8連結 ( 或者用Postman也可以 )

m3u8檔案

直接把這個檔案拖扔進任一編輯器或 IDE 看看

每個HLS影片(m3u8)影片內的東西都大同小異,也許有讀者用編輯器開啟自己找的 m3u8 連結,裡頭行數很少,或者都是一堆.ts檔也不一定。

m3u8 文件內容,會依照影片源在後端的設定而有所不同,有的 m3u8 文件裡頭就是一個一個的.ts檔案,這是很正常的, m3u8 文件會依照所保存的.ts相對位置,向後端索取對應.ts檔案,那為什麼我上面開啟的 m3u8 文件沒有呢?

有的 HLS 影片設計,會是透過一個主要的 m3u8 檔案 ( Master ),裡頭再包含同影片不同畫質音質 的 m3u8 連結,播放器透過切換這些相對連結路徑 ( 或是在不同頻寬下自動切換) ,向後端索取相應的資料 (例如 .ts 檔 )。

圖片來源:蘋果官方文件

什麼意思呢?來試試一次就知道了,以第14、15行為例:

EXT-X-STREAM-INF 代表 HLS 會依照使用者播放環境,讓 masterplaylist 決定主使用哪個 m3u8 。
這麼做的好處是能提高使用者體驗 ( 因為使用者可以手動切換畫質,或是讓影片自動切換對應的畫質連結),缺點是後端相同的影片,就要出好幾種版本,對server負擔會相對重一點。

以這個影片為例,同樣的內容它就分成了 250kbit、500kbit、800kbit、1100kbit、1500kbit、4000kbit、6000kbit、10000kbit 共 8 種 m3u8 連結。

了解上面的內容後,video/250kbit.m3u8 這串很明顯就是個連結,我們把它和當前連結:
https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8
做局部的替換,試試把連結改成這樣:
https://bitdash-a.akamaihd.net/content/sintel/hls/video/250kbit.m3u8

Native HLS Playback 去播放

也許圖片看不太出來,但是影片畫質很明顯地變差了。
接著我再用無痕模式或 Postman 把這個 m3u8 文件抓下來。
https://bitdash-a.akamaihd.net/content/sintel/hls/video/250kbit.m3u8

一樣用編輯器打開

我們可以看到一個一個的.ts#EXTINF其實就是時間秒數,這裡還可以再驗證,用一樣的方式把.ts檔抓下來:
這裡我隨便以 seq-10.ts 為例,連結組成這樣:
https://bitdash-a.akamaihd.net/content/sintel/hls/video/250kbit/seq-10.ts

把它下載下來

現在這個.ts片段可以透過播放器應用程式開啟

這邊附上連結,大家可以自己比較其差異。

Master Playlist
https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8

Media Playlist (250kbit)
https://bitdash-a.akamaihd.net/content/sintel/hls/video/250kbit.m3u8

.ts (250kbit)
https://bitdash-a.akamaihd.net/content/sintel/hls/video/250kbit/seq-10.ts

但這已經到 HLS 檔案的設計部份了,另外關於 m3u8 連結內的
#EXTM3U#EXT-X-MEDIA-SEQUENCE#EXT-X-TARGETDURATION#EXT-X-MEDIA....等等標示,這裡就不贅述,更進一步的資訊,可參考蘋果官方文件
 
 
 
最後,HLS 這個格式當初有很大部分是為了 HTML5 以及手機而出的,所以在除了手機瀏覽器與蘋果旗下產品瀏覽器外,支援度還不夠全面。

雖然原生支持率僅有 55% , 但前端仍可以透過 hls.js 或其他 Library 、播放器播放,退步一點的作法連瀏覽器端 Flash 也能播放 HLS。

有蘋果大力推動 HLS ,我是覺得沒有到 is being replaced 這麼嚴重啦....

 
 
 
 
參考
蘋果官方文件
直播協定 hls 筆記