HLS是什么
HLS是HTTP Live Streaming 的縮寫搪桂,是由蘋果公司推出的基于HTTP的能自適應(yīng)的流媒體傳輸協(xié)議片任,常用于直播和點播。
HLS 的工作原理是當(dāng)推流端把視頻流推到服務(wù)端后丹喻,服務(wù)端會把視頻流切割成一個個小的媒體文件(一般是ts文件,也有可能是fmp4文件)。然后服務(wù)器會把這些媒體文件的播放地址按照播放順序羅列到一個索引文件當(dāng)中宛徊,供客戶端查找可以的媒體流陪每。這個索引文件也就是我們平時在播放hls視頻的時候,最常見到的m3u8文件迷守。
碼率自適應(yīng)
為了能夠適應(yīng)觀眾的不同網(wǎng)絡(luò)環(huán)境犬绒,服務(wù)端會以不同的比特率和分辨率創(chuàng)建多個流,并把不同流的媒體文件地址放到了不同的索引文件(media playlist)當(dāng)中兑凿,并最終把不同流的索引文件的地址放到一個主索引文件中(master playlist)凯力。
客戶端在播放HLS媒體流時,能夠基于當(dāng)前的網(wǎng)絡(luò)情況礼华,選擇當(dāng)前可流暢播放的最高分辨率的媒體流進(jìn)行播放咐鹤。
M3U8文件詳解
對于HLS客戶端來講,最先要面對的并需要播放的媒體文件卓嫂,而是告知客戶端從何獲取媒體文件的索引(M3U8)文件慷暂。所以對于HLS客戶端來說,最首要的事情是對M3U8文件進(jìn)行解析晨雳。
從上面的介紹我們能夠知道行瑞,索引文件分為兩種類型,一種是 master playlist餐禁,一種是 media playlist血久。
media playlist
media playlist 內(nèi)部存放著一系列媒體片段資源,客戶端只要順序播放這些媒體片段資源帮非,就能夠完整地播放服務(wù)端提供地媒體資源氧吐。
media playlist 文件地格式如下所示:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:11
#EXTINF:10.000,
url_462/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_463/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_464/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_465/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_466/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_467/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_468/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:9.950,
url_469/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.050,
url_470/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_471/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_472/193039199_mp4_h264_aac_hd_7.ts
#EXT-X-ENDLIST
master playlist
master playlist 文件內(nèi)記錄著多個 media playlist 文件的地址,這些 media playlist 文件指向到的媒體文件的碼率末盔、格式各不相同筑舅。同時,還能夠提供不同語言的音頻文件陨舱,以及不同角度拍攝的視頻文件等等翠拣。客戶端能夠根據(jù)用戶不同的網(wǎng)絡(luò)環(huán)境游盲,或者是不同的語言误墓、興趣愛好的因素選擇合適的媒體資源。
maser playlist 文件的格式如下所示:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2149280,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=1280x720,NAME="720"
url_0/193039199_mp4_h264_aac_hd_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=246440,CODECS="mp4a.40.5,avc1.42000d",RESOLUTION=320x184,NAME="240"
url_2/193039199_mp4_h264_aac_ld_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=460560,CODECS="mp4a.40.5,avc1.420016",RESOLUTION=512x288,NAME="380"
url_4/193039199_mp4_h264_aac_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=836280,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=848x480,NAME="480"
url_6/193039199_mp4_h264_aac_hq_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=6221600,CODECS="mp4a.40.2,avc1.640028",RESOLUTION=1920x1080,NAME="1080"
url_8/193039199_mp4_h264_aac_fhd_7.m3u8
M3U8文件格式解析
playlist 文件定義
M3U8 文件必須以 UTF-8 [ RFC3629 ] 進(jìn)行編碼益缎,不能包含 Byte Order Mark(BOM)字節(jié)序谜慌, 不能包含 UTF-8 控制字符(U+0000 到 U+001F 和 U+007F 至 U+009F),CR (U+000D) 和 LF 除外(U+000A)莺奔。
M3U8 文件的每行的內(nèi)容只能是以下三種中的其中一種欣范。
- URI
- 空行
- 以 # 開頭的字符串
除了明確指定的元素之外不能有空格的存在。
以字符“#”開頭的行要么是注釋,要么是標(biāo)簽恼琼。標(biāo)簽以 #EXT 開頭杖刷,大小寫敏感。其他以“#”開頭的行都是注釋驳癌,客戶端解析時應(yīng)該忽略掉滑燃。
屬性列表
某些特定的標(biāo)簽的值是一個屬性列表。
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2149280,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=1280x720,NAME="720"
屬性列表以逗號作為分隔符颓鲜,分離出多組不帶空格的 AttributeName=AttributeValue
對表窘。如上面的EXT-X-STREAM-INF
屬性能夠分離出:
# AttributeName=AttributeValue
PROGRAM-ID=1,
BANDWIDTH=2149280,
CODECS="mp4a.40.2,avc1.64001f",
RESOLUTION=1280x720,
NAME="720"
標(biāo)簽
標(biāo)簽用于說明 M3U8 文件的全局參數(shù),以及 切片文件和媒體播放列表 的信息甜滨。標(biāo)簽可分以下幾種:
- 基礎(chǔ)標(biāo)簽(Basic Tags)
- 媒體片段標(biāo)簽(Media Segment Tags)
- 媒體播放列表標(biāo)簽(Media Playlist Tags)
- 主播放列表標(biāo)簽 (Master Playlist Tags)
- 媒體播放列表或主播放列表都使用的標(biāo)簽(Media or Master Playlist Tags)
下面會分別介紹這幾種類型中一些比較重要和常用的標(biāo)簽乐严。
基礎(chǔ)標(biāo)簽(Basic Tags)
基礎(chǔ)標(biāo)簽既能夠媒體播放列表(Media Playlist)中使用,也可以在主播放列表(Master Playlist)中使用衣摩。
-
EXTM3U
:每個 M3U8 文件必須將該標(biāo)簽放置在第一行昂验,表明該文件是一個 M3U8 文件。 -
EXT-X-VERSION
:表示 HLS 協(xié)議的版本號艾扮,該標(biāo)簽與流媒體的兼容性相關(guān)既琴。該標(biāo)簽為一個全局參數(shù),能夠在整個 M3U8 文件中進(jìn)行使用泡嘴。每個 M3U8 文件內(nèi)最多只能出現(xiàn)一個版本定義甫恩。如果 M3U8 文件內(nèi)不包含該標(biāo)簽,則默認(rèn)1酌予。
媒體播放列表標(biāo)簽(Media Playlist Tags)
媒體播放列表標(biāo)簽為 M3U8 文件的全局參數(shù)信息并且只能在 M3U8 文件中至多出現(xiàn)一次磺箕。媒體播放列表標(biāo)簽只能出現(xiàn)而在媒體播放列表(Media Playlist)當(dāng)中,而不能出現(xiàn)在主播放列表(Master Playlist)中抛虫。
EXT-X-TARGETDURATION
表示所有媒體片段最大的時長(單位秒),為必選標(biāo)簽松靡。
#EXT-X-TARGETDURATION:<s>
<meta charset="utf-8">
EXT-X-MEDIA-SEQUENCE
表示播放列表第一個 URL 片段文件的序列號。每個媒體片段 URL 都擁有一個唯一的整型序列號,每個媒體片段序列號按出現(xiàn)順序依次加 1建椰。如果該標(biāo)簽未指定雕欺,則默認(rèn)序列號從 0 開始。媒體片段序列號與片段文件名無關(guān)广凸。
#EXT-X-MEDIA-SEQUENCE:<number>
EXT-X-ENDLIST
表明 文件的結(jié)束,該標(biāo)簽可出現(xiàn)在 M3U8 文件任意位置阅茶,一般是結(jié)尾蛛枚。
當(dāng)media playlist中出現(xiàn)該標(biāo)簽時谅海,則說明改媒體流是一個點播源而不是一個直播源
EXT-X-PLAYLIST-TYPE
用于指明流媒體類型,該標(biāo)簽為可選標(biāo)簽蹦浦。
其格式為:
#EXT-X-PLAYLIST-TYPE:<type-enum>
其中:type-enum
可為:
VOD:即 Video on Demand扭吁,表示該媒體流為點播源,因此服務(wù)器不能更改該 M3U8 文件;
EVENT:表示該媒體流為直播源侥袜,服務(wù)器不能更改或刪除該 M3U8 文件任意部分內(nèi)容蝌诡,但是可以在文件末尾添加新內(nèi)容。
VOD 文件通常帶有 EXT-X-ENDLIST 標(biāo)簽枫吧,因為其為點播源浦旱,結(jié)束位置不會改變;而 EVEVT 文件初始化時一般不會有 EXT-X-ENDLIST 標(biāo)簽九杂,暗示有新的文件會添加到播放列表末尾颁湖,因此也需要客戶端定時獲取該 M3U8 文件,以獲取新的媒體片段資源例隆,直到訪問到 EXT-X-ENDLIST 標(biāo)簽才停止)甥捺。
EXT-X-I-FRAMES-ONLY
該標(biāo)簽全局生效,表示每個媒體片段都是一個 I 幀镀层。I 幀編碼時不需要依賴于其他幀镰禾,因此可以通過I 幀進(jìn)行快速播放等操作。
#EXT-X-I-FRAMES-ONLY
如果媒體播放列表設(shè)置了 EXT-X-I-FRAMES-ONLY唱逢,那么媒體片段的時長(EXTINF 標(biāo)簽的值)即為當(dāng)前媒體分片的 I 幀開始到下一個 I 幀出現(xiàn)的時長吴侦。
媒體資源如果包含I 幀切片,那么必須提供媒體初始化塊或者通過 EXT-X-MAP 標(biāo)簽提供媒體初始化塊的獲取途徑坞古,這樣客戶端就能通過這些I 幀切片以任意順序進(jìn)行加載和解碼妈倔。
媒體片段標(biāo)簽(Media Segment Tags)
每個媒體片段的 URI 前面都有一系列媒體片段標(biāo)簽,用于描述媒體片段的信息绸贡。有些片段標(biāo)簽只對其后切片資源有效盯蝴,有些片段標(biāo)簽對其后所有切片都有效,直到后續(xù)遇到另一個相同的標(biāo)簽描述听怕。媒體片段類型標(biāo)簽只能出現(xiàn)而在媒體播放列表(Media Playlist)當(dāng)中捧挺,而不能出現(xiàn)在主播放列表(Master Playlist)中(因為媒體片段URI只會出現(xiàn)在媒體播放列表中)。
EXTINF
表示其后 URI 指定的媒體片段時長(單位為秒)尿瞭。每個 URL 媒體片段之前必須指定該標(biāo)簽闽烙。該標(biāo)簽的使用格式為:
#EXTINF:<duration>,[<title>]
其中,duration是一個十進(jìn)制的整數(shù)或者浮點數(shù)声搁,其值必須小于或等于 EXT-X-TARGETDURATION
指定的值黑竞。
EXT-X-BYTERANGE
該標(biāo)簽表示接下來的媒體片段資源只是其 URI 指定的媒體片段資源的局部范圍(即截取 URI 媒體資源部分內(nèi)容作為下一個切片)。該標(biāo)簽只對其后一個 URI 起作用疏旨。其格式為:
#EXT-X-BYTERANGE:<length>[@<offset>]
其中很魂, length
是一個十進(jìn)制整型,表示截取片段大虚芾浴(單位:字節(jié))遏匆》òぃ可選參數(shù)offset
也是一個十進(jìn)制整型,指示截取起始位置(以字節(jié)表示幅聘,在 URI 指定的資源開頭移動該字節(jié)位置后進(jìn)行截确材伞)。如果offset
未指定帝蒿,則截取起始位置從上一個該標(biāo)簽截取完成的下一個字節(jié)(即上一個length+offset+1)開始截取荐糜。
如果沒有指定該標(biāo)簽,則表明的切分范圍為整個 URI 資源片段葛超。
使用 EXT-X-BYTERANGE 標(biāo)簽要求兼容版本號 EXT-X-VERSION 大于等于 4狞尔。
EXT-X-DISCONTINUITY
表明標(biāo)簽之前媒體片段與下一個媒體片段之間存在中斷。
當(dāng)以下任一情況變化時巩掺,必須使用該標(biāo)簽:
- 文件格式(file format)
- 數(shù)字(number)偏序,類型(type),媒體標(biāo)識符(identifiers of tracks)
- 時間戳序列(timestamp sequence)
當(dāng)以下任一情況變化時胖替,建議使用該標(biāo)簽:
- 編碼參數(shù)(encoding parameters)
- 編碼序列(encoding sequence)
EXT-X-DISCONTINUITY 最常用的場景是在媒體流中插入廣告研儒。插入廣告的例子:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
ad0.ts
#EXTINF:8.0,
ad1.ts
#EXT-X-DISCONTINUITY
#EXTINF:10.0,
movieA.ts
#EXTINF:10.0,
movieB.ts
...
#EXT-X-ENDLIST
EXT-X-KEY
該標(biāo)簽用于為加密的媒體片段指定解密方法。
該標(biāo)簽對所有 媒體片段 和 由標(biāo)簽 EXT-X-MAP 聲明的圍繞其間的所有 媒體初始化塊(Meida Initialization Section) 都起作用独令,直到遇到下一個 EXT-X-KEY(若 m3u8 文件只有一個 EXT-X-KEY 標(biāo)簽端朵,則其作用于所有媒體片段)。多個 EXT-X-KEY 標(biāo)簽如果最終生成的是同樣的秘鑰燃箭,則他們都可作用于同一個媒體片段冲呢。
#EXT-X-KEY:<attribute-list>
EXT-X-MAP
用于指明獲取媒體初始化塊(Meida Initialization Section)的方法。該標(biāo)簽對其后所有媒體片段生效招狸,直至遇到另一個 EXT-X-MAP 標(biāo)簽敬拓。擁有改標(biāo)簽的 M3U8 文件內(nèi)的所有媒體片段必須加上這個初始化片段才能組成一個完整的媒體文件。
其格式為:
#EXT-X-MAP:<attribute-list>
其屬性列表取值范圍如下:
URI:由引號包裹的字符串裙戏,指定了包含媒體初始化塊的資源的路徑乘凸。該屬性為必選參數(shù)。
BYTERANGE:由引號包裹的字符串累榜,指定了媒體初始化塊在 URI 指定的資源的位置(片段)营勤。
該屬性指定的范圍應(yīng)當(dāng)只包含媒體初始化塊。
該屬性為可選參數(shù)壹罚,如果未指定葛作,則表示 URI 指定的資源就是全部的媒體初始化塊。
EXT-X-PROGRAM-DATE-TIME
該標(biāo)簽使用一個絕對日期/時間表明第一個媒體片段的取樣時間猖凛。
其格式為:
#EXT-X-PROGRAM-DATE-TIME:<date-time-msec>
其中赂蠢,date-time-msec是一個 ISO/IEC 8601:2004 規(guī)定的日期格式,形如:YYYY-MM-DDThh:mm:ss.SSSZ形病。
例如:
#EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00
主播放列表標(biāo)簽 (Master Playlist Tags)
主播放列表(Master Playlist)定義了備份流客年,多語言翻譯流和其他全局參數(shù)。主播放列表標(biāo)簽只能出現(xiàn)在主播放列表(Master Playlist )中而不能出現(xiàn)在媒體播放列表(Media Playlist)中漠吻。
EXT-X-MEDIA
用于指定相同內(nèi)容的媒體文件的不同語言翻譯的媒體文件列表資源量瓜。
比如,通過三個 EXT-X-MEIDA 標(biāo)簽途乃,可以提供包含英文绍傲,法語和西班牙語版本的相同內(nèi)容的音頻資源,或者通過兩個 EXT-X-MEDIA 提供兩個不同拍攝角度的視頻資源耍共。
EXT-X-STREAM-INF
該屬性指定了一個備份源烫饼,并提供了該備份源的相關(guān)信息。
EXT-X-I-FRAME-STREAM-INF
該標(biāo)簽表明媒體播放列表文件包含多種媒體資源的 I幀试读。
EXT-X-SESSION-KEY
該標(biāo)簽允許主播放列表(Master Playlist)指定媒體播放列表(Meida Playlist)的加密密鑰杠纵。這使得客戶端可以預(yù)先加載這些密鑰,而無需從媒體播放列表中獲取钩骇。其屬性列表與 EXT-X-KEY 相同比藻,除了 METHOD 屬性的值必須不為NONE。
媒體播放列表或主播放列表都使用的標(biāo)簽(Media or Master Playlist Tags)
以下標(biāo)簽可同時設(shè)置于主播放列表(Master Playlist)和媒體播放列表(Media Playlist)中倘屹。但是對于在主播放列表中設(shè)置了的標(biāo)簽银亲,不應(yīng)當(dāng)再次設(shè)置媒體播放列表中。同時出現(xiàn)在兩者播放列表的相同標(biāo)簽必須具備相同的值纽匙。這些標(biāo)簽在播放列表中不能出現(xiàn)多次(只能使用一次)务蝠。
EXT-X-INDEPENDENT-SEGMENTS
該標(biāo)簽對列表內(nèi)所有媒體片段均有效,用于表明對于一個媒體片段中的所有媒體樣本均可獨立進(jìn)行解碼,而無須依賴其他媒體片段信息烛缔。
#EXT-X-INDEPENDENT-SEGMENTS
如果該標(biāo)簽出現(xiàn)在主播放列表中馏段,則其對所有媒體播放列表的所有媒體片段都生效。
EXT-X-START
該標(biāo)簽為可選標(biāo)簽践瓷,用于表示播放列表播放起始位置毅弧。默認(rèn)情況下,客戶端應(yīng)該使用該標(biāo)簽指定的位置進(jìn)行播放当窗。
#EXT-X-START:<attribute-list>
其參數(shù)屬性列表的取值范圍如下:
TIME-OFFSET:該屬性值為一個帶符號十進(jìn)制浮點數(shù)(單位:秒)够坐。
一個正數(shù)表示以播放列表起始位置開始的時間偏移量。
一個負(fù)數(shù)表示播放列表上一個媒體片段最后位置往前的時間偏移量崖面。
該屬性的絕對值應(yīng)當(dāng)不超過播放列表的時長元咙。如果超過,則表示到達(dá)文件結(jié)尾(數(shù)值為正數(shù))巫员,或者達(dá)到文件起始(數(shù)值為負(fù)數(shù))庶香。
如果播放列表不包含 EXT-X-ENDLIST 標(biāo)簽,那么 TIME-OFFSET 屬性值不應(yīng)當(dāng)在播放文件末尾三個切片時長之內(nèi)简识。PRECISE:該值為一個可枚舉字符串赶掖。
有效的取值為YES
或NO
感猛。
如果值為YES
,客戶端應(yīng)當(dāng)播放包含 TIME-OFFSET 的媒體片段奢赂,但不要渲染該塊內(nèi)優(yōu)先于 TIME-OFFSET 的樣本塊陪白。
如果值為NO
,客戶端應(yīng)當(dāng)嘗試渲染在媒體片段內(nèi)的所有樣本塊膳灶。
該屬性為可選參數(shù)咱士,未指定則認(rèn)為NO
。
HLS直播延遲高的原因
HLS直播延遲主要由以下幾個原因?qū)е碌模?/p>
- 客戶端一般存在安全緩沖的時長轧钓。HLS協(xié)議不建議客戶端選擇開始時間到最后一個分片結(jié)束時間間隔小于最后一個分片時長加兩倍的 EXT-X-TARGETDURATION 時長的分片作為首個分片進(jìn)行播放序厉。也就是說,一般而言毕箍,客戶端應(yīng)該從 M3U8 文件中倒數(shù)第三個或倒數(shù)第四個分片開始播放弛房。
服務(wù)器更新 M3U8 文件的間隔。理論上HLS服務(wù)器需要大于等于一個EXT-X-TARGETDURATION的時長去更新 M3U8文件而柑。
CDN緩存機制庭再。若當(dāng)前源站 M3U8 已經(jīng)更新到了第四個片段,但是CDN邊緣節(jié)點還緩存著上一個版本的 M3U8文件(只包含3個片段)牺堰。此時就需要等文件的TTL過期拄轻,邊緣節(jié)點才會去獲取最新版本的 M3U8 文件。而這個緩存TTL也不能取消伟葫,如果每個端上的請求到達(dá)CDN邊緣節(jié)點時都去找源站要最新版本恨搓,源站就可能會被流量沖垮。
客戶端下載分片以及解碼的時長筏养。
網(wǎng)絡(luò)延遲斧抱。
優(yōu)化延遲的方法
我們可以從延遲原因中的第 1
和第 2
點入手,降低我們直播的延遲渐溶。
- 適當(dāng)減少客戶端的安全緩沖時長辉浦。在保證網(wǎng)絡(luò)環(huán)境足夠優(yōu)越的場景下(如內(nèi)網(wǎng)直播),可以適當(dāng)降低客戶端安全緩沖的時長茎辐。如hls.js可以通過修改
liveSyncDurationCount
(安全緩沖的分片數(shù)量宪郊,默認(rèn)為3)和liveSyncDuration
(安全緩沖的時長,單位為秒)來調(diào)整安全緩沖的時長拖陆。 - 盡量使用GOP(Group Of Picture)的時長來設(shè)置分片的時長弛槐,降低服務(wù)器更新 M3U8 文件的間隔。