一、HLS 概述
HLS 全稱是 HTTP Live Streaming,是一個由 Apple 公司提出的基於 HTTP 的媒體流傳輸協議,用於實時音視頻流的傳輸。目前HLS協議被廣泛的應用於視頻點播和直播領域。
1. 原理介紹:
通過將整條流切割成一個小的可以通過 HTTP 下載的媒體文件, 然后提供一個配套的媒體列表文件, 提供給客戶端, 讓客戶端順序地拉取這些媒體文件播放, 來實現看上去是在播放一條流的效果.由於傳輸層協議只需要標准的 HTTP 協議, HLS 可以方便的透過防火牆或者代理服務器, 而且可以很方便的利用 CDN 進行分發加速, 並且客戶端實現起來也很方便.
2. 整體架構
HLS的架構分為三部分:Server,CDN,Client 。即服務器、分發組件和客戶端。
下面是 HLS 整體架構圖:

服務器用於接收媒體輸入流,對它們進行編碼,封裝成適合於分發的格式,然后准備進行分發。
分發組件為標准的 Web 服務器。它們用於接收客戶端請求,傳遞處理過的媒體,把資源和客戶端聯系起來。
客戶端軟件決定請求何種合適的媒體,下載這些資源,然后把它們重新組裝成用戶可以觀看的連續流。
二、HLS 播放
1. 播放未加密HLS
HLS格式的視頻,只有安卓4.0以上才支持,目前基本4.0一下的機子基本可以考慮不兼容了,所以為了減少工作量,這里繼續使用MediaPlayer來進行播放。
HLS格式的視頻,通過一個m3u8文件,然后里面包含若干個TS文件片段,這里有個蘋果的官方的一個例子:
http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8
里面的內容為:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10, no desc
fileSequence0.ts
#EXTINF:10, no desc
fileSequence1.ts
#EXTINF:10, no desc
fileSequence2.ts
#EXTINF:10, no desc
fileSequence3.ts
#EXTINF:10, no desc
fileSequence4.ts
#EXTINF:10, no desc
fileSequence5.ts
#EXTINF:10, no desc
fileSequence6.ts
#EXTINF:10, no desc
fileSequence7.ts
我們可以看到里面他又一個一個ts視頻片段,這個一個一個視頻片段就是我們需要的播放,那么他是如何被播放器識別播放的呢。
其實上面的這些關鍵的字段都是約定好的,MediaPlayer會去按照規定好的字段去解析這個m3u8文件,然后拼接成最終的播放地址進行播放。
實現這種未加密的緩存還是比較好實現的,大概可以分為這幾步:
1.我們首先按照特定的格式去解析這m3u8文件。
2.按照解析出來的ts文件按照我們知道的規則組拼起來,其下載這些ts文件,存放在手機的sd卡
3.我們需要在本地搭建一個本地http服務器,我們之前本打算搭建一個https,但是由於生成的證書是自己生成導致播放器不去訪問本地的服務器。
4.本地服務器我們通過過濾特定的接口名字,來實現根據不同ts名字返回不同的視頻文件(這里最好生成和原始的ts文件的名字一樣)
5.我們如何知道播放器播完一段視頻呢,因為他是一段一段播放的,所以這里就需要我們在本地生成一份本地指向我們本地服務器的m3u8文件,直接播放
2. 播放加密HLS
看下加密的m3u8文件的格式:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-KEY:METHOD=AES-128,URI="http://xxxxxx:5555//test/1102/test/segments.key"
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:19
#EXTINF:13.966667,
http://xxxxxx:5555/test/1102/test/segments0.ts
#EXTINF:10.000000,
http://xxxxxx:5555/test/1102/test/segments1.ts
#EXTINF:10.000000,
http://xxxxxx:5555/test/1102/test/segments2.ts
#EXTINF:10.000000,
http://xxxxxx.cn:5555/test/1102/test/segments3.ts
#EXTINF:10.000000,
http://xxxxxxn.cn:5555/test/1102/test/segments4.ts
#EXTINF:7.033333,
http://xxxxxx:5555/test/1102/test/segments5.ts
#EXTINF:10.000000,
我們看到了多了個字段EXT-X-KEY,這個也是m3u8給規定好的加密字段,如果包含這個字段播放器就會先去請求這個key,然后拿這個這個key去訪問加密的TS視頻就可以播放了。 其實看到這我們就因該有思路怎么去做,加密的緩存播放了。
實現播放加密緩存的思路:
1.我們首先按照特定的格式去解析這m3u8文件。
2.按照解析出來的ts文件按照我們知道的規則組拼起來,其下載這些ts文件,存放在手機的sd卡,這些下載下來的TS視頻文件是播放不了的,再把正確的key下載下來。
3.我們需要在本地搭建一個本地http服務器,我們之前本打算搭建一個https,但是由於生成的證書是自己生成導致播放器不去訪問本地的服務器。
4.本地服務器我們通過過濾特定的接口名字,來實現根據不同ts名字返回不同的視頻文件(這里最好生成和原始的ts文件的名字一樣)
三、HLS 協議總結
1. 優點:
- 客戶端支持簡單, 只需要支持 HTTP 請求即可, HTTP 協議無狀態, 只需要按順序下載媒體片段即可.
- 使用 HTTP 協議網絡兼容性好, HTTP 數據包也可以方便地通過防火牆或者代理服務器, CDN 支持良好.
- Apple 的全系列產品支持,不需要安裝任何插件就可以原生支持播放 HLS, 目前Android 也加入了對 HLS 的支持.
- 自帶多碼率自適應機制。
2. 缺點:
- 相比 RTMP 這類長連接協議, 延時較高, 難以用到互動直播場景.
- 對於點播服務來說, 由於 TS 切片通常較小, 海量碎片在文件分發, 一致性緩存, 存儲等方面都有較大挑戰.
3. 改進
由於客戶端每次請求 TS 或 M3U8 有可能一個新的連接請求, 無法有效的標識客戶端, 一旦出現問題, 基本無法有效的定位問題。
一般工業級的服務器都會對傳統的 HLS 做一些改進,常見優化是對每個M3U8文件增加Session來標識一條 HLS 連接。
不管通過哪種方式, 最終我們都能通過一個唯一的 id 來標識一條流, 這樣在排查問題時就可以根據這個 id 來定位播放過程中的問題.