1 HLS的簡介
1.1 HLS的背景
從 RTMP(Real-Time Messaging Protocol,實時消息傳輸協議) 到 HLS(HTTP Live Streaming,HTTP直播流) 的技術演進,本質上是直播協議從 專有協議 向 通用 Web 協議 的轉變,也是適應互聯網環境(如瀏覽器支持、移動端普及)的必然結果。
1. RTMP的核心問題
- 依賴Flash Player:RTMP是Adobe開發的專有協議,長期依賴Flash插件實現瀏覽器播放。但Flash存在安全漏洞多、移動端支持差(如早期iOS不支持)等問題,逐漸被淘汰。
- 防火墻與跨平臺限制:RTMP通常使用非標準端口(如1935),容易被防火墻攔截;且無法直接在HTML5中播放,需插件支持。
- 實時性與靈活性的矛盾:RTMP雖實時性強(延遲約1-3秒),但封裝格式(FLV)和傳輸方式難以適應動態網絡環境(如弱網、帶寬波動)。
2. HLS的設計目標
- 基于HTTP協議:利用HTTP的廣泛兼容性(瀏覽器原生支持)和防火墻友好性,無需額外插件即可播放。
- 分段傳輸(Chunked Transfer):將直播流分割為小尺寸的媒體片段(如TS/MP4文件),支持動態調整碼率,適應不同網絡條件。
- 無狀態協議:HTTP的無狀態特性使服務器架構更簡單,易于擴展(如CDN分發),降低直播成本。
HLS的核心問題
HLS 的延遲問題確實是其最被詬病的缺點之一,實際應用中延遲通常在 5-30 秒 之間(不同場景差異較大),極端情況下可能更高。這一現象是由其 設計機制 和 網絡傳輸特性 共同決定的 后面解釋
1.2 HLS的工作原理
- 音視頻采集
攝像機等設備獲取原始的音頻和視頻信號 ,這些信號是未經處理的模擬或數字信號。比如攝像機捕捉現場畫面,麥克風收錄現場聲音。 - 媒體編碼
- 位置與作用:采集到的音視頻輸入到服務器中的媒體編碼器(Media encoder )。媒體編碼器會按照特定的編碼標準,如視頻常用的 H.264、H.265,音頻常用的 AAC 等 ,對原始音視頻數據進行壓縮編碼。這一步是為了減小數據量,便于后續的傳輸和存儲 。
- 編碼原理:以 H.264 為例,它利用幀間預測、變換編碼等技術,去除視頻中的冗余信息 。比如對于連續的相似幀,只記錄關鍵幀和幀間差異,大幅降低數據量。
- 流分段
- 處理過程:編碼后的音視頻數據形成 MPEG - 2 傳輸流,進入流分段器(Stream segmenter )。流分段器將連續的媒體流切割成一個個小的片段,通常這些片段是.ts(MPEG - 2 傳輸流格式)格式 ,每個片段時長一般為幾秒到十幾秒 。例如設置每個片段時長為 5 秒,流分段器就會按時間間隔把流切割成相應的小段。
- 目的:分段是 HLS 的關鍵特性,便于客戶端按順序下載播放,也利于實現碼率自適應等功能 。
- 分發準備
- 索引文件生成:源 Web 服務器(Origin web server )會生成一個索引文件(Index file ,通常是.m3u8 格式 )。索引文件記錄了各個媒體片段的信息,包括片段的 URL 地址、時長等 。比如索引文件會明確指出第一個.ts 片段的地址在哪,第二個片段地址在哪等。
- 文件存儲:服務器將生成的媒體片段(.ts 文件 )和索引文件存儲好,等待客戶端請求 。
- 網絡傳輸
最終通過 HTTP 協議,服務器將索引文件和媒體片段傳輸給客戶端 。客戶端通過解析索引文件,按順序下載媒體片段進行播放 。
2 HLS 基本框架
服務器
- 復用與封裝
編碼后的音視頻基本流,會被復用并封裝成符合 MPEG - 2 系統層標準的傳輸流(TS)格式。MPEG - 2 TS 格式能將音視頻媒體流嚴格按時序交織復用 。這樣,任意截取和分段后的每個小段,都可獨立解碼和播放**。每個 TS 文件開頭需包含節目關聯表(PAT)和節目映射表(PMT) ;含視頻的文件,還得有至少一個關鍵幀及序列頭等信息,用于解碼器初始化**。 - 流分割處理
流分割器(Stream Segmenter)會將編碼器輸出的 MPEG - 2 TS 流,分割成一系列連續且長度均等的小 TS 文件(后綴為.ts )。同時,流分割器會創建一個索引文件(采用擴展的 M3U 播放列表格式,后綴名.m3u8 ) ,該文件包含指向小 TS 文件的指針。索引文件類似播放列表滑動窗口,每當生成新 TS 文件,其內容就會更新 ,新文件 URI 添加到末尾,舊的被移除,始終保持固定數量的最新分段信息。此外,流分割器還可對小 TS 文件加密,并生成密鑰文件。
之所以采用 MPEG - 2 TS 格式統一封裝編碼后的媒體流,**是因其具備讓各分段獨立解碼播放的特性。M3U8 索引文件是由若干文本行組成的文本文件 ,每行可能是 URI、**空行或以注釋符 “#” 起始的行 。其中,URI 指向分段媒體文件或衍生索引文件;以 “#EXT” 起始的行是標簽行,其他 “#” 起始行是可忽略的注釋。以下是一個簡單.m3u8 索引文件示例,其表示的媒體流由 5 個時長 5秒的未加密 TS 文件構成。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:54
#EXT-X-TARGETDURATION:6
#EXTINF:5.000, no desc
livestream-54.ts
#EXTINF:5.000, no desc
livestream-55.ts
#EXTINF:5.002, no desc
livestream-56.ts
#EXTINF:5.018, no desc
livestream-57.ts
#EXTINF:5.982, no desc
livestream-58.ts
內容分發
HLS 內容分發系統通過 HTTP 協議傳輸分割后的媒體文件(.ts)和索引文件(.m3u8),可直接使用普通 Web 服務器或 CDN,無需特殊配置,僅需關聯 MIME 類型:
.m3u8 → application/vnd.apple.mpegurl
.ts → video/MP2T
關鍵優化:
.m3u8 文件:設短緩存時間(如 5-10 秒),避免客戶端獲取舊索引,確保實時性。
.ts 文件:設長緩存時間(如 24 小時),減少重復下載,提升效率。
通過 CDN 加速和合理緩存策略,可高效分發內容,平衡實時性與帶寬成本。
客戶端
- 獲取索引文件(.m3u8)
客戶端通過網頁 URL 請求服務器獲取 HLS 索引文件,文件中包含:
當前可用的 TS 媒體片段 URL 列表
解密密鑰地址(若加密)
多碼率替換流索引(可選) - 下載與緩沖媒體片段
按索引順序下載 TS 文件,至少緩沖 1-2 個片段 后開始播放(推薦 2 個以保證無縫銜接)。(這無疑是延時的重要原因)
直播場景中,客戶端周期性刷新索引文件,獲取最新片段 URL 并添加到下載隊列。
點播場景中,遇 #EXT-X-ENDLIST 標簽則結束播放。 - 解碼與播放
拼裝 TS 片段為完整流,送播放器解碼。
加密流需通過索引獲取密鑰,完成用戶認證和解密。
?絡?適應的流間切換和故障保護
- 多碼率流的預先生成
服務器端對同一音視頻源進行不同碼率的編碼(如 240P/360P/720P/1080P 等),生成多套 TS 媒體片段(每個碼率對應獨立的 TS 片段序列)。
為每套碼率流生成獨立的索引文件(.m3u8),記錄該碼率下 TS 片段的 URL、時長等信息。
** 主索引文件(Master Playlist)** 中包含所有碼率流的索引文件地址,格式如下:
plaintext
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=500000,RESOLUTION=854x480 # 低碼率流
http://example.com/low.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720 # 高碼率流
http://example.com/high.m3u8
- 客戶端動態切換邏輯
實時監測網絡帶寬:通過下載速度、緩沖狀態、RTT(往返時間)等指標估算當前可用帶寬。
比較帶寬與碼率閾值:若當前帶寬低于某碼率的最低要求(如 720P 需至少 2Mbps),則切換至更低碼率;若帶寬充足,則切換至更高碼率以提升畫質。
平滑過渡機制:切換時等待當前片段播放完畢,再從新碼率的下一個片段開始加載,避免畫面中斷。
HLS(HTTP Live Streaming)被稱為 “以點播形式實現直播”,核心在于其技術實現邏輯完全基于HTTP 協議的文件分塊下載機制,而非傳統直播協議的實時數據流傳輸
- 傳統直播與HLS的本質區別
對比維度 | 傳統直播協議(如RTMP/RTSP) | HLS |
---|---|---|
數據傳輸形式 | 基于TCP/UDP的實時數據流,服務器持續推送數據。 | 基于HTTP的文件分塊下載,數據封裝為獨立TS文件。 |
客戶端獲取方式 | 直接接收連續數據流,邊收邊解。 | 主動下載分段文件(TS片段),拼裝后播放。 |
服務器角色 | 實時生成數據流并推送。 | 提前生成或實時切割TS文件,供客戶端拉取。 |
- 為什么說HLS的“直播是點播的變種”?
- 無實時數據流,只有文件序列
- 傳統直播協議中,服務器與客戶端建立長連接,數據流如“水管放水”般連續傳輸。
- HLS中,服務器僅提供文件列表和文件資源,客戶端通過“下載文件序列”模擬直播,本質是點播技術的時序化應用。
- 延遲來源于文件分塊和緩沖
- 直播延遲的核心原因:
- 文件分塊時長:每個TS文件至少5秒,服務器生成新文件需要時間。
- 緩沖機制:客戶端需下載并緩沖多個片段(如2個10秒片段)才能開始播放。
- 對比傳統直播:RTMP協議延遲可低至1-3秒,而HLS典型延遲為20-30秒(因需等待文件生成和下載)。
3 m3u8協議
示例1:單碼率媒體流索引
#EXTM3U # M3U8文件標識(必填)
#EXT-X-VERSION:3 # 協議版本號(如3)
#EXT-X-ALLOW-CACHE:YES # 允許緩存(YES/NO)
#EXT-X-MEDIA-SEQUENCE:2 # 起始媒體段序列號(從2開始)
#EXT-X-TARGETDURATION:16 # 單個TS片段最大時長(秒),需≥所有#EXTINF值
#EXTINF:14.357, no desc # 片段時長(秒)+描述(可選)
livestream-2.ts # 媒體段URI(對應TS文件)
#EXTINF:15.617, no desc
livestream-3.ts
#EXTINF:14.358, no desc
livestream-4.ts
- 特點:直接列出TS文件URI,用于單一碼率的直播或點播流。
示例2:多碼率適配流索引(主索引文件)
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000 # 子流帶寬(必填)
http://example.com/low.m3u8 # 低碼率子索引URI
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000
http://example.com/mid.m3u8 # 中碼率子索引URI
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000,RESOLUTION=1080x720
http://example.com/hi.m3u8 # 高碼率子索引URI(含分辨率)
- 特點:通過
#EXT-X-STREAM-INF
標簽嵌套子M3U8文件,每個子索引對應不同碼率流,客戶端根據帶寬動態選擇。
** M3U8核心標簽解析**
M3U8是純文本文件,由標簽(Tag)、URI和注釋組成,以#
開頭的行為標簽或注釋,其余為URI或空行。以下是關鍵標簽:
標簽 | 說明 | 必填性 | 示例 |
---|---|---|---|
#EXTM3U | 文件頭,標識為M3U8格式(必填) | 是 | 第一行固定為此標簽 |
#EXT-X-VERSION | 協議版本號(如3/4),影響標簽兼容性(如#EXT-X-BYTERANGE需版本≥4) | 否 | #EXT-X-VERSION:3 |
#EXTINF | 定義后續URI對應的TS片段時長(秒)和描述(可選) | 是(單碼率) | #EXTINF:10.0, Live segment 1 |
#EXT-X-TARGETDURATION | 最大片段時長(秒),需≥所有#EXTINF值,全局唯一 | 是(單碼率) | #EXT-X-TARGETDURATION:10 |
#EXT-X-MEDIA-SEQUENCE | 媒體段序列號,后續片段依次遞增(默認從0開始) | 否 | #EXT-X-MEDIA-SEQUENCE:1 |
#EXT-X-KEY | 加密配置(NONE/AES-128),指定密鑰URI和初始化向量(IV) | 否 | #EXT-X-KEY:METHOD=AES-128,URI=“key.bin”,IV=0x1234… |
#EXT-X-STREAM-INF | 多碼率場景下,定義子索引文件的帶寬、分辨率等屬性(嵌套子M3U8時必填) | 是(多碼率) | #EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1080x720 |
#EXT-X-ENDLIST | 標識點播流結束(直播流無此標簽) | 否(點播) | #EXT-X-ENDLIST |
** 關鍵機制說明**
-
單碼率與多碼率切換
- 單碼率:客戶端直接下載TS片段,適用于固定網絡環境。
- 多碼率:
- 主索引文件列出各碼率子索引(含帶寬、分辨率等信息)。
- 客戶端根據實時帶寬選擇子索引,如帶寬不足2Mbps時自動切換至
low.m3u8
。
-
緩存與更新策略
#EXT-X-ALLOW-CACHE:NO
:禁止緩存M3U8文件,確保客戶端每次獲取最新索引(適用于直播)。- 瀏覽器對M3U8的緩存由HTTP頭(如
Cache-Control
)控制,建議設置短緩存時間(如5秒)。
-
加密與解密
- 通過
#EXT-X-KEY
標簽啟用AES-128加密:METHOD=NONE
:不加密(默認)。METHOD=AES-128
:需指定密鑰文件URI(如http://example.com/key.bin
),IV可選(缺省則用序列號生成)。
- 通過
** 直播與點播場景差異**
場景 | 關鍵特征 | 標簽差異 |
---|---|---|
直播 | 索引文件動態更新,持續追加新TS片段URI,無結束標簽 | 無#EXT-X-ENDLIST ,需定期刷新索引 |
點播 | 索引文件固定,包含完整TS列表,末尾需#EXT-X-ENDLIST 標識結束 | 包含#EXT-X-ENDLIST ,無需刷新索引 |
2.5 嵌套層級限制
- M3U8僅支持一層嵌套:主索引文件(多碼率)嵌套子索引文件(單碼率),子索引文件直接指向TS片段。
- 禁止多層嵌套(如主索引→子索引→孫索引),避免解析復雜度過高。
總結
M3U8文件通過標準化標簽體系實現了對TS片段的有序管理,其核心價值在于:
- 單碼率場景:提供簡單、可靠的片段索引。
- 多碼率場景:結合客戶端帶寬自適應,保障不同網絡下的播放體驗。
- 擴展性:通過標簽支持加密、時間同步、多語言軌道等高級功能。
4 ts協議解析
4.1 基本框架
TS(Transport Stream,傳輸流)文件的分層結構設計精巧,由下至上可分為三層,這種分層模式使得音視頻數據在傳輸過程中更高效、穩定,各層各司其職,協同保障數據準確無誤地流轉與處理。
- ES 層(Elementary Stream,基本碼流層):這是最底層,處于音視頻數據的初始狀態,即經過壓縮編碼后的原始音視頻數據。視頻編碼多采用 H.264、H.265 等格式,音頻編碼常用 AAC、MP3 等格式。在這一層,數據以連續碼流形式存在,一個 ES 流僅包含單一類型數據,如純視頻、純音頻或純字幕。例如,一個 H.264 編碼的視頻 ES 流,其中全是按照 H.264 標準編碼的視頻數據,不摻雜音頻等其他類型信息 。其作用是提供最原始的音視頻內容素材,是整個 TS 文件數據的基石,后續各層都是基于此進行加工和處理。
- PES 層(Packet Elemental Stream,分組基本碼流層):在 ES 層基礎上構建,主要工作是在 ES 數據中加入時間戳(PTS/DTS)等關鍵信息。由于 ES 數據包通常較大,為便于傳輸與處理,會將 ES 流分割成長度不等的數據包,并為每個數據包添加 PES 包頭。其中,PTS(Presentation Time Stamp,顯示時間戳)用于指示視頻幀或音頻樣本應在何時顯示或播放;DTS(Decoding Time Stamp,解碼時間戳)指明數據應在何時進行解碼。對于視頻數據,I 幀和 P 幀一般同時具備 PTS 和 DTS,而 B 幀只需 PTS(因為其解碼順序與顯示順序不同,I、P 幀的 PTS 等于 DTS,若視頻無 B 幀,PTS 與 DTS 始終相同) 。PES 層通過這些時間戳信息,確保音視頻數據在解碼和播放過程中的時間順序準確無誤,實現音視頻的同步播放。例如,在一段包含多個 I、P、B 幀的視頻 PES 流中,每個幀對應的 PES 包會攜帶準確的 PTS 和 DTS,播放器依據這些時間戳來決定何時解碼、何時顯示每一幀畫面。
- TS 層(Transport Stream,傳輸流層):位于最上層,在 PES 層之上進一步添加了數據流識別信息與傳輸信息。TS 包大小固定為 188 字節(擴展后為 204 字節,含 16 字節 CRC 校驗),由三部分組成:
- TS Header(TS 包頭):固定為 4 字節,是每個 TS 包的起始標識,包含諸多關鍵控制信息。如同步字節(固定值 0x47,用于快速識別 TS 包起始位置)、傳輸錯誤指示(1 位,用于標記該包在傳輸過程中是否出現錯誤)、負載單元起始指示(1 位,指示包凈荷是否為新的存取單元起始,如視頻幀起始)、PID(Packet Identifier,包標識符,13 位,是區分不同數據流的關鍵,0x0000 代表 PAT 表,0x0001 代表條件訪問表等)、連續計數器(4 位,每發送一個相同 PID 的 TS 包,計數器遞增 1,從 0 到 15 循環,用于檢測包丟失)等。
- Adaptation Field(自適應字段):并非每個 TS 包都有,其存在的主要目的是為不足 188 字節的數據進行填充,以及插入節目時鐘參考(PCR,Program Clock Reference)等重要信息。PCR 對于恢復與編碼端一致的時鐘順序至關重要,通常每隔 100ms 至少傳輸一次,它作為解碼器解碼時的時鐘參考基準,調整本地時鐘以與編碼端同步。一般在視頻幀的首個和最后一個 TS 包中添加自適應字段,中間的 TS 包若無需求則可不加。
- Payload(有效載荷):承載的數據類型多樣,可能是 PES 數據(即音視頻數據經 PES 層封裝后的結果),也可能是節目專用信息 PSI(如 PAT、PMT 表)。PAT(Program Association Table,節目關聯表)用于列出所有節目及對應的 PMT 表 PID;PMT(Program Map Table,節目映射表)針對每個節目,詳細定義其包含的音視頻流的 PID、編碼格式、分辨率等關鍵參數,是解析 TS 流、分離出音視頻流的重要依據。
4.2 重點內容解析
TS 流解析的核心邏輯與 PID 體系
TS 流通過 PID(Packet Identifier) 實現不同類型數據的區分與復用,核心數據類型包括:
- PAT 表(Program Association Table,PID=0x0000):全局索引表,指向各節目的 PMT 表位置。
- PMT 表(Program Map Table):節目映射表,定義特定節目包含的音視頻流 PID 及編碼參數。
- 音頻流 / 視頻流:承載實際音視頻數據的媒體流。
解析流程:
定位 PAT 表:通過固定 PID(0x0000)獲取 PAT 表。
解析 PMT 位置:從 PAT 中提取目標節目的 PMT 表 PID。
獲取音視頻流:通過 PMT 表找到對應音頻流和視頻流的 PID。
數據解復用:根據音視頻 PID 過濾 TS 包,提取媒體數據
在 TS(Transport Stream)協議和相關流媒體場景中,“節目(Program)” 是一個邏輯概念,用于對音視頻內容及相關數據進行分組管理。它可以理解為一個完整的多媒體內容集合,包含了一組相互關聯的音視頻流、字幕流等,共同構成可供觀眾觀看或收聽的完整內容單元
PID 是什么?
就像快遞分揀站的 “包裹標簽”。
作用:TS 流里有很多種數據(比如視頻、音頻、節目表等),每個數據都要貼一個 “標簽”(PID),這樣接收端才能知道 “這個包裹里裝的是什么”。
比如:
貼了 “標簽 0” 的包裹:里面裝的是 “節目總目錄”(PAT 表),告訴用戶有哪些頻道 / 節目。
貼了 “標簽 100” 的包裹:里面裝的是 “某個頻道的視頻數據”。
貼了 “標簽 200” 的包裹:里面裝的是 “這個頻道的音頻數據”。
特點:
全局唯一:整個 TS 流里,每個標簽(PID)只能對應一種數據,不能重復。
必須有:就像快遞必須有標簽才能分揀,TS 流里的節目表(PAT/PMT)必須用固定標簽(如 PID=0)傳輸,否則接收端看不懂。
自適應區(Adaptation Field)的長度與結構
- 長度要求:
自適應區的總長度需包含 傳輸錯誤指示符(1 字節)。若實際數據不足,剩余字節用 0xFF 填充(類似補白)。 - 作用場景:
視頻 / 音頻流:必須添加自適應區,通常位于幀的首個 TS 包和最后一個 TS 包,用于插入 PCR 時鐘或填充數據。
PAT/PMT 表:無需自適應區,直接用 0xFF 補足長度即可。
PCR、DTS、PTS 的關系與作用
-PCR(節目時鐘參考)
本質:
對系統時鐘的采樣值,用于解碼器同步本地時鐘(類似 “時間基準”)。
特點:
單調遞增(不能回退),通常每 100ms 插入一次。
僅視頻流需要,音頻流通過 PTS 與視頻同步,無需 PCR。
-用途:可直接作為 DTS(解碼時間戳) 使用,簡化時間戳管理。