HTTP Live Streaming 是 Apple 實(shí)現(xiàn)的基于 HTTP 的自適應(yīng)比特率流通信協(xié)議,使用 HLS 可以直播(live)和點(diǎn)播(on-demand)音、視頻。由于 HLS 采用了 HTTP 協(xié)議,使用普通 web 服務(wù)器和內(nèi)容分發(fā)網(wǎng)絡(luò)(Content Delivery Network,簡(jiǎn)寫(xiě) CDN)即可。HLS 專為可靠性而設(shè)計(jì),可以根據(jù)網(wǎng)絡(luò)狀況動(dòng)態(tài)播放當(dāng)前可播放最佳質(zhì)量音視頻。
目前,iOS、macOS、tvOS、PC、Android 等均支持 HLS 協(xié)議,HLS 是應(yīng)用最為廣泛的流協(xié)議。

HLS 支持以下功能:
- 直播(Live broadcasts)和點(diǎn)播(video on demand,簡(jiǎn)寫(xiě) VOD,即預(yù)錄內(nèi)容)。
- 具有不同比特率的多個(gè)備用流。
- 根據(jù)網(wǎng)絡(luò)變化對(duì)流進(jìn)行智能切換。
- 數(shù)據(jù)加密和用戶身份驗(yàn)證。
下圖顯示了 HTTP Live Stream 的組成部分:

Apple 提供了幾個(gè)支持 HTTP Live Streaming 的框架,包括AVKit、AVFoundation、WebKit。
1. 術(shù)語(yǔ)
在學(xué)習(xí) HLS 之前,需要先了解幾個(gè)相關(guān)概念。
1.1 MPEG
動(dòng)態(tài)圖像專家組(Moving Picture Experts Group,簡(jiǎn)稱 MPEG)原本是一個(gè)研究視頻、音頻編碼標(biāo)準(zhǔn)的組織,成立于1988年,致力于開(kāi)發(fā)視頻、音頻壓縮編碼技術(shù)?,F(xiàn)在我們所說(shuō)的MPEG泛指該小組制定的一系列視頻編碼標(biāo)準(zhǔn)正式審核程序。至今已制定了MPEG-1、MPEG-2、MPEG-3、MPEG-4、MPEG-7、MPEG-21、MPEG-H、MEPG-DASH等標(biāo)準(zhǔn)。
1.2 MPEG-2
MPEG-2 由 ITU 定義,也稱為 H.222 / H.262,是運(yùn)動(dòng)圖像和相關(guān)音頻信息的通用編碼標(biāo)準(zhǔn),它描述了視頻、音頻有損壓縮的組合方法,該方法允許使用當(dāng)前可用的存儲(chǔ)媒體和傳輸寬帶來(lái)存儲(chǔ)、傳輸電影。常用在數(shù)字衛(wèi)星電視、數(shù)字有線電視,以及 DVD 視頻光盤(pán)中。
MPEG-2 標(biāo)準(zhǔn)作為 ISO / IEC 12818 的一部分發(fā)布。MPEG-2 包含多個(gè)標(biāo)準(zhǔn),每個(gè)部分涵蓋整個(gè)規(guī)范的某個(gè)方面。例如,Part 1 系統(tǒng)描述音視頻同步和多路復(fù)用;Part 7 部分描述了有損數(shù)字音頻壓縮的音頻編碼標(biāo)準(zhǔn),稱為高級(jí)音頻編碼(Advanced Audio Coding,簡(jiǎn)稱 AAC)。AAC 被設(shè)計(jì)為 MP3 格式的后繼產(chǎn)品,在相同的比特率下,其聲音質(zhì)量通常比 MP3 更好。
1.3 MPEG-4
MPEG-4 定義了音視頻數(shù)字?jǐn)?shù)據(jù)的壓縮方法。于1998年推出,并指定了一組音頻、視頻編碼格式的標(biāo)準(zhǔn)和相關(guān)技術(shù)。MPEG-4 由 ISO/IEC MEPG 組織在 ISO / IEC 14496 標(biāo)準(zhǔn)發(fā)布。MPEG-4 標(biāo)準(zhǔn)壓縮的數(shù)據(jù)可用于網(wǎng)絡(luò)流媒體、CD 分發(fā)、電話、可視電話和廣播電視。
與 MPEG-2 類似,MPEG-4 也包含多個(gè)部分,每個(gè)部分涵蓋整個(gè)規(guī)范的某個(gè)方面。例如,Part 2 描述了視覺(jué)數(shù)據(jù)的壓縮格式;Part 10 描述了視頻信號(hào)的壓縮格式,在技術(shù)上與 ITU-T H.264 標(biāo)準(zhǔn)相同。
1.4 H.264
H.264 被稱為高級(jí)視頻編碼(Advanced Video Coding,簡(jiǎn)稱 AVC,也稱為 H.264、MPEG-4 Part 10、MPEG-4 AVC),是一種面向塊、基于運(yùn)動(dòng)補(bǔ)償?shù)囊曨l編碼標(biāo)準(zhǔn)。在2004年時(shí) H.264 已成為高精度視頻錄制、壓縮、發(fā)布最常用格式之一。第一版標(biāo)準(zhǔn)的最終草案于2003年5月完成。
H.264 / MPEG-4 AVC 項(xiàng)目的目的是為了創(chuàng)建一個(gè)更佳的視頻壓縮標(biāo)準(zhǔn),在更低的比特率下依然能提供良好視頻質(zhì)量,同時(shí)不會(huì)大幅度增加設(shè)計(jì)的復(fù)雜性。廣泛用于網(wǎng)絡(luò)流媒體、各種高清晰度電和衛(wèi)星。
1.5 H.265
H.265 被稱為高效率視頻編碼(High Efficiency Video Coding,簡(jiǎn)稱 HEVC),是 MPEG-H 規(guī)范的第二部分。H.265 是一種視頻壓縮標(biāo)準(zhǔn),被視為 H.264 標(biāo)準(zhǔn)的繼任者。與AVC相比,HEVC 在相同視頻質(zhì)量下數(shù)據(jù)可以壓縮 25% 至 50%,或相同比特率下可顯著提高視頻質(zhì)量。HEVC 支持高達(dá) 8192*4320 的分辨率,HEVC 的高保真 Main10 配置文件已經(jīng)集成到幾乎所有支持的硬件中。HEVC 正在與 IETF 的 AV1 編碼格式競(jìng)爭(zhēng)。
1.6 AC-3
AC-3 是音頻編碼(Audio Coding)的縮寫(xiě),是杜比數(shù)字音頻編碼器(Dolby Digital audio codec)的同義詞。除 Dolby TrueHD 外,音頻均為有損壓縮。通常,AC-3 幾乎只用于視頻,并且通常需要特殊許可的軟件或硬件才能進(jìn)行編碼、解碼。除非用于電影、DVD和藍(lán)光項(xiàng)目,否則沒(méi)有理由使用AC-3。
1.7 AAC
AAC 被稱為高級(jí)音頻編碼(Advanced Audio Coding),用于有損數(shù)字音頻壓縮的音頻編碼標(biāo)準(zhǔn),被設(shè)計(jì)為 MP3 格式的繼任者。在相同比特率下,AAC 通常比 MP3 可以獲得更好的聲音質(zhì)量。AAC 是 iOS、Android 等系統(tǒng)的默認(rèn)或標(biāo)準(zhǔn)音頻格式。
2. HLS 架構(gòu)
這一部分介紹 HLS 主要組件如何協(xié)同工作以傳遞流媒體。從概念上講,HTTP Live Streaming 包含三部分:服務(wù)器組件、分發(fā)組件和客戶端軟件。
在常見(jiàn)配置中,硬件編碼器接受輸入的音視頻,將其編碼為 HEVC 視頻、AC-3 音頻,輸出片段化(fragmented)MPEG-4 文件或 MPEG-2 傳輸流,分段器(segmenter)軟件將 stream 分割成系列短媒體文件,然后將短媒體文件放在 web 服務(wù)器上。segmenter 還會(huì)創(chuàng)建并維護(hù)一個(gè)包含媒體文件列表的索引文件(index file)。索引文件的 URL 在 web 服務(wù)器上發(fā)布,客戶端讀取索引文件,按順序讀取列出的媒體文件并播放,各片段間沒(méi)有任何暫?;蜷g隔。
2.1 服務(wù)器組件
服務(wù)器組件負(fù)責(zé)獲取媒體輸入流并對(duì)其進(jìn)行數(shù)字編碼,將其封裝成適合傳輸?shù)母袷?,并為分發(fā)做準(zhǔn)備。
對(duì)于直播,服務(wù)器需要媒體編碼器(可以是現(xiàn)有的硬件),以及一種將編碼的媒體分割成片段并保存為文件的方法,該方法可以是由 Apple 提供的 media stream segmented,也可以是第三方解決方案。
2.2 分發(fā)組件
分發(fā)系統(tǒng)是 web 服務(wù)器或 web 緩存系統(tǒng),通過(guò) HTTP 將媒體文件和索引文件傳輸?shù)娇蛻舳恕TTP Live Streaming 協(xié)議不需要對(duì)服務(wù)器模塊進(jìn)行任何自定義即可用于傳輸內(nèi)容,且 web 服務(wù)器只需要很少的配置。要實(shí)際使用 HTTP Live Streaming,需要將 HTML 頁(yè)面或 app 作為接收器,還需要使用 web 服務(wù)器,以及將實(shí)時(shí)流編碼為 HEVC 或 H.264視頻、 ACC 或 AC-3 音頻的分段 MPEG-4 媒體文件。
2.3 客戶端軟件
客戶端軟件負(fù)責(zé)確定所請(qǐng)求媒體資源類型、下載所需資源、重新組合資源,最后將媒體連續(xù)的呈現(xiàn)給用戶。目前,Windows 10、macOS 10.6+、iOS 3.0+、Android 4.1+ 等均原生支持 HLS,大部分瀏覽器也支持HLS。點(diǎn)擊這里可以查看各瀏覽器起始支持 HLS 版本。
客戶端軟件使用標(biāo)志流媒體位置的 URL 獲取 index file,index file 指定可用媒體文件位置、解密密鑰和可選流。選定流后,客戶端按順序下載可用媒體文件,每個(gè)文件包含一段連續(xù)的 stream。當(dāng)擁有足夠數(shù)據(jù)后,客戶端播放重組的 stream。
客戶端負(fù)責(zé)獲取解密密鑰、身份認(rèn)證,根據(jù)需要解密媒體文件。
這些過(guò)程會(huì)一直持續(xù),直到在 index file 遇到 EXT-X-ENDLIST tag。如果沒(méi)有 EXT-X-ENDLIST tag,則 index file 是直播的一部分。在直播期間,客戶端會(huì)定期拉去 index file 的新版本,并在新版本的 index file 中查找新的媒體文件和加密密鑰,并將這些 URL 添加到隊(duì)列。
3. 部署基礎(chǔ)的 HTTP Live Stream
部署 HTTP Live Stream 需要滿足以下三點(diǎn):
- HTML 網(wǎng)頁(yè)或客戶端作為接收者。
- Web 服務(wù)器或 CDN 作為主機(jī)。
- 一種將媒體文件或直播流編碼為包含 HEVC 或 H.264 視頻、 AAC 或 AC-3 音頻的 MPEG-4 片段文件的方式。盡管也可以將 MP3 音頻或 MPEG-2 用于傳輸 H.264 視頻,但通常不推薦使用這些格式。
3.1 創(chuàng)建 HLS 媒體接收器
分發(fā) HTTP Live Streaming 媒體最簡(jiǎn)單的方法是使用 M3U8 播放列表文件作為視頻源,創(chuàng)建包含 HTML5 <video> 標(biāo)簽的網(wǎng)頁(yè),對(duì)于不支持 HTML5 視頻元素的瀏覽器,或不支持 HTTP Live Streaming 的瀏覽器,可以在 <video> 和</video> 標(biāo)簽之間添加降級(jí)代碼。例如,可以使用 QuickTime 插件回退到漸進(jìn)式下載或 RTSP 流。以下示例顯示了常見(jiàn) HTML 網(wǎng)頁(yè)代碼:
<html>
<head>
<title>HTTP Live Streaming Example</title>
</head>
<body>
<video controls="controls" autoplay="" src="https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8" type="video/x-m4v">
</video>
</body
></html>
如果你在開(kāi)發(fā) iOS app,則可以使用AVKit框架直接播放:
func playHLSVideo() {
guard let videoURL = URL(string: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8") else {
return
}
let player = AVPlayer(url: videoURL )
let playerViewController = AVPlayerViewController()
playerViewController.player = player
present(playerViewController,
animated: true) {
playerViewController.player?.play()
}
}
3.2 配置服務(wù)器
普通的 web 服務(wù)器即可提供 HTTP Live Streaming。對(duì)服務(wù)器進(jìn)行常規(guī)配置,然后將要提供文件的 MIME 類型與文件擴(kuò)展名相關(guān)聯(lián)。下表顯示了 HTTP Live Streaming 的 MIME 類型:
| 擴(kuò)展名 | MIME 類型 |
|---|---|
| .m3u8 | vnd.apple.mpegURL |
| .ts | video/MP2T |
| .mp4 | video/mp4 |
如果 web 服務(wù)器需要遵守 MIME 類型約束,則可以提供以 .m3u 結(jié)尾 MIME 類型為 audio/mpegURL 的文件,以實(shí)現(xiàn)兼容性。
索引文件通常很長(zhǎng),經(jīng)常被重新下載,但由于他們是文本文件,因此可以非常高效地進(jìn)行壓縮。通過(guò)啟用 M3U8 索引文件的實(shí)時(shí) gzip 壓縮來(lái)減少服務(wù)器開(kāi)銷(xiāo)。HTTP Live Streaming 客戶端會(huì)自動(dòng)進(jìn)行解壓縮。
對(duì)于點(diǎn)播類型視頻,索引文件格式如下:
#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
http://example.com/movie1/fileSequenceA.ts
#EXTINF:10.0,
http://example.com/movie1/fileSequenceB.ts
#EXTINF:10.0,
http://example.com/movie1/fileSequenceC.ts
#EXTINF:9.0,
http://example.com/movie1/fileSequenceD.ts
#EXT-X-ENDLIST
各標(biāo)記用途如下:
EXTM3U:表示此播放列表是擴(kuò)展為 M3U 的文件列表。通過(guò)將第一行標(biāo)記改為 EXTM3U,可以將這種類型的文件與基本的 M3U 文件區(qū)分開(kāi)。所有 HLS 播放列表都必須以此標(biāo)簽開(kāi)頭。
EXT-X-PLAYLIST-TYPE:提供使用于整個(gè)播放列表的文件是否可變信息。此標(biāo)簽內(nèi)容為 EVENT 或 VOD。如果標(biāo)簽為 EVENT,則服務(wù)器不能改變、刪除索引文件的任何部分,但可以向尾部拼接。如果標(biāo)記為 VOD,則播放列表不可更改。
EXT-X-TARGETDURATION:指定媒體文件最大時(shí)長(zhǎng)。
EXT-X-VERSION:表示播放列表文件的兼容版本。播放列表媒體和服務(wù)器必須符合該版本協(xié)議的 IETF Internet-Draft 最新規(guī)定。
EXT-X-MEDIA-SEQUENCE:要播放的第一個(gè)媒體文件序列號(hào)。播放列表中的每個(gè)媒體文件 URL 都有一個(gè)唯一的整數(shù)序列號(hào),URL 的序列號(hào)是其前面的 URL 序列號(hào)加一,序列號(hào)與文件名無(wú)關(guān)。
EXTINF:記錄標(biāo)記,描述緊隨其后的 URL 所標(biāo)識(shí)媒體文件。每個(gè)媒體文件 URL 之前都必須有一個(gè) EXTINF 標(biāo)記。該標(biāo)記包含一個(gè) duration 屬性。duration 屬性是一個(gè)整數(shù)或浮點(diǎn)數(shù),指定媒體段的持續(xù)時(shí)間(以秒為單位),該值必須小于等于目標(biāo)持續(xù)時(shí)間。
始終使用浮點(diǎn) EXTINF 時(shí)長(zhǎng)(協(xié)議版本 3 中增加的),這將使客戶端在流中搜素時(shí)減少出現(xiàn)錯(cuò)誤。
EXT-X-ENDLIST:標(biāo)記媒體文件結(jié)束,不會(huì)再添加新的媒體文件到播放列表。
上面的 VOD 播放列表使用完整路徑描述媒體文件。盡管可以使用絕對(duì)路徑,但更推薦使用相對(duì)路徑。相對(duì)路徑是相對(duì)于播放列表文件的位置,使用絕對(duì)路徑會(huì)導(dǎo)致更多文本,且相對(duì)路徑比絕對(duì)路徑更可移植。下面是使用相對(duì)路徑的同一播放列表:
#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
fileSequenceA.ts
#EXTINF:10.0,
fileSequenceB.ts
#EXTINF:10.0,
fileSequenceC.ts
#EXTINF:9.0,
fileSequenceD.ts
#EXT-X-ENDLIST
直播和 event session 播放列表會(huì)有所不同,具體可以查看:Live Playlist (Sliding Window) Construction 和 Event Playlist Construction。
對(duì)于點(diǎn)播來(lái)說(shuō),整個(gè)媒體文件已經(jīng)存在。因此,索引文件是靜態(tài)的,只會(huì)被下載一次。對(duì)于直播來(lái)說(shuō),索引文件不斷更新,當(dāng)新媒體資源可用時(shí),會(huì)替換掉原來(lái)媒體資源。對(duì)于 event session 來(lái)說(shuō),新媒體文件可用時(shí)會(huì)拼接到索引文件結(jié)尾,與點(diǎn)播不同的是,不能移除索引文件任何內(nèi)容,只能向文件尾部拼接新的媒體片段,event session 允許用戶跳轉(zhuǎn)到已經(jīng)播放過(guò)片段任一時(shí)刻,即等效于點(diǎn)播+直播,常用于演唱會(huì)、運(yùn)動(dòng)會(huì)。
3.3 驗(yàn)證流
Apple 提供的 HTTP Live Streaming Tools 包含 Media Stream Segmenter、Media File Segmenter、Media Subtitle Segmenter、Variant Playlist Creator、Media Stream Validator、 HLS Report、ID3 Tag Generator 幾種工具。
Media Stream Validator 工具模擬 HTTP Live Streaming 會(huì)話,并驗(yàn)證索引文件和媒體片段是否符合 HTTP Live Streaming 規(guī)范。其會(huì)執(zhí)行多次檢查以確保流傳輸可靠,如果發(fā)現(xiàn)錯(cuò)誤、問(wèn)題,會(huì)在診斷報(bào)告中列出。在提供流服務(wù)前,請(qǐng)始終運(yùn)行驗(yàn)證程序。
mediastreamvalidator 命令如下:
$ mediastreamvalidator https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8
上述命令執(zhí)行完畢后,會(huì)產(chǎn)生一個(gè) validation_data.json 的診斷報(bào)告,但其內(nèi)容并不方便閱讀,可以使用下面的 python script 將其轉(zhuǎn)換為 html 格式:
$ hlsreport.py validation_data.json
生成的 validation_data.html 如下圖所示:

mediastreamvalidator 命令即可以驗(yàn)證 HTTP URLs 的資源,也可以驗(yàn)證本地資源。
使用 mediastreamvalidator 命令時(shí)如需幫助,輸入
mediastreamvalidator -h命令即可查看文檔。
此前,HLS 缺點(diǎn)一直是高延遲。但 Apple 在 WWDC 2019 發(fā)布了新的解決方案,可以將延遲從8秒降低到1至2秒。具體可以查看Introducing Low-Latency HLS。
參考資料:
- HTTP Live Streaming
- Validating HTTP Live Streams
- How is AAC better than AC3?
- What is the difference between AAC and AC3 in quality? How can it be determined?
本文地址:https://github.com/pro648/tips/wiki/HTTP-Live-Streaming-詳解
歡迎更多指正:https://github.com/pro648/tips/wiki