議與多檔畫質(zhì):RTMP / SRT / WHIP 與 Simulcast)
上一篇講完架構(gòu)這一篇把鏡頭拉到鏈路的最底層**推流協(xié)議選型和多檔畫質(zhì)**。這兩個(gè)話題經(jīng)常被分開(kāi)講但它們其實(shí)是同一件事的兩面協(xié)議決定了「丟包時(shí)怎么辦」編碼方式?jīng)Q定了「一次推流能出幾檔畫質(zhì)」而這兩者又共同決定了弱網(wǎng)下觀眾看到的是什么。我們先把三種主流推流協(xié)議的權(quán)衡機(jī)制講透再講清楚「多檔畫質(zhì)、服務(wù)端免轉(zhuǎn)碼」到底是怎么實(shí)現(xiàn)的。---## 一、先從「丟包怎么辦」看三種協(xié)議判斷一個(gè)協(xié)議適不適合互動(dòng)直播最有效的角度不是背結(jié)論而是看它在丟包時(shí)做什么選擇。### RTMP繼承 TCP 的可靠有序RTMP 通常建立在持久 TCP 連接上消息被切成 chunk 并在多個(gè) chunk stream 上復(fù)用控制命令和數(shù)據(jù)用 AMF 序列化音視頻消息承載對(duì)應(yīng)的編碼數(shù)據(jù)。RTMPS 是在 TLS 上承載 RTMP提供機(jī)密性和完整性但**不消除 TCP 的隊(duì)頭阻塞**。這套設(shè)計(jì)在它誕生的年代是合理的TCP 的可靠傳輸省去了協(xié)議自己處理丟包重傳的麻煩。但代價(jià)就是我們上一篇講過(guò)的隊(duì)頭阻塞——任何分節(jié)丟失后面已到達(dá)的數(shù)據(jù)都要排隊(duì)等它重傳。今天 RTMP 在生態(tài)里的位置已經(jīng)很單薄播放側(cè)因?yàn)闉g覽器不再原生支持 Flash 播放基本退場(chǎng)僅剩的價(jià)值是一些老舊推流工具只認(rèn)它。而即便是「推流入口」這層價(jià)值也在被 SRT 和 WHIP 取代。### SRT為弱網(wǎng)而生的現(xiàn)代化選擇SRT 建立在 UDP 之上面向不穩(wěn)定網(wǎng)絡(luò)中的低時(shí)延可靠傳輸。理解它要把三個(gè)機(jī)制分開(kāi)- **ARQ自動(dòng)重傳請(qǐng)求**接收端根據(jù)序列號(hào)發(fā)現(xiàn)缺包并發(fā)送 NAK發(fā)送端在數(shù)據(jù)仍有時(shí)效時(shí)重傳。它解決「怎么恢復(fù)丟包」。- **TSBPD基于時(shí)間的包交付**依據(jù)發(fā)送時(shí)間戳和協(xié)商的 latency 安排包何時(shí)交付吸收網(wǎng)絡(luò)抖動(dòng)、恢復(fù)發(fā)送時(shí)序。它解決「何時(shí)交付」。- **過(guò)期包丟棄**啟用并滿足條件時(shí)放棄已來(lái)不及按計(jì)劃交付的數(shù)據(jù)。它解決「何時(shí)停止補(bǔ)救」。latency 這個(gè)參數(shù)給重傳和抖動(dòng)吸收提供時(shí)間預(yù)算調(diào)大通常提高恢復(fù)機(jī)會(huì)、增加交付等待調(diào)小則相反。但它**不是整個(gè) SRT 會(huì)話的嚴(yán)格數(shù)學(xué)時(shí)延上界**——握手、網(wǎng)絡(luò)排隊(duì)、應(yīng)用緩沖、斷線重連都在它之外。這也解釋了為什么 SRT 入庫(kù)的端到端時(shí)延通常比 WHIP 高它是「用延遲換弱網(wǎng)魯棒性」的有意取舍不是實(shí)現(xiàn)缺陷。### WHIP把 WebRTC 標(biāo)準(zhǔn)化成推流協(xié)議WHIP 本質(zhì)上不是全新的傳輸協(xié)議而是給 WebRTC 補(bǔ)上了一套標(biāo)準(zhǔn)化的「推流簽約流程」用 HTTP 完成 SDP offer/answer 交換媒體仍走 WebRTC 原生棧- **ICE** 負(fù)責(zé)打通網(wǎng)絡(luò)路徑含 NAT 穿透的地址協(xié)商- **DTLS-SRTP** 負(fù)責(zé)媒體鏈路加密注意若媒體在邊緣終止 SRTP 后重新加密轉(zhuǎn)發(fā)它是逐段保護(hù)不等于端到端加密- **RTP** 承載媒體配合 **NACK**選擇性重傳和可選的 **FEC**前向糾錯(cuò)處理丟包擁塞控制動(dòng)態(tài)調(diào)整發(fā)送碼率。WHIP 沒(méi)有 SRT 的 TSBPDRTP 接收端通常按**包數(shù)或字節(jié)數(shù)**維護(hù)重排歷史。這里有個(gè)容易搞混的點(diǎn)**包緩存數(shù)量不等于時(shí)間窗口**——同樣 512 個(gè)包在不同碼率、包長(zhǎng)和幀率下覆蓋的時(shí)間完全不同不能由它直接推出播放等待時(shí)延。WHIP 已經(jīng)正式發(fā)布為 RFC 9725不再是草案。---## 二、三者橫向?qū)Ρ葇 維度 | RTMP | SRT | WHIP || --- | --- | --- | --- || 傳輸層 | TCP | UDP ARQ | UDP RTPNACK / FEC / 擁塞控制 || 丟包處理 | TCP 必須重傳并按序交付可能隊(duì)頭阻塞 | ARQ 恢復(fù)TSBPD 定時(shí)交付可丟棄過(guò)期包 | NACK/FEC 依協(xié)商與實(shí)現(xiàn)使用jitter buffer 和解碼截止策略決定是否等待 || 延遲邊界 | 無(wú)嚴(yán)格數(shù)學(xué)上界 | latency 是工程預(yù)算不是無(wú)條件端到端上界 | 動(dòng)態(tài)緩沖與擁塞控制無(wú)無(wú)條件數(shù)學(xué)上界 || 加密 | 本身無(wú)加密RTMPS 用 TLS | 可配置 AES payload 加密 | 強(qiáng)制 DTLS-SRTP 鏈路加密不自動(dòng)等于 E2EE || 瀏覽器原生支持 | 已不支持 | 不支持 | 原生支持 || 典型定位 | 歷史遺留正在退出 | 弱網(wǎng)上行的現(xiàn)代選擇 | 主流實(shí)時(shí)推流/播放協(xié)議 |結(jié)論不是「誰(shuí)打敗誰(shuí)」而是**它們沒(méi)有脫離實(shí)現(xiàn)與網(wǎng)絡(luò)條件的數(shù)學(xué)延遲上界。**「TCP 不好、UDP 好」這種粗線條判斷會(huì)漏掉真正的工程重點(diǎn)——丟包時(shí)的取舍策略。---## 三、工程上怎么選統(tǒng)一信號(hào)差異化處理一個(gè)務(wù)實(shí)的做法是讓 WHIP 和 SRT **共存**服務(wù)不同場(chǎng)景- 網(wǎng)絡(luò)干凈、追求最低延遲時(shí)優(yōu)先 **WHIP**- 上行不穩(wěn)定、需要更強(qiáng)魯棒性時(shí)用 **SRT**用一點(diǎn)延遲換可靠性。兩者的原生統(tǒng)計(jì)口徑并不等價(jià)SRT 有 loss / retrans / drop / too-late 等RTP 側(cè)是序列號(hào)缺口 / NACK / RTX / FEC所以不能把兩邊的計(jì)數(shù)器直接套進(jìn)同一個(gè)公式。正確做法是**在接收端按統(tǒng)一采樣窗口、原包身份、恢復(fù)結(jié)果和播放 deadline 派生產(chǎn)品指標(biāo)再驅(qū)動(dòng)同一套降級(jí)決策。**降級(jí)動(dòng)作分兩步代價(jià)從低到高1. **先降編碼碼率**實(shí)時(shí)生效不中斷推流2. **碼率降到底仍不達(dá)標(biāo)才降分辨率**砍同播層數(shù)需要重啟推流有短暫中斷。背后的邏輯很直接調(diào)碼率零代價(jià)可以頻繁觸發(fā)調(diào)層數(shù)有中斷代價(jià)只有在「壓到底都不夠」時(shí)才動(dòng)用。同樣重要的是**恢復(fù)要慢、要穩(wěn)**——質(zhì)量指標(biāo)回落到恢復(fù)區(qū)間并持續(xù)觀察一段時(shí)間后才逐級(jí)恢復(fù)避免「加了又砍、砍了又加」的震蕩。 采樣窗口、降級(jí)閾值、恢復(fù)閾值、冷卻時(shí)間都是需要按協(xié)議、方向、內(nèi)容檔位和終端能力**配置并由真實(shí)網(wǎng)絡(luò)數(shù)據(jù)校準(zhǔn)的產(chǎn)品參數(shù)**不是協(xié)議常數(shù)。任何把某組實(shí)驗(yàn)值講成「通用閾值」的說(shuō)法都要警惕。---## 四、多檔畫質(zhì)的兩種做法服務(wù)端轉(zhuǎn)碼 vs Simulcast想要「1080P / 720P / 360P 同播」有兩條路。**傳統(tǒng)做法服務(wù)端轉(zhuǎn)碼。** 服務(wù)端先把收到的流完整解碼成原始畫面再按每個(gè)目標(biāo)檔位重新編碼一遍。解碼 多次重新編碼是相當(dāng)重的計(jì)算負(fù)擔(dān)而且天然帶來(lái)額外處理延遲費(fèi)用也按輸出檔位和時(shí)長(zhǎng)單獨(dú)計(jì)。**Simulcast推流端一次出多檔。** 關(guān)鍵要理解一句話**Simulcast 不是「一份編碼、服務(wù)端裁剪出多檔」而是發(fā)送端同時(shí)產(chǎn)生多份可獨(dú)立解碼的編碼。** 比如一路 1080P 輸入開(kāi) 3 層 Simulcast就產(chǎn)生 1080P、720P、360P 三份獨(dú)立編碼分別以 RTP 發(fā)送推流端編碼器│├── 主編碼器1080P──? RTP 流RID high├── 縮放層編碼器720P──? RTP 流RID mid└── 縮放層編碼器360P──? RTP 流RID low三條流各自獨(dú)立、完整可解碼服務(wù)端按 RID 識(shí)別并轉(zhuǎn)發(fā)對(duì)應(yīng)層服務(wù)端收到每一層時(shí)它已經(jīng)是可直接轉(zhuǎn)發(fā)給觀眾的完整畫面**不需要解碼、不需要重新編碼只做字節(jié)轉(zhuǎn)發(fā)**。這就是「網(wǎng)絡(luò)側(cè)不用轉(zhuǎn)碼」的技術(shù)根因轉(zhuǎn)碼的工作量沒(méi)有消失只是被挪到了推流端的編碼器上——**用推流端的編碼算力換服務(wù)端的轉(zhuǎn)碼算力。**---## 五、為什么是 Simulcast不是 SVC懂一點(diǎn)編解碼的人會(huì)問(wèn)可分層編碼SVC不是更省帶寬嗎- **SVC 的思路**編碼輸出包含基礎(chǔ)層和一個(gè)或多個(gè)增強(qiáng)層層之間有依賴關(guān)系轉(zhuǎn)發(fā)端可按依賴結(jié)構(gòu)選擇轉(zhuǎn)發(fā)子集通常比多份完全獨(dú)立編碼更省總碼率。- **代價(jià)是復(fù)雜度和兼容性**轉(zhuǎn)發(fā)端必須正確處理層標(biāo)識(shí)、依賴關(guān)系和切換點(diǎn)接收端也必須支持對(duì)應(yīng)的 codec/profile/scalability mode。H264/HEVC 是否可用 SVC取決于瀏覽器、系統(tǒng)解碼器、協(xié)商和產(chǎn)品實(shí)現(xiàn)。所以選 Simulcast 還是 SVC**本質(zhì)是當(dāng)前終端矩陣下的兼容性取舍不是哪個(gè)標(biāo)準(zhǔn)更先進(jìn)**。選型時(shí)應(yīng)以目標(biāo)終端矩陣和互操作測(cè)試為準(zhǔn)而不是聽(tīng)某一家產(chǎn)品的現(xiàn)狀。---## 六、無(wú)縫切換切換點(diǎn)必須「可獨(dú)立解碼」最后一個(gè)關(guān)鍵問(wèn)題觀眾從 720P 切到 360P 時(shí)怎么切才不花屏答案和點(diǎn)播的碼率切換是**同一條原理**獨(dú)立編碼的流只能從一個(gè)可解碼的接入點(diǎn)開(kāi)始接入解碼器不能從中間任意一點(diǎn)切入。點(diǎn)播里表現(xiàn)為「只在分片邊界換檔」直播的 Simulcast 分層切換里表現(xiàn)為「等待目標(biāo)層的隨機(jī)接入點(diǎn)常見(jiàn)是請(qǐng)求關(guān)鍵幀」觀眾當(dāng)前播放 mid 檔720P│▼檢測(cè)到丟包率上升決定降檔到 low360P│▼請(qǐng)求或等待 low 層的可用關(guān)鍵幀│▼從該關(guān)鍵幀開(kāi)始改為轉(zhuǎn)發(fā) low 層數(shù)據(jù)要注意**關(guān)鍵幀邊界本身不等于無(wú)條件無(wú)縫**。是否無(wú)感取決于關(guān)鍵幀等待時(shí)間、緩沖狀態(tài)和 RTP 連續(xù)性處理。關(guān)鍵幀請(qǐng)求會(huì)消耗碼率、存在等待時(shí)間所以正確切換能避免引用鏈損壞和花屏但不保證零等待、零卡頓。順便借這個(gè)原理聊聊向頭部點(diǎn)播平臺(tái)學(xué)什么它們的 ABR 決策不只看瞬時(shí)網(wǎng)速還看**播放緩沖區(qū)還剩多少內(nèi)容**切換點(diǎn)嚴(yán)格對(duì)齊編碼階梯按內(nèi)容定制。這些思路可以借鑒但**點(diǎn)播和直播的約束差一個(gè)數(shù)量級(jí)**——點(diǎn)播可以攢大緩沖、可以離線反復(fù)試驗(yàn)最優(yōu)編碼參數(shù)低延遲直播緩沖預(yù)算更小、編碼必須實(shí)時(shí)。照抄參數(shù)會(huì)出問(wèn)題能真正復(fù)用的是決策哲學(xué)**以觀感為中心而不是以某個(gè)單一技術(shù)指標(biāo)為中心。**---## 小結(jié)- **三種協(xié)議看丟包策略**RTMP 繼承 TCP 的隊(duì)頭阻塞SRT 用 ARQ TSBPD 過(guò)期丟棄換弱網(wǎng)魯棒性WHIP 復(fù)用 WebRTC/RTP 的反饋、擁塞控制和動(dòng)態(tài)緩沖。- **共存優(yōu)于二選一**WHIP 追低延遲SRT 保弱網(wǎng)上行兩者統(tǒng)計(jì)口徑不同要在接收端派生統(tǒng)一的產(chǎn)品指標(biāo)再驅(qū)動(dòng)降級(jí)。- **降級(jí)有代價(jià)梯度**先壓碼率不中斷再砍分辨率短暫中斷恢復(fù)要慢要穩(wěn)。- **多檔畫質(zhì)靠 Simulcast**發(fā)送端出多份獨(dú)立編碼服務(wù)端只轉(zhuǎn)發(fā)不轉(zhuǎn)碼用推流端算力換服務(wù)端算力。- **無(wú)縫切換的通用原理**在可獨(dú)立解碼、時(shí)間線連續(xù)的位置切換關(guān)鍵幀是常用但非唯一的手段。下一篇我們講一個(gè)同樣容易被忽略、但直接關(guān)系業(yè)務(wù)安全的話題**推拉流的簽名、Token 與防盜鏈**。---**系列導(dǎo)航**- 上一篇[02 · 自建 CDN 架構(gòu)總覽](02-自建CDN架構(gòu)總覽-控制面與媒體面分離.md)- 下一篇[04 · 推拉流安全簽名、Token 與防盜鏈](04-推拉流安全-簽名Token與防盜鏈.md)- 返回[系列導(dǎo)覽](README.md)