1.簡述
官方文檔地址:https://tools.ietf.org/html/rfc8216
如果需要更詳細了解這個協議,就需要閱讀這個協議。
HLS(HTTP Live Streaming) 把整個流分片,然后基于HTTP的文件來下載,每次只下載一部分。HLS 協議由三部分組成:HTTP、M3U8、TS。其中,HTTP 是傳輸協議,M3U8 是索引?件,TS是?視頻的媒體信息。
關于HLS的詳細介紹可參考如下地址:
https://tools.ietf.org/html/draft-pantos-http-live-streaming-18
HLS 是提供?個 m3u8 地址,Apple 的 Safari 瀏覽器直接就能打開 m3u8 地址(試了下,win的瀏覽器是無法打開),如下地址:
http://demo.srs.com/live/livestream.m3u8
注意:Android 也是不能直接打開,需要使? html5 的 video 標簽,然后在瀏覽器中打開這個??即可,如:
<!-- livestream.html -->
<video width="640" height="360"
autoplay controls autobuffer
src="http://demo.srs.com/live/livestream.m3u8"
type="application/vnd.apple.mpegurl">
</video>
HLS 的 m3u8,是?個 ts 的列表,也就是告訴瀏覽器可以播放這些 ts ?件,如下列表:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:64
#EXT-X-TARGETDURATION:12
#EXTINF:11.550
livestream-64.ts
#EXTINF:5.250
livestream-65.ts
#EXTINF:7.700
livestream-66.ts
#EXTINF:6.850
livestream-67.ts
注意:如果只有#表示注釋,如果有#EXT,表示標記一個tag。
有?個關鍵的參數,這些參數在 SRS 的配置?件中都有配置項:
(1)#EXTM3U:每個M3U?件第??必須是這個tag,請標示作?。
(2)#EXT-X-VERSION:該屬性可以沒有,上面列表中,?前版本號主要是version 3,最新的是7。
(3)#EXT-X-MEDIA-SEQUENCE:每?個media URI在PlayList中只有唯?的序號(每一次開始播放ts文件的所對應的序號),相鄰之間序號+1,?個media URI并不是必須要包含的,如果沒有,默認為0。如這里#EXT-X-MEDIA-SEQUENCE:64,對應下面livestream-64.ts(開始播放的序號)。
(4)#EXT-X-TARGETDURATION:ts列表中所有切?的最?時?(上述列表為12s)。有些 Apple 設備這個參數不正確會?法播放。SRS 會?動計算出 ts ?件的最?時?,然后更新 m3u8 時會?動更新這個值。?戶不必??配置。
(5)#EXTINF:ts 切?的實際時?,SRS 提供配置項 hls_fragment,但實際上的 ts 時?還受 gop 影響,確保是完整的gop。分別對應下面ts的切片時長,如,#EXTINF:11.550(時間單位為s),描述的是livestream-64.ts的切片時長為11.55s(如果向上取整,則就是所有ts文件的切片最大時長為12s)。
(6)ts ?件的數?:SRS 可配置 hls_window(單位是秒,不是數量),指定 m3u8 中保存多少個切?(類似一個容器),譬如,每個 ts 切?為 10 秒,窗?為 60 秒,那么 m3u8 中最多保存 6 個 ts 切?,SRS 會?動清理舊的切?。
(7)livestream-67.ts:SRS 會?動維護 ts 切?的?件名,在編碼器重推之后,這個編號會繼續增?,保證流的連續性。直到 SRS 重啟,這個編號才重置為 0。
注意搞懂這些概念:每?個 .m3u8 ?件,分別對應若?個 ts ?件的索引和配置信息,真正的音視頻數據是存放在ts文件。m3u8 ?件只是存放了?些 ts ?件的配置信息和相關路徑。
.m3u8 ?件,其實就是以 utf-8 編碼的 m3u ?件,這個?件本身不能播放,只是存放了播放信息的?本?件。比如一碗湯,.m3u8 ?件就是一個碗,而ts才是正真的湯,無論湯增加還是減少,都是在碗里變化。
當視頻播放時,.m3u8 文件(可以理解為一個變化的容器)是動態改變的,video標簽會解析這個?件,并根據索引信息找到對應的 ts ?件來播放。所以?般為了加快速度,.m3u8 放在 web 服務器上,ts ?件放在 cdn 上。
m3u8示例
m3u8 ?件示例 1:單碼率適配流
該 m3u8 ?件只是?個簡單的 Media Playlist。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-MEDIA-SEQUENCE:2
#EXT-X-TARGETDURATION:16
#EXTINF:14.357, no desc
livestream-2.ts
#EXTINF:15.617, no desc
livestream-3.ts
#EXTINF:14.358, no desc
livestream-4.ts
#EXTINF:15.618, no desc
livestream-5.ts
#EXTINF:11.130, no desc
livestream-6.ts
m3u8 ?件示例 2:多碼率適配流
包含多種?特率的 Master Playlist。該?件是?個實際使?中的頂級 m3u8 ?件,該?件中?定義了http://example.com/low.m3u8 、 http://example.com/mid.m3u8 等 ? 個 ? 級 ? 件 。 頂 級m3u8 ?件主要是做碼率適配的,?級 m3u8 才是真正的切??件,拉流端會默認選擇碼率最?的請求,如果發現碼率達不到,會請求降低碼率的流。客戶端拿到?級 m3u8 ?件后,會繼續請求??的?件,這時就可以進?播放了。
注意:這個碼率自適應功能,是非常值得推薦。
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000
http://example.com/low.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000
http://example.com/mid.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000
http://example.com/hi.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS="mp4a.40.5"
http://example.com/audio-only.m3u8
- HLS 整體數據流程框架
前一節講過,.m3u8 放在 web 服務器上,ts ?件放在 cdn 上,切片在流媒體服務器。框架如下圖:
3.HLS 協議編碼格式要求
HLS協議對編碼格式有如下要求,一般只支持這幾種格式:
(1)視頻的編碼格式:H264。
(2)?頻的編碼格式:AAC、MP3、AC-3。
(3)視頻的封裝格式:ts。
(4)保存 ts 索引的 m3u8 ?件。
3.1 HLS 協議優點
(1)HLS 相對于 RTMP 來講使?了標準的 HTTP 協議來傳輸數據,可以避免在?些特殊的?絡環境下被屏蔽。
(2)HLS 相? RTMP 在服務器端做負載均衡要簡單得多。因為 HLS 是基于?狀態協議 HTTP 實現的,拉流端只需要按照順序使?下載存儲在服務器的普通 ts ?件進?播放就可以。? RTMP 是?種有狀態協議,很難對視頻服務器進?平滑擴展,因為需要為每?個播放視頻流的拉流端維護狀態。
(3)HLS 協議本身實現了碼率?適應,在不同帶寬情況下,設備可以?動切換到最適合??碼率的視頻播放。這一點是非常好的一項功能,要是需要重點關注。
3.2 HLS 協議缺點
HLS 協議在直播的視頻延遲時間很難做到 10 s 以下延時,? RTMP 協議的延時可以降到 1s 左右,甚至1s以下。
在這里提醒各位朋友,不管怎樣,這兩種方案都是有應用的,需要根據自己的需求和應用場景,選擇不同的方案。不能只看的協議的缺點,而不看協議的優點。
4.協議其它概念解析
(1)Playlist file
?個 m3u 的 Playlist 就是?個由多個獨??組成的?本?件,每?由回?/換?區分。每??可以是?個URI、空??或是?個 以 "#" 號開頭的字符串,并且空格只能存在于??中不同元素間的分隔。?個 URI 表示?個媒體段或是 "variant Playlist file"(最多?持?層嵌套,即?個 m3u8 ?件中嵌套另?個 m3u8),以 "EXT" 開頭的表示?個 "tag",否則表示注釋,直接忽略。
(2)Tags解析
#EXTM3U :每個 m3u8 ?件第??必須是這個 tag,如上?的兩個示例。
#EXT-X-VERSION:m3u8?件版本號,?如#EXT-X-VERSION:3。
#EXTINF :指定每個媒體段(ts)的持續時間,這個僅對其后?的 URI 有效,每兩個媒體段 URI 間被這個 tag 分隔開其格式為: #EXTINF:<duration>,<title>, ?如#EXTINF:14.357, nodesc
duration:表示持續的時間(秒),"Durations MUST be integers if the protocol version of the Playlist file is less than 3"(如果版本號小于3,就是整數),否則可以是浮點數。
#EXT-X-BYTERANGE :表示媒體段是?個媒體 URI 資源中的?段,只對其后的 media URI 有效,格式為: #EXT-X-BYTERANGE:<n>[@o]。這個字段在版本4才有體現。
n:表示這個區間的??
o:表示在 URI 中的 offset
#EXT-X-TARGETDURATION :指定當前視頻流中的單個切?(即 ts)?件的最?時?(秒)。所以#EXTINF 中指定的時間?度必須?于或是等于這個最?值。這個 tag 在整個 Playlist ?件中只能出現?次(在嵌套的情況下,?般有真正ts url 的 m3u8 才會出現該 tag)。格式為: #EXT-X-TARGETDURATION:<s>
s:表示最?的秒數。
#EXT-X-MEDIA-SEQUENCE :每?個 media URI 在 Playlist 中只有唯?的序號,相鄰之間序號 +1。格式為: #EXT-X-MEDIA-SEQUENCE:<number> 。?個 media URI 并不是必須要包含的,如果沒有,默認為 0.
#EXT-X-KEY :表示怎么對 media segments 進?解碼。其作?范圍是下次該 tag 出現前的所有media URI。格式為: #EXT-X-KEY:<attribute-list>NONE 或者 AES-128。如果是 NONE,則 URI 以及 IV 屬性必須不存在,如果是 AES-128(Advanced Encryption Standard),則 URI 必須存在,IV 可以不存在。對于 AES-128 的情況,keytag 和 URI 屬性共同表示了?個 key ?件,通過 URI 可以獲得這個key,如果沒有 IV(Initialization Vector),則使?序列號作為 IV 進?編解碼,將序列號的?位賦到 16 個字節的 buffer 中,左邊補 0;如果有 IV,則將該值當成 16 個字節的 16 進制數。
#EXT-X-PROGRAM-DATE-TIME :將?個絕對時間或是?期和?個媒體段中的第?個 sample 相關聯,只對下?個 media URI 有效,格式如下: #EXT-X-PROGRAM-DATE-TIME:<YYYY-MM-DDThh:mm:ssZ>
如: #EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00
#EXT-X-ALLOW-CACHE :是否允許做 cache,這個可以在 Playlist ?件中任意地?出現,并且最多只出現?次,作?效果是所有的媒體段。格式如下: #EXT-X-ALLOW-CACHE:<YES|NO>
#EXT-X-PLAYLIST-TYPE :提供關于 Playlist 的可變性的信息,這個對整個 Playlist ?件有效,是可選的,格式如下: #EXT-X-PLAYLIST-TYPE:<EVENT|VOD>
VOD,即為點播視頻,服務器不能改變 Playlist ?件,換句話說就是該視頻全部的 ts ?件已經被?成好了EVENT,就是實時?成 m3u8 和 ts ?件。服務器不能改變或是刪除 Playlist ?件中的任何部分,但是可以向該?件中增加新的??內容。它的索引?件?直處于動態變化中,播放的時候需要不斷下載?級 index ?件
#EXT-X-ENDLIST :表示 m3u8 ?件的結束,live m3u8 沒有該 tag。它可以在 Playlist 中任意位置出現,但是只能出現?個,格式如下: #EXT-X-ENDLIST
#EXT-X-MEDIA :被?來在 Playlist 中表示相同內容的不同語種/譯?的版本,?如可以通過使? 3個這種 tag 表示 3 種不同語?的?頻,或者? 2 個這個 tag 表示不同?度的 video。在 Playlist中,這個標簽是獨?存在的,其格式如下: #EXT-X-MEDIA:<attribute-list>
該屬性列表中包含:URI、TYPE、GROUP-ID、LANGUAGE、NAME、DEFAULT、AUTOSELECT。
URI:如果沒有,則表示這個 tag 描述的可選擇版本在主 PlayList 的 EXT-X-STREAM-INF 中存在
TYPE:AUDIO and VIDEO
GROUP-ID:具有相同 ID 的 MEDIAtag,組成?組樣式
LANGUAGE:identifies the primary language used in the rendition
NAME:The value is a quoted-string containing a human-readable description of the
rendition. If the LANGUAGE attribute is present then this description SHOULD be in
that language
DEFAULT:YES 或是 NO,默認是 No,如果是 YES,則客戶端會以這種選項來播放,除??戶
??進?選擇
AUTOSELECT:YES 或是 NO,默認是 No,如果是 YES,則客戶端會根據當前播放環境來進?
選擇(?戶沒有根據??偏好進?選擇的前提下),這個在版本4中,也是存在。
#EXT-X-STREAM-INF :指定?個包含多媒體信息的 media URI 作為 Playlist,?般做 m3u8 的嵌套使?,它只對緊跟后?的 URI 有效,格式如下: #EXT-X-STREAM-INF:<attribute-list>常?的屬性如下:
BANDWIDTH:帶寬,必須有
PROGRAM-ID:該值是?個?進制整數,唯?地標識?個在 Playlist ?件范圍內的特定的描述。
?個 Playlist ?件中可能包含多個有相同 ID 的此 tag
CODECS:指定流的編碼類型,不是必須的
RESOLUTION:分辨率
AUDIO:這個值必須和 AUDIO 類別的 "EXT-X-MEDIA" 標簽中 "GROUP-ID" 屬性值相匹配
VIDEO:同上
#EXT-X-DISCONTINUITY :當遇到該 tag 的時候說明以下屬性發?了變化:
file format ?件格式
number and type of tracks 軌道
encoding parameters 編碼參數
encoding sequence 編碼序號
timestamp sequence 時間戳序號
#ZEN-TOTAL-DURATION :
表示這個 m3u8 所含 ts 的總時間?度
本篇文章就分析到這里,歡迎大家關注歡迎關注,點贊,轉發,收藏,分享,評論區討論。