1286 words
6 minutes
Hello World (Streaming ver.)

Preface#

前陣子筆者在工作上的事情比較多,有一陣子沒更新了。這次想來聊聊【串流】這件事。

接觸程式開發以來,很少聽到串流這塊領域,感覺它是一塊特有的冷門區域,進入門檻有點高度。

儘管串流在我們的生活中無所不在,不論是 Netflix、YouTube 等影音媒體,你所看到的畫質、播放速度,每個都是串流處理的事情。

很幸運在這份工作中接觸到這塊領域,串流分為許多環節,不過簡單來說可以是 推流端 -> Media Server -> 拉流端。而其中使用的協定又分很多種,例如推流 RTSP、RTMP 等; 拉流 WebRTC、HLS、FLV 等,Media Server 也有 MediaMTX, SRS, Ant Media Server。 而負責推流的工具例如 FFmpeg, GStreamer… (聽起來很多吧哈哈,真的是塊坑,但我很開心能有所收穫)

那所以今天想來簡單講一下串流每個環節處理的事情,還有它的專有名詞,但由於篇幅長度,細節就暫時不贅述 (給未來的自己挖坑)。

推流端#

編碼標準 (Codec)#

原始影像 (raw frame) 非常大,舉例來說 (大小 1920 x 1080 @30 FPS 的影片),

  1. 單張圖片的 pixels = 1920 x 1080 = 2,073,600 pixels
  2. 每個 pixel 由 R、G、B 三通道組成 (有時候會是 RGBA,包括透明度通道),每個通道是 8 bits,所以每個 pixel 是 24 bits (or 32 bits)
  3. 這個影片每秒的數據量 = 像素數量 (pixels) x 單個像素大小 (bits) x 每秒幀數 (FPS) = 2073600 x 24 x 30 = 1,492,992,000 bits/second = 1.49 Gbps = 186.6 MB

如果不透過編碼技術壓縮,這在網路上傳輸非常困難。

那常見的編碼技術有幾種 :

Mux / Demux#

Mux 是 Multiplex 的縮寫,意思是多路傳輸,也就是把多個數據流 (影片、音頻素材) 封裝的過程。

編碼後的壓縮數據是 ES (Elementary Stream),ES 會被切成多個封包,並加上一個 PES Header 成為 PES (Packetized Elementary Stream),PTS (Presentation Time Stamp) 跟 DTS (Decoding Time Stamp) 就是在這出現的。

接下來 Muxer 會將不同 PID (Packet Identifier) 的影像 PES 與音訊 PES 按時間順序 interleaving,插入 PSI (Program Specific Information) (MPEG-TS 體系) 或 Metadata (MP4/MOV 體系),定義屬性與解碼參數。

Demuxer 會尋找封裝格式的同步字節 (如 TS 的 0x47、MP4 的 Box Header),然後讀取 Header 來獲得編碼參數,並傳遞給解碼器。根據封包標記 (PID、Track ID) 將 PES 數據分發至對應的解碼管線,提取 PTS / DTS 作為渲染引擎的參考依據。

傳輸 (Streaming)#

在完成 Mux 封裝後,數據需要透過特定的應用層協議發送至 Media Server。

協議傳輸層特點
RTMPTCP適合一對多的單向廣播
RTSPUDP/TCP監控系統
SRTUDP跨國直播推流、網路環境不穩定
WebRTCUDP多對多的即時互動
RISTUDP多路徑的能力; RIST 可以同時發送數據到兩條不同電信商的網路,並在接收端去重,即使一條斷掉,畫面也不會閃爍。
HLSHTTP(TCP)大規模分發、CDN 緩存

速率控制 (Bitrate)#

Bitrate 決定了頻寬的佔用。

  • CBR (Constant Bitrate) : 強制每一秒的數據量保持固定。在畫面簡單時填充無效數據 (Padding),複雜時犧牲畫質。適用於網路頻寬受限的直播場景。

  • VBR (Variable Bitrate) : 根據畫面複雜度分配位元率。簡單畫面低位元率,複雜畫面高位元率。常見於 點播 VOD (Video On Demand) 或錄影存檔,旨在維持視覺品質的一致性。

GOP (Group of Pictures)#

GOP 是影音壓縮中時間預測的基礎單位。它由一個 I-Frame (關鍵幀) 開始,後面跟隨多個 P-Frame (預測幀) 與 B-Frame (雙向預測幀)。

P-Frame / B-Frame 必須依賴 I-Frame 才能解碼。也就是說拉流端進入直播間時,必須等到下一個 I-Frame 出現才能顯示畫面。因此 GOP Length 決定了隨機存取的接入點。

IDR Frame (Instantaneous Decoding Refresh) : 當 IDR Frame 出現時,解碼器會清空幀緩衝區 (DPB) 以防止錯誤累積。

FFmpeg、GStreamer#

這兩個工具扮演 : 數據採集 -> 解法 -> 封裝 -> 傳輸 的角色。

  • FFmpeg : CLI 工具

  • GStreamer : 開發框架 (是個大坑),基於 Plugin-based 的 Pipeline 架構

未來有機會可以多講講這裡。

Media Server#

Media Server開發語言連結
MediaMTXGoLink
SRSC++Link
Ant Media ServerJavaLink
Nginx-RTMPCLink
LiveKitGoLink

拉流端#

Protocol傳輸層撥放器支援度ProsCons
HLS (HTTP Live Streaming)HTTP(TCP)穿透力強、ABR (自適應畫質)延遲高,不適合互動
WebRTCUDP低延遲、雙向通訊伺服器成本高、大規模分發較難
HTTP-FLVTCP穿透力強、低延遲瀏覽器相容性正逐漸被淘汰
DASHHTTP(TCP)強化版的 HLS設定較為複雜
RTSPUDP/TCP低 (需專業撥放器)低延遲網頁端幾乎無法直接播放

穿透力是指順利通過防火牆 (Firewall) 與網路位址轉換 (NAT) 的能力,由於 WebRTC 走的是 UDP,所以需要透過 ICE / STUN / TURN 找到傳送路徑。

Hello World (Streaming ver.)
https://nu1lspaxe.github.io/posts/20260131/
Author
nu1lspaxe
Published at
2026-01-31