從「能播」到「不會掛」之間隔著一整套工程。單路推流一定會斷,單一轉碼節點一定會故障,而直播沒有重來的機會——一場賽事中斷十秒就是永久的損失。這一篇處理規模化之後才會遇到的問題:備援、同步、可觀測性,以及把這一切換算成錢。
📖 學
一、備援的四個層次
第一哩路備援(推流端)
- 雙網路 bonding:把多條網路(4G + 5G + 固網)綁成一條邏輯通道。SRT 自 1.5 版起支援 connection bonding,提供 broadcast(全部複製,最耗頻寬最可靠)、backup(主備切換)、balancing(分流)三種模式。RIST 也有對應能力。
- 雙編碼器:兩台機器編同一個訊號,各自推流,下游擇一。
- 判準:移動場景(SNG 車、戶外)bonding 幾乎是必需;固定場地雙線路即可。
源站備援
同一條流推到兩個接收端點(不同區域),下游自動切換。關鍵是兩路要能無縫切換,這要求時間戳對齊——否則切換時會跳秒或重複。
轉碼備援
轉碼節點是有狀態的(它維持著編碼器狀態與 GOP 結構),不能像無狀態服務那樣隨意重啟。常見作法是 active-active(兩套同時跑、下游選一)而非 active-standby,因為冷啟動一個編碼器要數秒。
分發備援
多 CDN(multi-CDN)策略:同一內容掛在兩家以上 CDN,用 DNS 或客戶端邏輯做切換。它同時解決可用性與議價能力。代價是打包/金鑰/鑑權都要在多家之間保持一致,複雜度明顯上升。
二、同步問題
直播有四種「同步」,彼此獨立:
唇音同步(A/V sync)——音訊與影像的相對時間。音訊處理鏈(壓縮、降噪、等化)會引入延遲而影像鏈不會,必須量測後補償。容忍範圍:影像領先音訊約 +45 ms 到落後約 −125 ms 之間多數人察覺不到(這是廣電領域的經驗區間,人對「聲音早於畫面」比「晚於畫面」敏感得多)。
多機位同步——多個攝影機之間。靠共用時間碼(genlock/PTP/SMPTE timecode)解決,不能靠事後對齊。
多觀眾同步——不同觀眾看到同一時刻的畫面。這在 ABR + CDN 架構下天生做不到精確,不同人的 buffer 不同、階梯不同、路徑不同,差幾秒是常態。需要同步的場景(例如多人一起看、競猜)必須在應用層用伺服器時間對齊,而不是假設視訊時鐘一致。
視訊時鐘 vs 業務時鐘——這是最容易出事的一個。絕對不能用視訊的播放進度當成業務的時間依據。 下注截止、答題時限、拍賣結束,都必須由權威伺服器時間決定;如果某個觀眾的視訊延遲了三秒,正確行為是提示或暫停他的互動,而不是給他多三秒。使用者提供的方案文件把這一條明確寫進規範(「游戏结果及下注截止时间由权威游戏服务决定,不以视频时钟或客户端缓冲作为依据」),見 案例拆解。
三、字幕
| 方式 | 機制 | 優缺點 |
|---|---|---|
| 燒錄(burned-in / open caption) | 直接畫進影像 | 一定顯示、不可關閉、不可選語言、佔用碼率 |
| WebVTT(HLS/DASH 側載) | 獨立軌道,播放器渲染 | 可開關、可多語、可搜尋;需播放器支援 |
| CEA-608/708(嵌入式) | 嵌在視訊位元流的 SEI | 廣電相容性好;在純網路鏈路中容易在轉碼時被丟掉 |
直播字幕的難點是即時性。人工聽打有數秒延遲,ASR(語音辨識)更快但錯誤率高。實務上常見的是 ASR + 人工校正的混合,並且字幕軌的延遲必須與視訊對齊——否則字幕會提前或落後於畫面。
轉碼會丟掉嵌入式字幕是一個很常見的坑:CEA-608 藏在 SEI 裡,多數轉碼器預設不保留。要嘛明確設定保留,要嘛改用側載 WebVTT。
四、監控:該看什麼
分成三層,缺一層就會有盲區:
管線健康(我的系統有沒有在動)
- 推流連線狀態、實際入口碼率(跟設定值比對)
- 轉碼節點的輸入/輸出幀率(掉幀是最早的故障訊號)
- 分片產出速率(應該穩定等於 1/分片長度)
- 清單更新時間戳(卡住代表打包掛了)
分發健康(內容有沒有送出去)
- CDN 快取命中率、回源請求數
- 各區域的 HTTP 狀態碼分布(4xx 突增通常是鑑權問題,5xx 是源站問題)
- 邊緣延遲
使用者體驗(觀眾實際看到什麼)
- QoE 指標:首幀、卡頓率、碼率分布、失敗率
- 按地區/ISP/裝置分群——總體數字會掩蓋局部災難,某個 ISP 全掛在總體上可能只是 2% 的波動
除錯的順序:從使用者症狀往回推,而不是從管線往前查。先確認是「所有人都有問題」還是「某一群人有問題」——前者查管線,後者查分發與特定環境,這個分岔能省掉大半時間。
五、成本模型
直播的成本有五塊,比例依規模差異很大:
| 項目 | 計價方式 | 規模相依 |
|---|---|---|
| 出流頻寬 | 每 GB 或每 Mbps 峰值 | 與觀眾數線性,通常是最大項 |
| 轉碼計算 | 每小時每路 | 與流數相關,與觀眾數無關 |
| 請求數 | 每百萬次 | 低延遲時會變成顯著項 |
| 儲存 | 每 GB 月 | 只有要錄影/回看才顯著 |
| 媒體伺服器(WebRTC) | 每併發路數 | 與觀眾數線性且昂貴 |
一個基本的出流估算:
出流頻寬 = 平均碼率 × 同時觀看人數
10 萬人 × 1.5 Mbps = 150,000 Mbps = 150 Gbps
每人每小時用量 = 1.5 Mbps × 3600 s ÷ 8 = 675 MB ≈ 0.675 GB
10 萬人看一小時 = 67.5 TB
這個算式沒有包含音訊、協定開銷、重傳、ABR 階梯切換造成的浪費、TURN 中繼與回源,實際採購必須在此之上留餘量。這組數字正是使用者提供的方案文件裡的容量模型基準,詳見 案例拆解。
成本優化的優先序:
- 降低平均碼率(更好的 codec、per-title、更合理的階梯)——直接乘在最大項上。
- 提高快取命中率——回源流量是重複的錢。
- 多 CDN 議價——規模夠大時單價可以談。
- 減少轉碼階數——但要權衡弱網觀眾的體驗。
- 把 WebRTC 限制在真正需要的人身上——這是混合架構最大的經濟理由。
最後一項值得強調:如果十萬觀眾裡只有兩千人需要次秒級互動,把兩千人放 WebRTC、九萬八千人放 LL-HLS,成本可能只有全部走 WebRTC 的零頭。架構決定成本的幅度遠大於參數調優。
🧠 記
轉碼節點是有狀態的,備援要 active-active 而非冷備。
視訊時鐘絕不能當業務時鐘,下注/答題/拍賣的截止必須由權威伺服器決定。
轉碼預設會丟掉嵌入式字幕,要嘛明確保留要嘛改側載。
監控要按地區/ISP/裝置分群,總體數字會掩蓋局部災難。
出流頻寬通常是最大成本項,且與觀眾數線性;轉碼成本只與流數相關。
架構決定成本的幅度遠大於參數調優——混合架構把 WebRTC 限制在需要的人身上是最大的一筆節省。
✍️ 實踐
做一張自己服務的成本結構表,30 分鐘:
- 填入:平均碼率、峰值同時觀看、平均觀看時長、每日場次、ABR 階數。
- 算出每月出流 GB、轉碼小時數、請求總數。
- 對照你的 CDN 與雲端報價,算出三項各佔多少百分比。
- 然後做一次敏感度分析:平均碼率降 20%,總成本降多少?階梯從 5 階減到 4 階,總成本降多少?
幾乎所有人做完這張表都會發現同一件事:碼率的槓桿遠大於其他所有項目的總和,而那正好是前面幾篇在處理的東西。
🔗 延伸學習
- Appear — SRT Stream Density and Transport for Broadcast Contribution——從廣電硬體廠商視角談 SRT 的密度與備援,比純軟體視角多了實務約束。
- hls.js — GitHub——播放端監控埋點的實作參考。