WebRTC低延遲直播實戰(zhàn):基于SRS的Docker部署與播放測試)
之前做直播項目時業(yè)務(wù)方經(jīng)常提一個需求“畫面要低延遲最好控制在 1 秒以內(nèi)但我們的攝像頭和編碼器只支持 RTMP 輸出”。瀏覽器原生又不能直接播放 RTMPHTTP-FLV 延遲又不理想。后來在測試環(huán)境里用 SRS 把 RTMP 轉(zhuǎn)成 WebRTC才把問題徹底打通。本文就用一套最小可復(fù)現(xiàn)的 rtmp2webrtc 測試環(huán)境帶你從環(huán)境搭建、協(xié)議轉(zhuǎn)換、推流驗證到 WebRTC 播放完整跑一遍。文章會包含 Docker 部署、配置文件、ffmpeg 推流命令、網(wǎng)頁播放器代碼和常見排錯思路適合剛接觸流媒體轉(zhuǎn)換、或者已經(jīng)在做直播/監(jiān)控項目想降低播放延遲的開發(fā)者。1. 背景與核心概念1.1 為什么需要 RTMP 轉(zhuǎn) WebRTC在真實項目中RTMP 和 WebRTC 經(jīng)常是兩個獨立的技術(shù)棧但業(yè)務(wù)上卻要把它們串起來。RTMP 目前依然是很多攝像頭、編碼器、推流軟件的標(biāo)準(zhǔn)輸出協(xié)議。傳統(tǒng) OBS、硬件編碼器、監(jiān)控攝像頭幾乎都支持 RTMP 推流。但瀏覽器端對 RTMP 的支持已經(jīng)基本消失。以前用 Flash 播放 RTMP 已經(jīng)過時現(xiàn)代瀏覽器不可能直接解析 RTMP 流。如果要實現(xiàn)“攝像頭 RTMP 推流網(wǎng)頁端低延遲觀看”最直接的辦法是在服務(wù)器上搭建一個中間層把 RTMP 接收下來再轉(zhuǎn)換成瀏覽器能消費的流。這個中間層可以是 HTTP-FLV、HLS 或 WebRTC。HTTP-FLV 延遲雖然不錯但相比 WebRTC 還是不夠低HLS 延遲通常在 3 到 10 秒只適合點播或?qū)ρ舆t不敏感的場景。WebRTC 的優(yōu)勢在于基于 UDP 傳輸具備實時通信能力播放延遲通??梢钥刂圃?1 秒以內(nèi)。所以“RTMP 推流 WebRTC 播放”成了低延遲直播測試和落地的主流組合。1.2 RTMP 與 WebRTC 的核心差異搞清楚這兩個協(xié)議的差異對理解轉(zhuǎn)換原理很有幫助。RTMP 是基于 TCP 的實時消息傳輸協(xié)議。它把視頻、音頻、metadata 封裝成 FLV 標(biāo)簽通過長連接推送到服務(wù)器。TCP 保證了可靠性但會有一定的緩沖和排隊延遲。早期 RTMP 用于 Flash 播放器到現(xiàn)在依然是行業(yè)里最常見的推流協(xié)議。WebRTC 是一套瀏覽器實時通信標(biāo)準(zhǔn)主要使用 UDP 傳輸 RTP/RTCP 媒體數(shù)據(jù)。它通過 ICE 做連接協(xié)商用 SDP 交換媒體能力基于 SRTP 加密傳輸。瀏覽器原生支持 WebRTC所以不需要安裝插件或 Flash。下面用表格對比會更直觀對比項RTMPWebRTC傳輸層TCPUDP RTP/RTCP瀏覽器支持不支持原生支持典型角色推流端為主播放端/雙向通話延遲范圍2 到 5 秒0.2 到 1 秒加密可配默認(rèn) SRTP端口固定 1935動態(tài) RTP 端口/UDP簡單理解RTMP 在推流階段有優(yōu)勢WebRTC 在播放和雙向通信階段有優(yōu)勢。服務(wù)器需要做的就是接收 RTMP 流解出 FLV 封裝中的視頻幀和音頻幀再按 WebRTC/SDP 協(xié)商出來的能力重新封裝成 RTP 包發(fā)送給瀏覽器。1.3 一套完整的 rtmp2webrtc 測試環(huán)境包含什么一套可復(fù)用的 rtmp2webrtc 測試環(huán)境通常由以下幾個部分組成流媒體服務(wù)器承擔(dān) RTMP 接收和 WebRTC 轉(zhuǎn)換任務(wù)例如 SRS。推流端使用 ffmpeg 拉取本地視頻文件或者直接生成測試畫面把 RTMP 流推到服務(wù)器。播放端一個普通的 Chrome/Edge 瀏覽器頁面使用 WebRTC API 從服務(wù)器拉流。網(wǎng)絡(luò)環(huán)境服務(wù)器需要開放 RTMP 的 TCP 端口、HTTP API 端口以及 WebRTC 媒體傳輸?shù)?UDP 端口。本文選擇 SRS 作為測試服務(wù)器因為它開源、部署簡單并且原生支持 RTMP 與 WebRTC 的雙向轉(zhuǎn)換。你可能還聽說過 Janus、mediacodec、GStreamer 等方案但 SRS 在中文社區(qū)資料比較豐富單機測試也最省事。2. 環(huán)境準(zhǔn)備與版本說明2.1 操作系統(tǒng)與硬件要求測試環(huán)境不要求高性能服務(wù)器。本文的示例在 Linux 系統(tǒng)上演示如果你用的是云主機、虛擬機或本地 Linux 開發(fā)機都可以。常見環(huán)境如下操作系統(tǒng)Ubuntu 20.04 / 22.04CentOS 7 及以上或者兼容性較好的 Linux 發(fā)行版。CPU/內(nèi)存2 核 4G 起步單路流媒體轉(zhuǎn)換測試完全夠用。瀏覽器Chrome 或 Edge 最新版本。如果你的測試機是國產(chǎn)化平臺例如麒麟操作系統(tǒng)搭配飛騰/鯤鵬或兆芯等架構(gòu)部署思路也類似。優(yōu)先選擇支持對應(yīng) CPU 架構(gòu)的 Docker 鏡像如果沒有現(xiàn)成鏡像可以改用源碼編譯方式。SRS 對 ARM64 的編譯還算友好但具體還要按實際系統(tǒng)環(huán)境調(diào)整這里重點演示配置思路而不是特定發(fā)行版的命令。2.2 軟件工具清單為了跑通測試環(huán)境我們需要的工具如下工具用途說明Docker / Docker Compose啟動 SRS 服務(wù)快速、環(huán)境隔離ffmpeg模擬 RTMP 推流可使用虛擬視頻源SRS 5流媒體服務(wù)器接收 RTMP 并轉(zhuǎn) WebRTCChrome 瀏覽器播放 WebRTC 流支持 WebRTC API版本說明SRS 5 開始完整支持 WebRTC 播放所以本文以 SRS 5 為例。SRS 6 也保留了類似配置細節(jié)上你可以參考官方文檔做微調(diào)。不要盲目用 latest 鏡像固定具體大版本更利于復(fù)現(xiàn)環(huán)境。如果你不希望安裝 Docker也可以直接從源碼編譯 SRS但需要額外安裝 Go、gcc、cmake 等依賴。本文優(yōu)先使用 Docker 方案因為它可以把注意力集中在流媒體本身而不是編譯環(huán)境上。2.3 測試目錄規(guī)劃建議在測試機上單獨建立一個目錄方便清理和備份。/data/rtmp2webrtc/ ├── conf/ │ └── srs.conf ├── pages/ │ └── player.html └── logs/conf 目錄放 SRS 自定義配置文件。pages 目錄放 WebRTC 播放頁面。logs 目錄留作日志備份。實際使用時按你的習(xí)慣調(diào)整目錄位置。下面所有命令都默認(rèn)在 /data/rtmp2webrtc 下執(zhí)行。3. 核心原理拆解3.1 SRS 在測試環(huán)境中的雙重角色SRSSimple Realtime Server在本文測試環(huán)境中承擔(dān)兩個角色RTMP 流媒體服務(wù)器監(jiān)聽 1935 端口接收 ffmpeg 或其他推流端發(fā)來的 RTMP 流。WebRTC 網(wǎng)關(guān)通過 HTTP 信令接口與播放端交換 SDP通過 UDP 端口傳輸 RTP 媒體數(shù)據(jù)。當(dāng) ffmpeg 推流到 SRS 后SRS 內(nèi)部會生成一條流。這條流先以 RTMP/FLV 的形式存在服務(wù)器上。當(dāng)播放端發(fā)起 WebRTC 請求時SRS 讀取這條流中的 H.264 視頻幀把它們封裝到 RTP 包中通過協(xié)商好的 UDP 路徑發(fā)送給瀏覽器。這里有一個關(guān)鍵點RTMP 到 WebRTC 的轉(zhuǎn)換并不等于轉(zhuǎn)碼。默認(rèn)情況下SRS 不改變視頻編碼格式而是做“轉(zhuǎn)封裝/轉(zhuǎn)協(xié)議”。如果推流端編碼是 H.264WebRTC 播放端同樣收到的也是 H.264。轉(zhuǎn)碼會消耗大量 CPU所以通常只在編碼格式不兼容時才考慮。3.2 WHIP 與 WHEP 信令流程WebRTC 連接并不是“服務(wù)器直接往瀏覽器扔數(shù)據(jù)”它需要先完成信令協(xié)商。兩端要先交換 SDPSession Description Protocol告訴對方自己支持什么編碼、用什么 IP 和端口通信。SRS 5 支持兩類標(biāo)準(zhǔn)信令接口WHIPWebRTC-HTTP Ingest Protocol用于 WebRTC 推流。WHEPWebRTC-HTTP Egress Protocol用于 WebRTC 拉流播放。本文場景是瀏覽器拉流所以走 WHEP 流程。大致步驟如下瀏覽器創(chuàng)建一個 RTCPeerConnection 對象。調(diào)用 createOffer 生成自己的 SDP offer。把 SDP offer 通過 HTTP POST 發(fā)送到 SRS 的 WHEP 地址。SRS 返回 SDP answer。瀏覽器把 answer 寫入 remoteDescription。雙方通過 ICE 完成 UDP 連接。瀏覽器收到 RTP 媒體數(shù)據(jù)并渲染到 video 標(biāo)簽。整個流程看似復(fù)雜但 SRS 簡化了大部分服務(wù)端邏輯瀏覽器側(cè)使用原生 WebRTC API 就能完成。3.3 媒體格式兼容性注意事項WebRTC 對音頻編碼有比較強的偏好。瀏覽器普遍支持 Opus而 RTMP 推流端很多默認(rèn)使用 AAC。SRS 在某些版本中支持 AAC 到 Opus 的轉(zhuǎn)換但不同版本和配置下行為可能不一樣。為了減少測試環(huán)節(jié)的不確定性我們可以在 ffmpeg 推流時直接輸出 H.264 視頻和 AAC 音頻如果播放端沒有聲音再嘗試推 Opus 音頻。視頻方面H.264 是最穩(wěn)妥的 WebRTC 播放格式幾乎所有瀏覽器都能硬解。如果你推流端輸出的是 H.265瀏覽器 WebRTC 默認(rèn)不支持通常需要先轉(zhuǎn)成 H.264。這一點在視頻監(jiān)控項目中尤其常見。4. 完整實戰(zhàn)搭建 rtmp2webrtc 測試環(huán)境4.1 編寫 SRS 配置文件首先創(chuàng)建配置文件 /data/rtmp2webrtc/conf/srs.conf。# 文件路徑/data/rtmp2webrtc/conf/srs.conf listen 1935; max_connections 1000; daemon off; srs_log_tank console; http_api { enabled on; listen 1985; } http_server { enabled on; listen 8080; dir ./objs/nginx/html; } rtc_server { enabled on; listen 8000; candidate $CANDIDATE; } vhost __defaultVhost__ { rtc { enabled on; } }配置說明listen 1935RTMP 接收端口。http_api.listen 1985HTTP API 端口用于查看流信息、調(diào)用管理接口。http_server.listen 8080HTTPS 靜態(tài)文件服務(wù)端口方便直接訪問播放頁面。rtc_server.listen 8000WebRTC RTP/RTCP 媒體傳輸?shù)?UDP 監(jiān)聽端口。rtc_server.candidateSRS 向播放端通告的 IP 地址。這里寫成 $CANDIDATE 是為了通過環(huán)境變量動態(tài)注入你也可以在測試環(huán)境里直接寫成服務(wù)器實際 IP。candidate 配置是 rtmp2webrtc 測試環(huán)境中最容易踩坑的地方。如果服務(wù)器是公網(wǎng)機器或云主機candidate 必須配置成客戶端能訪問到的 IP。如果配置成了 127.0.0.1 或內(nèi)網(wǎng) IP瀏覽器雖然完成了信令協(xié)商但媒體包可能永遠到不了播放端。4.2 Docker 啟動 SRS進入測試目錄執(zhí)行以下命令啟動 SRS 容器。假設(shè)你的服務(wù)器 IP 是 192.168.1.100請?zhí)鎿Q成實際環(huán)境。cd /data/rtmp2webrtc docker run -d --name srs \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ -p 8000:8000/udp \ -v /data/rtmp2webrtc/conf/srs.conf:/usr/local/srs/conf/srs.conf \ -e CANDIDATE192.168.1.100 \ ossrs/srs:5執(zhí)行后查看容器日志docker logs -f srs如果啟動正常日志中會顯示配置加載成功并出現(xiàn) RTMP、HTTP API、RTC Server 的監(jiān)聽信息??吹筋愃葡旅娴膬?nèi)容時說明服務(wù)已經(jīng)起來了rtmp: listen tcp://0.0.0.0:1935 http api: listen tcp://0.0.0.0:1985 rtc_server: listen udp://0.0.0.0:8000注意容器的 8000 端口映射方式與普通 TCP 端口不同需要顯式聲明為 udp。漏掉 /udp 聲明會導(dǎo)致瀏覽器可以完成信令協(xié)商但媒體數(shù)據(jù)無法傳輸播放畫面會一直黑屏。4.3 驗證 SRS 服務(wù)是否正常在瀏覽器訪問下面的地址如果能打開 SRS 的默認(rèn) HTTP 頁面說明靜態(tài)服務(wù)器正常http://192.168.1.100:8080/訪問 HTTP API 查看流列表curl http://192.168.1.100:1985/api/v1/streams此時還沒有推流返回結(jié)果中 streams 數(shù)組應(yīng)該為空。這個接口在后面可以用來確認(rèn)流是否成功推上來。4.4 使用 ffmpeg 模擬 RTMP 推流為了方便測試我使用 ffmpeg 的 lavfi 虛擬設(shè)備生成畫面和聲音不需要準(zhǔn)備真實視頻文件。先測試視頻和音頻均為 H.264 AAC 的推流命令ffmpeg -re -f lavfi -i testsrcsize1280x720:rate25 \ -f lavfi -i sinefrequency1000:sample_rate44100 \ -c:v libx264 -preset veryfast -b:v 1500k \ -c:a aac -b:a 128k \ -f flv rtmp://192.168.1.100:1935/live/livestream命令參數(shù)解釋-re以實時速率讀取輸入模擬真實推流。testsrcffmpeg 內(nèi)置測試畫面畫面帶有彩色條和時間信息。sine1kHz 正弦波模擬音頻。libx264H.264 編碼。aacAAC 音頻編碼。rtmp://192.168.1.100:1935/live/livestream推流地址其中 live 是應(yīng)用名livestream 是流名。如果你希望驗證 WebRTC 音頻兼容性可以把音頻編碼改成 Opusffmpeg -re -f lavfi -i testsrcsize1280x720:rate25 \ -f lavfi -i sinefrequency1000:sample_rate44100 \ -c:v libx264 -preset veryfast -b:v 1500k \ -c:a libopus -b:a 64k \ -f flv rtmp://192.168.1.100:1935/live/livestream當(dāng) ffmpeg 成功推流后再次查看流列表curl http://192.168.1.100:1985/api/v1/streams如果返回結(jié)果表明存在 live/livestream 這條流說明 RTMP 推流已經(jīng)成功。4.5 編寫 WebRTC 播放頁面下面創(chuàng)建一個最簡單的 WebRTC 播放頁面。這個頁面不依賴任何第三方庫使用瀏覽器原生 API 和 SRS 的 WHEP 接口完成拉流。文件路徑/data/rtmp2webrtc/pages/player.html!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleSRS WebRTC 播放測試/title style body { font-family: Arial, sans-serif; padding: 20px; } video { width: 640px; background: #000; } /style /head body h2RTMP 轉(zhuǎn) WebRTC 播放測試/h2 video idplayer autoplay controls muted/video p idstatus正在連接.../p script const video document.getElementById(player); const status document.getElementById(status); // 改成你的服務(wù)器實際地址 const whepUrl http://192.168.1.100:1985/rtc/v1/whep/?applivestreamlivestream; async function startPlayback() { // 1. 創(chuàng)建 RTCPeerConnection const pc new RTCPeerConnection({ iceServers: [{ urls: stun:stun.l.google.com:19302 }] }); // 2. 聲明接收音視頻 pc.addTransceiver(video, { direction: recvonly }); pc.addTransceiver(audio, { direction: recvonly }); // 3. 收到媒體流后渲染到 video pc.ontrack (event) { if (event.streams event.streams[0]) { video.srcObject event.streams[0]; status.textContent WebRTC 播放中; } }; // 4. 創(chuàng)建并設(shè)置本地 SDP const offer await pc.createOffer(); await pc.setLocalDescription(offer); // 5. 通過 WHEP 接口發(fā)送給 SRS const resp await fetch(whepUrl, { method: POST, headers: { Content-Type: application/sdp }, body: offer.sdp }); if (!resp.ok) { throw new Error(WHEP 請求失敗: resp.status await resp.text()); } // 6. 設(shè)置遠端 SDP const answerSdp await resp.text(); await pc.setRemoteDescription({ type: answer, sdp: answerSdp }); } startPlayback().catch((err) { status.textContent 播放失敗: err.message; console.error(err); }); /script /body /html把這個頁面放到 SRS 的 HTTP 服務(wù)目錄下或者單獨用 Nginx 托管。最簡單的方式是直接使用 Docker 命令拷貝到容器內(nèi)。但更推薦在宿主機上通過 Nginx 或 Python HTTP 服務(wù)訪問避免修改容器內(nèi)部文件造成環(huán)境不可恢復(fù)。如果使用 SRS 的 8080 靜態(tài)服務(wù)可以直接把頁面放到容器映射目錄中。不過上面的配置里 http_server 的 dir 指向的是容器內(nèi)的 ./objs/nginx/html因此更方便的辦法是把 player.html 放到 SRS 的 html 目錄然后在瀏覽器訪問http://192.168.1.100:8080/player.html拷貝方式docker cp /data/rtmp2webrtc/pages/player.html srs:/usr/local/srs/objs/nginx/html/player.html4.6 運行與驗證在瀏覽器打開 player.html如果一切正常你會看到測試畫面同時頁面提示“WebRTC 播放中”。驗證要點畫面是否流暢延遲是否符合預(yù)期。聲音是否正常。如果你用 AAC 推流沒有聲音可以換成 Opus 推流命令再試。瀏覽器控制臺沒有 WebRTC 連接失敗的錯誤。為了更直觀地觀察延遲ffmpeg 生成的 testsrc 畫面上帶有時間信息。你用手機秒表或另一臺顯示當(dāng)前時間的設(shè)備對比一下就能粗略判斷延遲高低。正常情況下延遲通常在 1 秒以內(nèi)。5. 常見問題與排查思路5.1 問題速查表問題現(xiàn)象常見原因解決思路頁面一直轉(zhuǎn)圈無法播放candidate 配置錯誤將 srs.conf 中 candidate 改成客戶端可達 IP信令正常但畫面黑屏UDP 8000 端口不通檢查云安全組和服務(wù)器防火墻放通 UDP 8000瀏覽器報 CORS 錯誤播放頁面與 API 不同源用 Nginx 將頁面和 /rtc/v1/ 接口代理到同一域名ffmpeg 推流失敗RTMP 端口未放通檢查 TCP 1935 端口有畫面沒有聲音音頻編碼不兼容試試推 Opus 音頻或檢查 SRS 是否啟用轉(zhuǎn)碼延遲很高是否真正建立了 WebRTC 連接檢查頁面是不是走了 HTTP-FLV/HLS 回流5.2 典型問題信令通了但畫面一直黑屏這是 rtmp2webrtc 測試環(huán)境中最常見的問題?,F(xiàn)象是瀏覽器控制臺沒有報錯WHEP 請求成功返回RTCPeerConnection 狀態(tài)也正常但 video 標(biāo)簽一直黑屏。根本原因通常是 UDP 媒體端口不通。WebRTC 的信令走 HTTP只要 TCP 1985 端口能訪問信令流程就會成功。但真正的視頻數(shù)據(jù)是走 UDP 8000 端口發(fā)送的。如果服務(wù)器防火墻或云安全組沒有放通 UDP 8000媒體包就會被丟棄。排查順序查看 SRS 容器是否監(jiān)聽 UDP 8000docker exec -it srs ss -lunp | grep 8000在客戶端測試 UDP 端口是否可達。UDP 沒有 telnet 那樣的三次握手但可以用 nc 做簡單驗證nc -vuz 192.168.1.100 8000這個命令能證明 UDP 包是否有去有回不過不同系統(tǒng)下結(jié)果不一定絕對準(zhǔn)確。更可靠的判斷方式是在 SRS 容器里開啟詳細日志觀察是否有 RTP 包進來。檢查云廠商安全組。云主機通常有兩個防火墻層級操作系統(tǒng)內(nèi)部防火墻firewalld/iptables和安全組。兩個地方都要放通 UDP 8000。解決方案在防火墻中放通 UDP 8000然后重啟 SRS 容器并重新播放驗證。5.3 典型問題CORS 跨域錯誤當(dāng)你用瀏覽器直接訪問另一個端口的 WHEP 接口時如果 SRS 沒有返回正確的 Access-Control-Allow-Origin 響應(yīng)頭控制臺會報跨域錯誤播放自然失敗。規(guī)避方法有兩種。第一種把播放頁面放到 SRS 的 8080 端口靜態(tài)目錄中但 API 是 1985 端口這仍然是跨域。所以更推薦第二種。第二種用 Nginx 做反向代理。把頁面和 API 統(tǒng)一暴露在同一個域名和端口下。Nginx 配置示例server { listen 80; server_name 192.168.1.100; location /rtc/ { proxy_pass http://127.0.0.1:1985; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; } }配置完成并重啟 Nginx 后播放頁面要改成訪問 Nginx 的地址const whepUrl http://192.168.1.100/rtc/v1/whep/?applivestreamlivestream;頁面本身通過http://192.168.1.100/player.html訪問。這樣頁面和接口就在同一個源下不會有跨域問題。5.4 典型問題Candidate 地址不對SRS 的 rtc_server.candidate 決定了 SRS 在 SDP 中通告給瀏覽器的媒體連接地址。如果這個地址是內(nèi)網(wǎng) IP 或者 127.0.0.1瀏覽器會嘗試往這個地址發(fā)媒體數(shù)據(jù)自然連不上。在 Docker 部署方式下還需要注意容器網(wǎng)絡(luò)模式。如果你把 candidate 設(shè)成了容器內(nèi)部 IP瀏覽器訪問不到。正確做法是設(shè)置成宿主機可訪問的 IP 或域名。如果部署在云主機上candidate 可以填云主機私網(wǎng) IP也可以填公網(wǎng) IP。這里沒有絕對標(biāo)準(zhǔn)原則只有一個客戶端能夠訪問到該地址。對于公網(wǎng)播放場景candidate 必須配置成公網(wǎng) IP。修改配置文件后一定要重啟容器docker restart srs然后重新打開播放頁面測試。6. 最佳實踐與工程建議6.1 測試環(huán)境與生產(chǎn)環(huán)境的差異測試環(huán)境跑通后不代表生產(chǎn)環(huán)境可以直接按同樣方式部署。下面幾點在工程上尤其值得注意。生產(chǎn)環(huán)境建議使用固定版本鏡像而不是 latest。Docker 鏡像的 latest 標(biāo)簽會隨時間變化容易導(dǎo)致測試和生產(chǎn)版本不一致。推薦在 Docker Compose 文件里寫死鏡像 tag。生產(chǎn)環(huán)境還要考慮域名和 HTTPS。瀏覽器對 WebRTC 的限制非常嚴(yán)格如果頁面通過 HTTPS 訪問媒體流的信令和傳輸會有更統(tǒng)一的兼容性。雖然這個純拉流示例不一定強制要求 HTTPS但在真實業(yè)務(wù)中頁面和 API 都建議統(tǒng)一走 HTTPS/WSS。6.2 配置管理SRS 配置文件應(yīng)該納入版本管理。不同環(huán)境使用不同配置文件例如srs.conf公共配置。srs.conf.test測試環(huán)境配置。srs.conf.prod生產(chǎn)環(huán)境配置。candidate 這類和環(huán)境強相關(guān)的配置不要寫入公共配置應(yīng)該通過環(huán)境變量或部署管道注入。這樣同一份配置可以在不同環(huán)境之間切換不容易出現(xiàn)“本地能跑線上黑屏”的問題。6.3 安全與訪問控制SRS 默認(rèn)的 HTTP API 端口如果直接暴露到公網(wǎng)任何人都有可能調(diào)用接口查看流信息或執(zhí)行管理操作。測試環(huán)境問題不大但生產(chǎn)環(huán)境至少做好兩步限制 API 端口訪問來源例如只允許管理網(wǎng)段訪問 1985。對播放和推流做鑒權(quán)SRS 支持回調(diào)鑒權(quán)可以在推流或播放時通過 HTTP 回調(diào)到業(yè)務(wù)服務(wù)器校驗身份。涉及服務(wù)器防火墻和云安全組配置時遵循最小權(quán)限原則。只放通必要的端口不要順手放行整個網(wǎng)段更不要在生產(chǎn)環(huán)境關(guān)閉防火墻做測試。6.4 性能與穩(wěn)定性媒體服務(wù)器對 UDP 端口和網(wǎng)絡(luò)質(zhì)量比較敏感。大規(guī)模并發(fā)播放時UDP 8000 端口會成為瓶頸單節(jié)點能力有限。建議在接入生產(chǎn)流量前做壓測觀察 CPU、內(nèi)存和帶寬占用。時間同步也是一個容易被忽視的點。WebRTC 對時間戳和 RTCP 反饋有要求服務(wù)器時間漂移會影響播放穩(wěn)定性。部署服務(wù)后建議開啟 NTP 時間同步。如果測試環(huán)境是國產(chǎn)化平臺例如麒麟系統(tǒng) ARM 架構(gòu)部署前先確認(rèn)鏡像是否支持對應(yīng) CPU 架構(gòu)。不支持的架構(gòu)就用源碼編譯不要盲目用docker pull避免啟動時出現(xiàn) exec format error。7. 總結(jié)與下一步這篇文章從零搭建了一套 rtmp2webrtc 測試環(huán)境核心內(nèi)容包括RTMP 與 WebRTC 的協(xié)議差異。SRS 如何接收 RTMP 流并轉(zhuǎn)換給瀏覽器。Docker 啟動 SRS 的具體步驟。ffmpeg 推流命令和 WebRTC 網(wǎng)頁播放器。黑屏、CORS、candidate 配置錯誤的排查方法。把這套環(huán)境跑通之后你可以繼續(xù)往更多方向深入例如測試 SRT 協(xié)議接入、WebRTC 推流、多路流轉(zhuǎn)發(fā)、集群部署、鑒權(quán)回調(diào)等。RTMP 轉(zhuǎn) WebRTC 只是流媒體接入層的一個環(huán)節(jié)掌握它以后再去理解低延遲直播的全鏈路架構(gòu)就不會覺得有障礙了。如果你在搭建過程中遇到其他問題建議先把容器日志打開再按“信令是否通過、媒體端口是否放通、candidate 是否正確、編碼格式是否兼容”的順序逐步排查。這套思路能覆蓋大部分測試環(huán)境中的故障場景。