參考文檔:https://datatracker.ietf.org/doc/html/rfc8216
一、m3u8協議概述
m3u8 協議是基于 M3U 格式擴展而來的一種多媒體播放列表協議,主要用于流媒體的索引和分發,尤其在 HLS(HTTP Live Streaming)技術中扮演核心角色。它通過文本文件(.m3u8 擴展名)描述媒體片段的地址、時長、編碼信息等,讓客戶端能夠按順序請求并播放流媒體內容。
-
起源:m3u8 源于傳統的 M3U 文件(一種音頻播放列表格式,后綴為.m3u),為適應流媒體和 UTF-8 編碼需求,擴展出.m3u8 格式(強制使用 UTF-8 編碼)。
-
核心作用:作為流媒體的 “導航地圖”,告訴客戶端:
- 流媒體包含哪些片段(如.ts 視頻切片);
- 每個片段的網絡地址、時長、碼率;
- 可選的多碼率版本(方便客戶端根據網絡狀況切換清晰度)。
二、m3u8文件結構與語法
HLS(HTTP Live Streaming) 把整個流分成?個個?的基于 HTTP 的?件來下載,每次只下載?些。HLS 協議由三部分組成:HTTP、M3U8、TS。這三部分中,HTTP 是傳輸協議,M3U8 是索引?件,TS是?視頻的媒體信息。
HLS 是提供?個 m3u8 地址,Apple 的 Safari 瀏覽器直接就能打開 m3u8 地址,譬如:
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"
</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
有?個關鍵的參數,這些參數在 SRS 的配置?件中都有配置項:
-
#EXTM3U
:每個M3U?件第??必須是這個tag,請標示作? -
#EXT-X-VERSION
:該屬性可以沒有,?前主要是version 3,最新的是7 -
#EXT-X-MEDIA-SEQUENCE
:每?個media URI在PlayList中只有唯?的序號,相鄰之間序號+1,?個media URI并不是必須要包含的,如果沒有,默認為0 -
#EXT-X-TARGETDURATION
:所有切?的最?時?。有些 Apple 設備這個參數不正確會?法播放。SRS 會?動計算出 ts ?件的最?時?,然后更新 m3u8 時會?動更新這個值。?戶不必??配置。 -
#EXTINF
:ts 切?的實際時?,SRS 提供配置項 hls_fragment,但實際上的 ts 時?還受 gop 影響。 -
ts ?件的數?:SRS 可配置 hls_window(單位是秒,不是數量),指定 m3u8 中保存多少個切?,譬如,每個 ts 切?為 10 秒,窗?為 60 秒,那么 m3u8 中最多保存 6 個 ts 切?,SRS 會?動清理舊的切?。
-
livestream-67.ts:SRS 會?動維護 ts 切?的?件名,在編碼器重推之后,這個編號會繼續增?,保證流的連續性。直到 SRS 重啟,這個編號才重置為 0。
每?個 .m3u8 ?件,分別對應若?個 ts ?件,這些 ts ?件才是真正存放視頻的數據。m3u8 ?件只是存放了?些 ts ?件的配置信息和相關路徑,當視頻播放時,.m3u8 是動態改變的,video標簽會解析這個?件,并找到對應的 ts ?件來播放,所以?般為了加快速度,.m3u8 放在 web 服務器上,ts ?件放在 cdn 上。.m3u8 ?件,其實就是以 utf-8 編碼的 m3u ?件,這個?件本身不能播放,只是存放了播放信息的?本?件。
進入SRS服務器對應的視頻流路徑,可以查看到.m3u8文件
srs/trunk/objs/nginx/html/live
比如這里有個livestream
和livestream2
的視頻流,目錄下就存在對應的livestream.ts
、livestream2.ts
文件
查看對應的livestream.m3u8
cat livestream.m3u8
m3u8 與 HLS 的關系
- HLS 是蘋果公司推出的流媒體傳輸協議,而 m3u8 是 HLS 協議中用于描述媒體片段的索引文件格式。
- HLS 的工作流程依賴 m3u8:
- 服務器將視頻切分為短片段(通常 5-10 秒,格式為.ts);
- 生成 m3u8 文件,列出所有.ts 片段的地址和信息;
- 客戶端請求 m3u8 文件,根據其內容依次下載并播放.ts 片段;
- 直播場景中,服務器會定期更新 m3u8 文件(刪除舊片段,添加新片段),客戶端周期性拉取最新列表。
三、m3u8示例
3.1 簡單的點播 m3u8 文件
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
video_0.ts # 第一個10秒的視頻片段
#EXTINF:10.0,
video_1.ts # 第二個10秒的視頻片段
#EXTINF:5.0,
video_2.ts # 最后一個5秒的視頻片段
#EXT-X-ENDLIST # 標識播放結束
3.2 多碼率直播 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
-
包含多種?特率的 Master Playlist。該?件是?個實際使?中的頂級 m3u8 ?件,該?件中?定義了
http://example.com/low.m3u8
、http://example.com/mid.m3u8
等 ? 個 ? 級 ? 件 。 頂 級m3u8 ?件主要是做碼率適配的,?級 m3u8 才是真正的切??件,客戶端會默認選擇碼率最?的請求 -
如果發現碼率達不到,會請求降低碼率的流。客戶端拿到?級 m3u8 ?件后,會繼續請求??的?件,這時就可以進?播放了。
四、基礎概念
4.1 Playlist file
-
?個 m3u 的 Playlist 就是?個由多個獨??組成的?本?件,每?由回?/換?區分。每??可以是?個URI、空??或是?個 以 “#” 號開頭的字符串,并且空格只能存在于??中不同元素間的分隔。
-
?個 URI 表示?個媒體段或是 “variant Playlist file”(最多?持?層嵌套,即?個 m3u8 ?件中嵌套另?個 m3u8),以 “EXT” 開頭的表示?個 “tag”,否則表示注釋,直接忽略。
4.2 Tags
1. #EXTM3U
每個m3u8文件第一行必須是這個tag,如上述兩個示例。
2. #EXT-X-VERSION
- 作用:指定m3u8文件的版本號。
- 格式:
#EXT-X-VERSION:<版本號>
- 示例:
#EXT-X-VERSION:3
3. #EXTINF
- 作用:指定每個媒體段(ts文件)的持續時間,僅對其后的URI有效,每兩個媒體段URI間需用此tag分隔。
- 格式:
#EXTINF:<duration>,<title>
- 示例:
#EXTINF:14.357, no desc
- 參數說明:
duration
:表示持續時間(單位:秒)。若協議版本小于3,duration
必須為整數;版本≥3時可使用浮點數。
4. #EXT-X-BYTERANGE
- 作用:表示媒體段是某一媒體URI資源中的一段,僅對其后的media URI有效。
- 格式:
#EXT-X-BYTERANGE:<n>[@o]
- 參數說明:
n
:表示該區間的大小(字節)。o
:表示在URI中的偏移量(可選)。
- 備注:該標簽在協議版本4及以上出現。
5. #EXT-X-TARGETDURATION
- 作用:指定當前視頻流中單個切片(ts文件)的最大時長(單位:秒)。
#EXTINF
中指定的時間長度必須小于或等于該最大值。 - 格式:
#EXT-X-TARGETDURATION:<s>
- 參數說明:
s
表示最大秒數。 - 備注:在整個Playlist文件中只能出現一次(嵌套場景中,通常包含真實ts url的m3u8文件才會出現此tag)。
6. #EXT-X-MEDIA-SEQUENCE
- 作用:每個media URI在Playlist中擁有唯一序號,相鄰序號遞增1。
- 格式:
#EXT-X-MEDIA-SEQUENCE:<number>
- 備注:若未包含此tag,默認序號從0開始。
7. #EXT-X-KEY
- 作用:定義對media segments的解碼方式,作用范圍為下次該tag出現前的所有media URI。
- 格式:
#EXT-X-KEY:<attribute-list>
- 參數說明:
METHOD
:加密方法,可選值為NONE
(不加密)或AES-128
(AES-128加密)。- 若
METHOD=NONE
,則URI
和IV
屬性必須不存在。 - 若
METHOD=AES-128
(Advanced Encryption Standard),則URI
必須存在,IV
可選。
- 若
URI
:密鑰文件的獲取地址(當METHOD=AES-128
時必選)。IV
:初始化向量(Initialization Vector)。若未指定,默認使用媒體序列號(#EXT-X-MEDIA-SEQUENCE
)作為IV(將序列號高位填入16字節buffer,左側補0);若指定,需為16字節的十六進制字符串。
8. #EXT-X-PROGRAM-DATE-TIME
- 作用:將絕對時間或日期與媒體段中的第一個樣本關聯,僅對下一個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
9. #EXT-X-ALLOW-CACHE
- 作用:指定是否允許緩存媒體段,對所有媒體段有效。
- 格式:
#EXT-X-ALLOW-CACHE:<YES|NO>
- 備注:可在Playlist文件中任意位置出現,最多出現一次。
10. #EXT-X-PLAYLIST-TYPE
- 作用:提供關于Playlist可變性的信息,對整個Playlist文件有效(可選標簽)。
- 格式:
#EXT-X-PLAYLIST-TYPE:<EVENT|VOD>
- 參數說明:
VOD
:點播視頻。服務器不能修改Playlist文件,所有ts文件已生成完畢。EVENT
:實時生成m3u8和ts文件。服務器不能修改或刪除Playlist文件中的內容,但可追加新行,播放時需不斷下載二級index文件。
11. #EXT-X-ENDLIST
- 作用:表示m3u8文件的結束,直播(live)m3u8文件通常不含此tag。
- 格式:
#EXT-X-ENDLIST
- 備注:可在Playlist中任意位置出現,但僅能出現一次。
12. #EXT-X-MEDIA
- 作用:在Playlist中表示相同內容的不同語種/譯文版本(如多語言音頻、多視角視頻),標簽獨立存在。
- 格式:
#EXT-X-MEDIA:<attribute-list>
- 屬性列表說明:
URI
:若未指定,表明該tag描述的可選版本存在于主Playlist的EXT-X-STREAM-INF
中。TYPE
:類型,可選AUDIO
(音頻)或VIDEO
(視頻)。GROUP-ID
:具有相同ID的EXT-X-MEDIA
標簽組成一組樣式。LANGUAGE
:標識該版本使用的主要語言。NAME
:人類可讀的描述字符串,若LANGUAGE
存在,描述應使用該語言。DEFAULT
:是否默認選擇,可選YES
或NO
(默認NO
)。若為YES
,客戶端默認播放此版本(用戶手動選擇除外)。AUTOSELECT
:是否自動選擇,可選YES
或NO
(默認NO
)。若為YES
,客戶端在用戶未指定偏好時,根據播放環境自動選擇。
- 備注:該標簽在協議版本4及以上出現。
13. #EXT-X-STREAM-INF
- 作用:指定包含多媒體信息的media URI作為Playlist,通常用于m3u8嵌套,僅對緊跟其后的URI有效。
- 格式:
#EXT-X-STREAM-INF:<attribute-list>
- 常用屬性說明:
BANDWIDTH
:帶寬(必選)。PROGRAM-ID
:十進制整數,唯一標識Playlist文件范圍內的特定描述,可重復。CODECS
:指定流的編碼類型(可選)。RESOLUTION
:分辨率(可選)。AUDIO
:值需與AUDIO
類別EXT-X-MEDIA
標簽的GROUP-ID
屬性匹配(可選)。VIDEO
:同上,與VIDEO
類別EXT-X-MEDIA
標簽的GROUP-ID
匹配(可選)。
14. #EXT-X-DISCONTINUITY
- 作用:標識后續媒體段的以下屬性發生變化:
- 文件格式(file format)
- 軌道數量和類型(number and type of tracks)
- 編碼參數(encoding parameters)
- 編碼序號(encoding sequence)
- 時間戳序號(timestamp sequence)
15. #ZEN-TOTAL-DURATION
- 作用:表示該m3u8文件所包含的ts文件總時長。
更多資料:https://github.com/0voice