今天來介紹一下HLS協議,這個協議是由蘋果公司提出並推廣開來的。來一段維基百科的定義。
HTTP Live Streaming(縮寫是HLS)是一個由蘋果公司提出的基於HTTP的流媒體網絡傳輸協議。是蘋果公司QuickTime X和iPhone軟件系統的一部分。它的工作原理是把整個流分成一個個小的基於HTTP的文件來下載,每次只下載一些。當媒體流正在播放時,客戶端可以選擇從許多不同的備用源中以不同的速率下載同樣的資源,允許流媒體會話適應不同的數據速率。在開始一個流媒體會話時,客戶端會下載一個包含元數據的extended M3U (m3u8)playlist文件,用於尋找可用的媒體流。
HLS只請求基本的HTTP報文,與實時傳輸協議(RTP)不同,HLS可以穿過任何允許HTTP數據通過的防火牆或者代理服務器。它也很容易使用內容分發網絡來傳輸媒體流。
蘋果公司把HLS協議作爲一個互聯網草案(逐步提交),在第一階段中已作爲一個非正式的標準提交到IETF。但是,即使蘋果偶爾地提交一些小的更新,IETF卻沒有關於制定此標準的有關進一步的動作。[1]
協議簡介
HLS協議規定:
- 視頻的封裝格式是TS。
- 視頻的編碼格式爲H264,音頻編碼格式爲MP3、AAC或者AC-3。
- 除了TS視頻文件本身,還定義了用來控制播放的m3u8文件(文本文件)。
爲什麼蘋果要提出HLS這個協議,其實他的主要是爲了解決RTMP協議存在的一些問題。比如RTMP協議不使用標準的HTTP接口傳輸數據,所以在一些特殊的網絡環境下可能被防火牆屏蔽掉。但是HLS由於使用的HTTP協議傳輸數據,不會遇到被防火牆屏蔽的情況(該不會有防火牆連80接口都不放過吧)。
另外於負載,RTMP是一種有狀態協議,很難對視頻服務器進行平滑擴展,因爲需要爲每一個播放視頻流的客戶端維護狀態。而HLS基於無狀態協議(HTTP),客戶端只是按照順序使用下載存儲在服務器的普通TS文件,做負責均衡如同普通的HTTP文件服務器的負載均衡一樣簡單。
另外HLS協議本身實現了碼率自適應,不同帶寬的設備可以自動切換到最適合自己碼率的視頻播放。其實HLS最大的優勢就是他的親爹是蘋果。蘋果在自家的iOS設備上只提供對HLS的原生支持,並且放棄了flash。Android也迫於平果的“淫威”原生支持了HLS。這樣一來flv,rtmp這些Adobe的視頻方案要想在移動設備上播放需要額外下點功夫。當然flash對移動設備造成很大的性能壓力確實也是自身的問題。
但HLS也有一些無法跨越的坑,比如採用HLS協議直播的視頻延遲時間無法下到10秒以下,而RTMP協議的延遲最低可以到3、4秒左右。所以說對直播延遲比較敏感的服務請慎用HLS。
圖片來源於蘋果官網
來解釋一下這張圖,從左到右講,左下方的inputs的視頻源是什麼格式都無所謂,他與server之間的通信協議也可以任意(比如RTMP),總之只要把視頻數據傳輸到服務器上即可。這個視頻在server服務器上被轉換成HLS格式的視頻(既TS和m3u8文件)文件。細拆分來看server裏面的Media encoder的是一個轉碼模塊負責將視頻源中的視頻數據轉碼到目標編碼格式(H264)的視頻數據,視頻源的編碼格式可以是任何的視頻編碼格式(參考《視頻技術基礎》)。轉碼成H264視頻數據之後,在stream segmenter模塊將視頻切片,切片的結果就是index file(m3u8)和ts文件了。圖中的Distribution其實只是一個普通的HTTP文件服務器,然後客戶端只需要訪問一級index文件的路徑就會自動播放HLS視頻流了。
HLS的index文件
所謂index文件就是之前說的m3u8文本文件。
圖片來源於蘋果官網
如上圖所示,客戶端播放HLS視頻流的邏輯其實非常簡單,先下載一級Index file,它裏面記錄了二級索引文件(Alternate-A、Alternate-B、Alternate-C)的地址,然後客戶端再去下載二級索引文件,二級索引文件中又記錄了TS文件的下載地址,這樣客戶端就可以按順序下載TS視頻文件並連續播放。
一級index文件
視頻源:https://dco4urblvsasc.cloudfront.net/811/81095_ywfZjAuP/game/index.m3u8
-
#EXTM3U
-
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1064000
-
1000kbps.m3u8
-
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=564000
-
500kbps.m3u8
-
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=282000
-
250kbps.m3u8
-
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2128000
-
2000kbps.m3u8
bandwidth指定視頻流的比特率,PROGRAM-ID無用無需關注,每一個#EXT-X-STREAM-INF的下一行是二級index文件的路徑,可以用相對路徑也可以用絕對路徑。例子中用的是相對路徑。這個文件中記錄了不同比特率視頻流的二級index文件路徑,客戶端可以自己判斷自己的現行網絡帶寬,來決定播放哪一個視頻流。也可以在網絡帶寬變化的時候平滑切換到和帶寬匹配的視頻流。
-
#EXTM3U
-
#EXT-X-PLAYLIST-TYPE:VOD
-
#EXT-X-TARGETDURATION:10
-
#EXTINF:10,
-
2000kbps-00001.ts
-
#EXTINF:10,
-
2000kbps-00002.ts
-
#EXTINF:10,
-
2000kbps-00003.ts
-
#EXTINF:10,
-
2000kbps-00004.ts
-
#EXTINF:10,
-
... ...
-
#EXTINF:10,
-
2000kbps-00096.ts
-
#EXTINF:10,
-
2000kbps-00097.ts
-
#EXTINF:10,
-
2000kbps-00098.ts
-
#EXTINF:10,
-
2000kbps-00099.ts
-
#EXTINF:10,
-
2000kbps-00100.ts
-
#ZEN-TOTAL-DURATION:999.66667
-
#ZEN-AVERAGE-BANDWIDTH:2190954
-
#ZEN-MAXIMUM-BANDWIDTH:3536205
-
#EXT-X-ENDLIST
二級文件實際負責給出ts文件的下載地址,這裏同樣使用了相對路徑。#EXTINF表示每個ts切片視頻文件的時長。#EXT-X-TARGETDURATION指定當前視頻流中的切片文件的最大時長,也就是說這些ts切片的時長不能大於#EXT-X-TARGETDURATION的值。#EXT-X-PLAYLIST-TYPE:VOD的意思是當前的視頻流並不是一個直播流,而是點播流,換句話說就是該視頻的全部的ts文件已經被生成好了,#EXT-X-ENDLIST這個表示視頻結束,有這個標誌同時也說明當前的流是一個非直播流。
播放模式
-
點播VOD的特點就是當前時間點可以獲取到所有index文件和ts文件,二級index文件中記錄了所有ts文件的地址。這種模式允許客戶端訪問全部內容。上面的例子中就是一個點播模式下的m3u8的結構。
-
Live 模式就是實時生成M3u8和ts文件。它的索引文件一直處於動態變化的,播放的時候需要不斷下載二級index文件,以獲得最新生成的ts文件播放視頻。如果一個二級index文件的末尾沒有#EXT-X-ENDLIST標誌,說明它是一個Live視頻流。
客戶端在播放VOD模式的視頻時其實只需要下載一次一級index文件和二級index文件就可以得到所有ts文件的下載地址,除非客戶端進行比特率切換,否則無需再下載任何index文件,只需順序下載ts文件並播放就可以了。但是Live模式下略有不同,因爲播放的同時,新ts文件也在被生成中,所以客戶端實際上是下載一次二級index文件,然後下載ts文件,再下載二級index文件(這個時候這個二級index文件已經被重寫,記錄了新生成的ts文件的下載地址),再下載新ts文件,如此反覆進行播放。
文/我在睡覺(簡書作者)
原文鏈接:http://www.jianshu.com/p/426425cad08a
著作權歸作者所有,轉載請聯繫作者獲得授權,並標註“簡書作者”。