封裝格式
MEPG-2 TS
編碼格式
視頻編碼格式為H.264,音頻編碼格式為MP3、AAC、AC-3或EC-3
索引文件
M3U8
需要說明的是,目前已有廠家實現了H.265的HLS編碼。在封裝層面建立索引自動標記文件,除了MPEG-2 TS封裝外,在上,蘋果宣布了HLS對分段MP4(fMP4)文件字節尋址的支持,為HLS向MPEG-DASH的兼容提供了可能。
3 HLS 流程
根據媒體流的生成及流向,HLS的結構可劃分為如下幾個部分:
序號
說明
1
Audio/Video 視頻源可以是任意格式,可以是離線文件或實時碼流。
2
接收到視頻源后,Media 將源視頻轉碼成HLS支持的編碼格式和封裝格式,根據需求可輸出多個碼率分別送至 ,在中被切分成指定大小或時間長度的TS切片,并生成索引文件M3U8。
3
是一個HTTP文件服務器,負責將流媒體文件推送出去或響應客戶端的請求。客戶端只要訪問一級M3U8文件路徑就能自動播放HLS視頻流了。
4 M3U8文件簡介
4.1 M3U文件標簽及屬性說明
M3U文件中可以包含多個tag,每個tag的功能和屬性如下:
標簽
說明
#
每個M3U文件第一行必須是這個tag,起到標示作用。其格式如下:
#
#
指定每個媒體段(ts)的持續時間,這個僅對其后面的URI有效,每兩個媒體段URI間被這個tag分隔開,其格式如下:
#:,
(a) 表示持續的時間(秒)必須是整數,如果版本在3以上可以是浮點數。
(b) title是下載資源的url。
示例:
#:9.009,
#EXT-X-
表示媒體段是一個媒體URI資源中的一段,只對其后的media URI有效,格式如下:
#EXT-X-:[@o]
(a) 其中n表示這個區間的大小。
(b) o表在URI中的。
這個標簽出現在版本4中。
#EXT-X-
指定最大的媒體段時間長(秒)。所以#中指定的時間長度必須小于或是等于這個最大值。這個tag在整個文件中只能出現一 次(在嵌套的情況下,一般有真正ts url的m3u8才會出現該tag)。格式如下:
#EXT-X-:
(a) s表示最大的秒數。
示例:
#EXT-X-:10
#EXT-X-MEDIA-
每一個media URI 在 中只有唯一的序號,相鄰之間序號+1。格式如下:
#EXT-X-MEDIA-:
(a) 一個media URI并不是必須要包含的,如果沒有,默認為0。
示例:
#EXT-X-MEDIA-:2680
#EXT-X-KEY
表示怎么對media 進行解碼。其作用范圍是下次該tag出現前的所有media URI,格式如下:
#EXT-X-KEY:
(a) NONE 或者 AES-128。
如果是NONE,則URI以及IV屬性必須不存在,如果是AES-128( ),則URI必須存在,IV可以不存在。
對于AES-128的情況,和URI屬性共同表示了一個key文件,通過URI可以獲得這個key,如果沒有IV( ),則使用序列號作為IV進行編解碼,將序列號的高位賦到16個字節的中,左邊補0;如果有IV,則將改值當成16個字節的16進制數。
示例:
#EXT-X-KEY:=AES-128,URI=""
#EXT-X--DATE-TIME
將一個絕對時間或是日期和一個媒體段中的第一個相關聯,只對下一個meida URI有效,格式如下:
#EXT-X--DATE-TIME:
示例:
#EXT-X--DATE-TIME:2010-02-19T14:54:23.031+08:00
#EXT-X-ALLOW-CACHE
是否允許做cache,這個可以在文件中任意地方出現,并且最多出現一次,作用效果是所有的媒體段。格式如下:
#EXT-X-ALLOW-CACHE:
#EXT-X--TYPE
提供關于的可變性的信息, 這個對整個文件有效,是可選的,格式如下:
#EXT-X--TYPE:
(a) 如果是VOD,則服務器不能改變 文件。
(b) 如果是EVENT,則服務器不能改變或是刪除文件中的任何部分,但是可以向該文件中增加新的一行內容。
#EXT-X-
表示的末尾了,它可以在中任意位置出現,但是只能出現一個,格式如下:
#EXT-X-
EXT-X-MEDIA
被用來在中表示相同內容的不用語種/譯文的版本,比如可以通過使用3個這種tag表示3中不用語音的音頻,或者用2個這個tag表示不同角度的video在中。這個標簽是獨立存在的,其格式如下:
#EXT-X-MEDIA::該屬性列表中包含:URI、TYPE、GROUP-ID、、NAME、、。
(a) URI:如果沒有,則表示這個tag描述的可選擇版本在主的EXT-X--INF中存在;
(b) TYPE:AUDIO and VIDEO;
(c) GROUP-ID:具有相同ID的MEDIA tag,組成一組樣式;
(d) :確定使用的主要語言。
(e) NAME:人類可讀的語言的翻譯。
(f) : YES或是NO,默認是No,如果是YES,則客戶端會以這種選項來播放,除非用戶自己進行選擇。
(g) :YES或是NO,默認是No,如果是YES,則客戶端會根據當前播放環境來進行選擇(用戶沒有根據自己偏好進行選擇的前提下)。
#EXT-X--INF
指定一個包含多媒體信息的 media URI 作為,一般做M3U8的嵌套使用,它只對緊跟后面的URI有效建立索引自動標記文件,格式如下:
#EXT-X--INF:
有以下屬性:
(a) :帶寬,必須有。
(b) -ID:該值是一個十進制整數,惟一地標識一個在文件范圍內的特定的描述。一個 文件中可能包含多個有相同ID的此tag。(這個屬性在后面的協議版本廢除了)
(c) :指定流的編碼類型,不是必須的。
(d) :分辨率。
(e) AUDIO:這個值必須和AUDIO類別的“EXT-X-MEDIA”標簽中“GROUP-ID”屬性值相匹配。
(f) VIDEO:這個值必須和VIDEO類別的“EXT-X-MEDIA”標簽中“GROUP-ID”屬性值相匹配。
示例:
#EXT-X--INF:-ID=1, =, =
.M3U8
4.2 M3U8結構
M3U8文件其實就是以UTF-8編碼的M3U文件,該文件本身不能播放,只是用于存放待播放視頻流的基本信息。
如果你的視頻具備流切換功能,處于不同的帶寬、不同的網速播放不同清晰度的視頻流,這樣只能的流切換可以保證用戶感覺到非常流暢的觀影體驗,同時不同的設備也可以作為選擇的條件,比如視網膜屏可以在網速良好的情況下播放清晰度更高的視頻流。
這種功能的實現在于,索引文件的特殊結構。
如上圖所示,客戶端播放HLS視頻流的邏輯其實非常簡單,先下載一級Index file,它里面記錄了二級索引文件(-A、-B、-C)的地址,然后客戶端再去下載二級索引文件,二級索引文件中又記錄了TS文件的下載地址,這樣客戶端就可以按順序下載TS視頻文件并連續播放。
(1) HLS有兩級索引:
(a) 第一級索引存放的是不同碼率的HLS源的M3U8地址,也就是二級索引文件的地址。
(b) 第二級索引則記錄了同一碼率下TS切片序列的下載地址。
客戶端獲取一級M3U8文件后,根據自己的帶寬,去下載相應碼率的二級索引文件,然后再按二級索引文件的切片順序下載并播放TS文件序列。
4.3 HLS 會話模式
模式
說明
VOD
點播VOD的特點就是當前時間點可以獲取到所有index文件和ts文件,二級index文件中記錄了所有ts文件的地址。這種模式允許客戶端訪問全部內容。
LIVE
Live 模式就是實時生成M3u8和ts文件。它的索引文件一直處于動態變化的,播放的時候需要不斷下載二級index文件,以獲得最新生成的ts文件播放視頻。如果一個二級index文件的末尾沒有#EXT-X-標志,說明它是一個Live視頻流。
這種類型通過向索引文件添加媒體地址可以很容易的轉化為VOD類型。在轉化時不要移除原來舊的源,而是通過添加一個 #ET-X-標記來終止實時事件。轉化時如果你的索引文件中包含 EXT-X--TYPE標簽,你需要將值從EVENT改為 VOD。
客戶端在播放VOD模式的視頻時其實只需要下載一次一級index文件和二級index文件就可以得到所有ts文件的下載地址,除非客戶端進行比特率切換,否則無需再下載任何index文件,只需順序下載ts文件并播放就可以了。但是Live模式下略有不同,因為播放的同時,新ts文件也在被生成中,所以客戶端實際上是下載一次二級index文件,然后下載ts文件,再下載二級index文件(這個時候這個二級index文件已經被重寫,記錄了新生成的ts文件的下載地址),再下載新ts文件,如此反復進行播放。
4.4 索引文件分析
4.4.1 一級索引文件格式
第一級索引存放的是不同碼率的HLS源的M3U8地址,也就是二級索引文件的地址。
- #EXTM3U
- #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=500000, RESOLUTION=720x480
- mid_video_index.M3U8
- #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=800000, RESOLUTION=1280x720
- wifi_video_index.M3U8
- #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=3000000, CODECS="avc1.4d001e,mp4a.40.5", RESOLUTION=1920x1080
- h264main_heaac_index.M3U8
- #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=64000, CODECS="mp4a.40.5"
- aacaudio_index.M3U8
#
格式標簽,標明該文件是一個 M3U播放列表文件,必須存在于一二級列表的第一行。
#EXT-X--INF
特定流標簽,指示了該流的格式信息:
(a) -ID節目ID,一般不用考慮;
(b) :指定流的帶寬;
(c) :視頻分辨率;如果存在音頻分級,則需指定音頻的編碼格式,如上例中的最后兩項;
(d) -INF的下一行是二級index文件的路徑,可以用相對路徑也可以用絕對路徑。例子中用的是相對路徑。這個文件中記錄了不同比特率視頻流的二級index文件路徑,客戶端可以自己判斷自己的現行網絡帶寬,來決定播放哪一個視頻流。也可以在網絡帶寬變化的時候平滑切換到和帶寬匹配的視頻流。
4.4.2 二級索引文件格式
第二級索引則記錄了同一碼率下TS切片序列的下載地址。
(1) VOD形式
點播VOD的特點就是當前時間點可以獲取到所有index文件和ts文件,二級index文件中記錄了所有ts文件的地址。這種模式允許客戶端訪問全部內容。
下面的例子中就是一個點播模式下的m3u8的結構。
- #EXTM3U
- #EXT-X-TARGETDURATION:10
- #EXT-X-VERSION:3
- #EXT-X-PLAYLIST-TYPE:VOD
- #EXTINF:9.009,
- http://media.example.com/first.ts
- #EXTINF:9.009,
- http://media.example.com/second.ts
- #EXTINF:3.003,
- http://media.example.com/third.ts
- #EXT-X-ENDLIST
#
格式標簽,標明該文件是一個 M3U播放列表文件,必須存在于一二級列表的第一行。
#EXT-X--TYPE
#EXT-X--TYPE:VOD的意思是當前的視頻流并不是一個直播流,而是點播流,換句話說就是該視頻的全部的ts文件已經被生成好了。
#EXT-X-
表示切片的最大時長,單位是秒。#EXT-X-:10表示列表中表示的每個切片時長不超過10秒。
#EXT-X-
表示協議兼容性版本。
#
切片的實際時長,若要求取整,則其數值不能大于EXT-X-的值。
對應的切片文件(路徑),可以是絕對路徑,也可以是相對路徑。
#EXT-X-
表示整個碼流的結束,不再向后附加新的切片列表。有這個標志同時也說明當前的流是一個非直播流。
(2) Live形式
Live 模式就是實時生成M3u8和ts文件。它的索引文件一直處于動態變化的,播放的時候需要不斷下載二級index文件,以獲得最新生成的ts文件播放視頻。如果一個二級index文件的末尾沒有#EXT-X-標志,說明它是一個Live視頻流。
- #EXT-X-VERSION:3
- #EXT-X-TARGETDURATION:8
- #EXT-X-MEDIA-SEQUENCE:2680
-
- #EXTINF:7.975,
- https://priv.example.com/fileSequence2680.ts
- #EXTINF:7.941,
- https://priv.example.com/fileSequence2681.ts
- #EXTINF:7.975,
- https://priv.example.com/fileSequence2682.ts
#EXT-X-MEDIA-
媒體序列號,表示出現在當前M3U8文件中的第一個的序列號。
Live形式的M3U8一般用于直播,列表中的文件數有限制,推薦配置中是3個,服務端會實時更新該列表,刪除最開始的,并向后面添加新生成的。因此,這種模式下,當網絡帶寬不足時,客戶端來不及下載新的M3U8和對應的切片文件,會導致切片丟失,播放卡頓。
(3) 加密形式:
- #EXTM3U
- #EXT-X-VERSION:3
- #EXT-X-MEDIA-SEQUENCE:7794
- #EXT-X-TARGETDURATION:15
-
- #EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"
-
- #EXTINF:2.833,
- http://media.example.com/fileSequence52-A.ts
- #EXTINF:15.0,
- http://media.example.com/fileSequence52-B.ts
- #EXTINF:13.333,
- http://media.example.com/fileSequence52-C.ts
-
- #EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=53"
-
- #EXTINF:15.0,
- http://media.example.com/fileSequence53-A.ts
HLS可以被加密。客戶端通過讀取M3U8文件中的#EXT-X_KEY標簽可以獲取解密的密鑰。EXT-X-KEY指示的密鑰信息作用于當前EXT-X-KEY標簽至下一個EXT-X-KEY標簽(若沒有下一個,則到最后一個)之間的所有。指示加密算法,可用的取值有NONE、AES-128和-AES,NONE表示不加密。URI指示獲取密鑰的路徑,該項不可省略,除非為NONE。
5 流測試網址