HLS 串流完整指南

HLS 是當今網路影音傳輸的骨幹,從 YouTube 到各大電視台直播都靠它運作。這頁從協定設計的「為什麼」出發,帶你看懂播放清單的每個標籤,並實際示範如何用 FFmpeg 建立自己的 HLS 服務。如果你只是想播一個 m3u8,可先看播放器指南。

操作步驟

  1. 準備來源影片

    準備一個 MP4 或其他格式的影片檔。若要從現有串流轉換,來源也可以是 m3u8 網址。

  2. 用 FFmpeg 切割

    執行 ffmpeg -i input.mp4 -c copy -f hls -hls_time 10 -hls_playlist_type vod output.m3u8,會產生一個 m3u8 與多個 ts 片段。-hls_time 10 表示每段 10 秒。

  3. 架設網頁播放器

    把產生的檔案放到網頁伺服器,用 hls.js 或支援 HLS 的播放器載入 m3u8 網址即可。別忘了設定 CORS 標頭。

HLS 為什麼會被設計出來

HLS 由 Apple 在 2009 年提出,當時的串流技術(如 RTMP、RTSP)各有痛點:需要專用伺服器、難以穿透防火牆、擴展成本高。

HLS 的核心洞見很簡單:與其發明新的傳輸協定,不如用已經無所不在的 HTTP。具體做法是把影片切成小片段,每個片段都是一個普通檔案,用一般的 HTTP 請求下載。這樣一來:

  • 任何網頁伺服器都能提供服務,不需要串流軟體
  • 可以直接用 CDN 快取與加速,擴展成本大幅降低
  • 能穿透企業防火牆(看起來就像普通網頁請求)
  • 播放器可依網速選擇畫質,實現自適應位元率

這個設計如此成功,以至於十多年後的今天,HLS 仍是網路直播與隨選影片的主流選擇。

播放清單結構與標籤

M3U8 播放清單是純文字檔,每一行以 # 開頭的是標籤(指令),其餘是檔案路徑。以下是一個完整的 Media Playlist 範例:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key.bin"
#EXTINF:10.0,
segment-000.ts
#EXTINF:10.0,
segment-001.ts
#EXTINF:9.8,
segment-002.ts
#EXT-X-ENDLIST

常用標籤說明:

標籤作用
#EXTM3U固定開頭,表示這是 M3U 格式。
#EXT-X-VERSIONHLS 協定版本,影響可用的標籤。
#EXT-X-TARGETDURATION單一片段的最大秒數(取整數)。播放器據此決定緩衝策略。
#EXT-X-MEDIA-SEQUENCE第一個片段的序號。直播時會遞增,用於滑動視窗。
#EXT-X-KEY標示片段加密方式與金鑰位置。有這個標籤就代表內容受保護。
#EXTINF標示下一個片段的秒數,是唯一的必要標籤。
#EXT-X-ENDLIST表示播放清單已完整。有這個標籤是隨選影片,沒有則是直播。

想實際看看真實串流的結構?用串流檢測工具貼上網址,就能看到片段數量、目標長度與加密狀態。

Master 與 Media:兩層結構

HLS 採用兩層清單設計,這是實現「自適應位元率」的關鍵:

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=854x480
480p/index.m3u8

這是 Master Playlist,它不包含片段,而是指向不同畫質的 Media Playlist。播放器讀取後就知道有哪些畫質可選,並依網速切換。

清單類型內容
Master Playlist列出所有可選畫質,每項指向一個 Media Playlist。標籤為 #EXT-X-STREAM-INF。
Media Playlist單一畫質的片段清單,記載每個片段的位置與秒數。

當你貼上 Master 網址時,播放器會顯示畫質選單;貼上 Media 網址時則只播那個畫質。這也是判斷網址類型的方法。

實作:用 FFmpeg 建立 HLS 服務

最簡單的方式是用 FFmpeg 把現有影片轉成 HLS:

# 單一畫質(最簡單)
ffmpeg -i input.mp4 -c copy -f hls \
  -hls_time 10 -hls_playlist_type vod \
  output.m3u8

若要產生多畫質(Master Playlist),需要分別轉出各畫質再手動建立 Master:

# 1080p
ffmpeg -i input.mp4 -vf scale=1920:1080 -c:v libx264 \
  -b:v 5000k -c:a aac -b:a 128k -f hls \
  -hls_time 10 -hls_playlist_type vod 1080p/index.m3u8

# 720p
ffmpeg -i input.mp4 -vf scale=1280:720 -c:v libx264 \
  -b:v 2500k -c:a aac -b:a 128k -f hls \
  -hls_time 10 -hls_playlist_type vod 720p/index.m3u8

部署注意事項:

  • MIME 類型:.m3u8 要設為 application/vnd.apple.mpegurl,.ts 設為 video/mp2t。
  • CORS 標頭:若播放器與影片不同網域,必須設定 Access-Control-Allow-Origin。
  • 快取策略:VOD 的片段可長期快取,但 m3u8 要設短快取(直播則不可快取)。
  • HTTPS:若網頁是 HTTPS,串流也必須是 HTTPS,否則瀏覽器會阻擋(混合內容)。

更完整的 FFmpeg 參數與錯誤排除,請見 FFmpeg M3U8 指令集。

HLS 與其他串流技術比較

技術延遲特性與適用場景
HLS6-30 秒
(LL-HLS 約 2 秒)
相容性最佳,Apple 原生支援,可穿透防火牆,CDN 友善。直播與 VOD 皆適用。
MPEG-DASH與 HLS 相近開放標準,Android 生態較常見。與 HLS 原理相似,常與 HLS 並行提供。
WebRTC低於 1 秒超低延遲,適合視訊通話、互動直播。但架構複雜、CDN 成本高、不適合大規模單向播放。
RTMP2-5 秒舊技術,需要專用伺服器,無法穿透防火牆。現多用於「推流端」,再由伺服器轉成 HLS。

選擇原則:如果你的目標是「大量使用者、各種裝置都能看」,選 HLS;如果需要「即時互動、延遲低於 1 秒」,選 WebRTC。沒有最好的技術,只有最適合場景的技術。

常見問題

HLS 為什麼要用 HTTP?好處是什麼?
因為 HTTP 是網路上最普及的協定,幾乎所有伺服器、CDN、防火牆都支援。好處有三:一、不需要特殊的串流伺服器,一般網頁伺服器就能架設;二、可直接使用 CDN 加速與快取,成本低且擴展性極佳;三、能穿透企業防火牆與代理伺服器,因為它看起來就是普通的網頁請求。這是 HLS 能成為主流的最大原因。
HLS 的片段為什麼是 .ts 格式?
.ts 是 MPEG-TS(Transport Stream)格式,原本用於數位電視廣播。它被 HLS 採用的原因是設計上適合「串流傳輸」:每個片段都能獨立解碼,不依賴前後片段,且對封包遺失有較好的容錯。不過近年 HLS 也支援 fMP4(碎片化 MP4)片段,因為它與 DASH 相容且效率更好,新服務越來越多採用 fMP4。
HLS 的延遲可以降到多低?
傳統 HLS 的延遲通常是 6 到 30 秒,因為播放器需要緩衝數個片段。若需要更低延遲,Apple 提出了 LL-HLS(低延遲 HLS),透過縮短片段、部分片段傳輸(Partial Segments)與預載提示等機制,可將延遲降到 2 秒左右。若要做到 sub-second 延遲,則需改用 WebRTC 或 SRT 等技術。
我可以自己架設 HLS 服務嗎?
可以,而且比想像中簡單。最基本的方式是用 FFmpeg 把影片切成片段與 m3u8,放到任何網頁伺服器(Nginx、Apache 皆可)就能運作,因為 HLS 只需要「用 HTTP 提供檔案」。若要做直播,可用 FFmpeg 接收來源並即時產生片段,或用 Nginx 的 RTMP 模組轉 HLS。需要注意跨網域(CORS)設定,否則網頁播放器無法讀取。
HLS 跟 MPEG-DASH 該選哪個?
兩者原理相近,選擇取決於目標平台。若你的使用者有大量 Apple 裝置(iPhone、iPad、Mac、Apple TV),選 HLS,因為它原生支援、不需額外程式庫。若是純 Android 或需要遵循開放標準,DASH 較合適。實務上多數大型服務會同時提供兩者,讓播放器依裝置自動選擇,這也是 Netflix、YouTube 的做法。
HLS 支援哪些編碼格式?
HLS 本身只是一種「傳輸與封裝」協定,不限定編碼格式。實務上最常見的是 H.264(相容性最好)與 H.265/HEVC(壓縮效率高但相容性較差,多用於 4K)。音訊則以 AAC 為主流。近年 AV1 也開始被支援。選擇時要權衡壓縮效率與裝置支援度 —— 相容性永遠是第一考量。

測試你的 HLS 串流

貼上網址,立即檢查片段與加密狀態。

開啟檢測工具