一、HLS 介紹
HLS,全稱 HTTP Live Streaming,是蘋(píng)果公司實(shí)現(xiàn)的基于 HTTP 的流媒體傳輸協(xié)議。它可以支持流媒體的直播和點(diǎn)播,主要應(yīng)用在 iOS 系統(tǒng)和 HTML5 網(wǎng)頁(yè)播放器中。
HLS 的基本原理非常簡(jiǎn)單,它是將多媒體文件或直接流進(jìn)行切片,形成一堆的 ts 文件和 m3u8 索引文件并保存到磁盤(pán)。
當(dāng)播放器獲取 HLS 流時(shí),它首先根據(jù)時(shí)間戳,通過(guò) HTTP 服務(wù),從 m3u8 索引文件獲取最新的 ts 視頻文件切片地址,然后再通過(guò) HTTP 協(xié)議將它們下載并緩存起來(lái)。當(dāng)播放器播放 HLS 流時(shí),播放線程會(huì)從緩沖區(qū)中讀出數(shù)據(jù)并進(jìn)行播放。
通過(guò)上面的描述我們可以知道,HLS 協(xié)議的本質(zhì)就是通過(guò) HTTP 下載文件,然后將下載的切片緩存起來(lái)。由于切片文件都非常小,所以可以實(shí)現(xiàn)邊下載邊播的效果。HLS 規(guī)范規(guī)定,播放器至少下載一個(gè) ts 切片才能播放,所以 HLS 理論上至少會(huì)有一個(gè)切片的延遲。
二、HLS的優(yōu)勢(shì)和不足
優(yōu)勢(shì):
HLS 是為了解決 RTMP 協(xié)議中存在的一些問(wèn)題而設(shè)計(jì)的,所以,它自然有自己的優(yōu)勢(shì)。主要體現(xiàn)在以下幾方面:
RTMP 協(xié)議沒(méi)有使用標(biāo)準(zhǔn)的 HTTP 接口傳輸數(shù)據(jù),在一些有訪問(wèn)限制的網(wǎng)絡(luò)環(huán)境下,比如企業(yè)網(wǎng)防火墻,是沒(méi)法訪問(wèn)外網(wǎng)的,因?yàn)槠髽I(yè)內(nèi)部一般只允許 80/443 端口可以訪問(wèn)外網(wǎng)。而 HLS 使用的是 HTTP 協(xié)議傳輸數(shù)據(jù),所以 HLS 協(xié)議天然就解決了這個(gè)問(wèn)題。
HLS 協(xié)議本身實(shí)現(xiàn)了碼率自適應(yīng),不同帶寬的設(shè)備可以自動(dòng)切換到最適合自己碼率的視頻進(jìn)行播放。
瀏覽器天然支持 HLS 協(xié)議,而 RTMP 協(xié)議需要安裝 Flash 插件才能播放 RTMP 流。
不足:
HLS 最主要的問(wèn)題就是實(shí)時(shí)性差。由于 HLS 往往采用 10s 的切片,所以最小也要有 10s 的延遲,一般是 20~30s 的延遲,有時(shí)甚至更差。
HLS 之所以能達(dá)到 20~30s 的延遲,主要是由于 HLS 的實(shí)現(xiàn)機(jī)制造成的。HLS 使用的是 HTTP 短連接,且 HTTP 是基于 TCP 的,所以這就意味著 HLS 需要不斷地與服務(wù)器建立連接。TCP 每次建立連接時(shí)都要進(jìn)行三次握手,而斷開(kāi)連接時(shí),也要進(jìn)行四次揮手,基于以上這些復(fù)雜的原因,就造成了 HLS 延遲比較久的局面。
三、HLS 直播架構(gòu)
客戶端采集媒體數(shù)據(jù)后,通過(guò) RTMP 協(xié)議將音視頻流推送給 CDN 網(wǎng)絡(luò)的源節(jié)點(diǎn)(接入節(jié)點(diǎn))。源節(jié)點(diǎn)收到音視頻流后,再通過(guò) Convert 服務(wù)器將 RTMP 流切割為 HLS 切片文件,即 .ts 文件。同時(shí)生成與之對(duì)應(yīng)的 m3u8 文件,即 HLS 播放列表文件。
切割后的 HLS 分片文件(.ts 文件)和 HLS 列表文件(.m3u8 文件)經(jīng) CDN 網(wǎng)絡(luò)轉(zhuǎn)發(fā)后,客戶端就可以從離自己最近的 CDN 邊緣節(jié)點(diǎn)拉取 HLS 媒體流了。
在拉取 HLS 媒體流時(shí),客戶端首先通過(guò) HLS 協(xié)議將 m3u8 索引文件下載下來(lái),然后按索引文件中的順序,將 .ts 文件一片一片下載下來(lái),然后一邊播放一邊緩沖。此時(shí),你就可以在 PC、手機(jī)、平板等設(shè)備上觀看直播節(jié)目了。
對(duì)于使用 HLS 協(xié)議的直播系統(tǒng)來(lái)說(shuō),最重要的一步就是切片。源節(jié)點(diǎn)服務(wù)器收到音視頻流后,先要數(shù)據(jù)緩沖起來(lái),保證到達(dá)幀的所有分片都已收到之后,才會(huì)將它們切片成 TS 流。
四、m3u8 格式分析
HLS 必須要有一個(gè) .m3u8 的索引文件 。它是一個(gè)播放列表文件,文件的編碼必須是 UTF-8 格式。m3u8 文件內(nèi)容如下:
#EXTM3U
#EXT-X-VERSION:3 // 版本信息
#EXT-X-TARGETDURATION:11 // 每個(gè)分片的目標(biāo)時(shí)長(zhǎng)
#EXT-X-MEDIA-SEQUENCE:0 // 分片起始編號(hào)
#EXTINF:10.922578, // 分片實(shí)際時(shí)長(zhǎng)
test000.ts // 分片文件
#EXTINF:9.929578, // 第二個(gè)分片實(shí)際時(shí)長(zhǎng)
test001.ts // 第二個(gè)分片文件
...
RFC8216 規(guī)定,.m3u8 文件內(nèi)容以#字母開(kāi)頭的行是注釋和 TAG,其中 TAG 必須是#EXT 開(kāi)頭,如上面示例中的內(nèi)容所示。
接下來(lái),我們對(duì)這幾個(gè) TAG 做一下說(shuō)明:
EXTM3U 表示文件是第一個(gè)擴(kuò)展的 M3U8 文件,此 TAG 必須放在索引文件的第一行。
EXT-X-VERSION: n 表示索引文件支持的版本號(hào),后面的數(shù)字 n 是版本號(hào)數(shù)字。需要注意的是,一個(gè)索引文件只能有一行版本號(hào) TAG,否則播放器會(huì)解析報(bào)錯(cuò)。
EXT-X-TARGETDURATION: s 表示 .ts 切片的最大時(shí)長(zhǎng),單位是秒(s)。
EXT-X-MEDIA-SEQUENCE: number 表示第一個(gè) .ts 切片文件的編號(hào)。若不設(shè)置此項(xiàng),就是默認(rèn)從 0 開(kāi)始的。
EXTINF: duration, title 表示 .ts 文件的時(shí)長(zhǎng)和文件名稱。文件時(shí)長(zhǎng)不能超過(guò)#EXT-X-TARGETDURATION中設(shè)置的最大時(shí)長(zhǎng),并且時(shí)長(zhǎng)的單位應(yīng)該采用浮點(diǎn)數(shù)來(lái)提高精度。
五、TS 格式分析
TS 流最早應(yīng)用于數(shù)字電視領(lǐng)域,其格式非常復(fù)雜,包含的配置信息表多達(dá)十幾個(gè)。蘋(píng)果推出的 HLS 協(xié)議對(duì) MPEG2 規(guī)范中的 TS 流做了精減,只保留了兩個(gè)最基本的配置表 PAT 和 PMT,再加上音視頻數(shù)據(jù)流就形成了現(xiàn)在的 HLS 協(xié)議。也就是說(shuō), HLS 協(xié)議是由 PAT + PMT + TS 數(shù)據(jù)流組成的。其中,TS 數(shù)據(jù)中的視頻數(shù)據(jù)采用 H264 編碼,而音頻數(shù)據(jù)采用 AAC/MP3 編碼。TS 數(shù)據(jù)流示意圖如下所示:

TS 數(shù)據(jù)流由 TS Header 和 TS Payload 組成。其中,TS Header 占 4 字節(jié),TS Payload 占 184 字節(jié),即 TS 數(shù)據(jù)流總長(zhǎng)度是 188 字節(jié)。
TS Payload 又由 PES Header 和 PES Payload 組成。其中,PES Payload 是真正的音視頻流,也稱為 ES 流。
PES(Packet Elementary Stream)是將 ES 流增加 PES Header 后形成的數(shù)據(jù)包。
ES(Elementary Stream),中文可以翻譯成基流,是編碼后的音視頻數(shù)據(jù)。
TS 數(shù)據(jù)流的格式,如下圖所示:

這是 TS Header 各個(gè)字段的詳細(xì)說(shuō)明,圖中數(shù)字表示長(zhǎng)度,如果數(shù)字后面帶有 bytes ,單位就是 bytes;否則,單位都是 bit。
TS Header 分為 8 個(gè)字段,下面我們分別解釋一下:

PES Packet 作為 TS 數(shù)據(jù)流的 Payload,也有自己的 Header,如下圖所示:

下面我們就對(duì)這些常用的字段一一做下解釋,當(dāng)然也還有很多不常用的字段,我們這里就不列出來(lái)了,如有需求,可參考 ISO-IEC 13818-1 2.4.3.7 節(jié)。
PES Header 長(zhǎng)度是 6 字節(jié),字段說(shuō)明如下:

參考:從0打造音視頻直播系統(tǒng)/04-支持上萬(wàn)人同時(shí)在線的直播系統(tǒng)%20(8講)/32丨HLS:實(shí)現(xiàn)一對(duì)多直播系統(tǒng)的必備協(xié)議.html
從0打造音視頻直播系統(tǒng)/04-支持上萬(wàn)人同時(shí)在線的直播系統(tǒng)%20(8講)/31丨一對(duì)多直播系統(tǒng)RTMP-HLS,你該選哪個(gè)?.html