外網訪問內網海康威視監控視頻的方案:WebRTC + Coturn
需求背景
在倉庫中有海康威視的監控攝像頭,內網中是可以直接訪問到監控攝像的畫面,由于項目的需求,需要在外網中也能看到監控畫面。
實現這個功能的意義在于遠程操控設備的時候可以看到監控畫面,方便查看遠程操作的效果。
解決方案
海康威視監控攝像頭提供的是RTSP視頻流,在網上查閱了資料,可以通過WebRTC協議在web頁面上顯示RTSP視頻流。
WebRTC協議實現的最好的開源項目是webrtc-streamer,地址在:https://github.com/mpromonet/webrtc-streamer
由于WebRTC會使用對等連接,所以從外網訪問內網的海康威視監控視頻的時候就需要中繼服務,也就是需要一個 STUN 或 TURN 服務器,其作用是為每個客戶端提供 ICE 候選,然后將其轉移到遠程對等方。
大多數 WebRTC 應用都需要服務器來中繼對等方之間的流量,因為客戶端之間通常無法建立直接套接字(除非它們位于同一本地網絡中)。常見的解決方法是使用 TURN 服務器。該術語代表“Traversal Using Relays around NAT”,是一種用于中繼網絡流量的協議。
目前,網上有多個 TURN 服務器選項,既有自托管應用(例如開源 COTURN 項目),也有云端提供的服務。
本項目最終采用自托管的COTURN項目,地址在:https://github.com/coturn/coturn
方案示例圖如下:
上圖中的Relay server即為turn中繼服務器,而STUN server的作用是通過收集NAT背后peer端(即:躲在路由器或交換機后的電腦)對外暴露出來的ip和端口,找到一條可穿透路由器的鏈路,俗稱“打洞”。stun/turn服務器通常要部署在公網上,能被所有peer端訪問到,coturn開源項目同時實現了stun和turn服務的功能,是webrtc應用的必備首選。
方案確定了,接下來就是動手實際搭建了。
實際搭建
基于Coturn搭建stun/turn服務器
參考github中readme文檔,在云服務器中直接使用apt安裝:
step1 更新軟件源
$ sudo apt update
step2 安裝coturn
$ sudo apt install coturn
step3 修改配置文件
主要修改下面幾項關鍵的配置:
lt-cred-mech
user=<用戶名>:<密碼>
注意:要把用戶名和密碼替換成實際的字符串。
step4 停止掉coturn服務
由于安裝coturn服務后,默認是會運行該服務的,所以這兒要先停止掉
$ sudo systemctl stop coturn
step5 前臺運行turnserver服務器
第一次運行,最好是使用前端運行的方式,如果沒有問題的話,再使用后端服務的運行方式。
$ sudo turnserver -r chengdu --log-file stdout
step6 后端服務的方式運行turnserver
在啟動之前要在配置文件中增加realm=chengdu
配置項。
$ sudo systemctl start coturn
可以使用journalctl -xeu coturn.service
查看后臺服務coturn的日志。
step7 驗證stun和turn服務正常運行。
找一臺可以訪問Coturn服務所在ip的機器,然后執行下面的命令:
$ turnutils_uclient -v -u <用戶名> -w <密碼> <云服務器地址>
注意:turnutils_uclient命令要在安裝了coturn服務的機器上才有。
還可以在下面這個網址上驗證stun/turn服務是否運行正常。
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
參考下圖,把stun和turn地址設置好,然后點擊最下面的“Gather candidates”(收集候選鏈路)
云服務器要開放的端口
云服務器需要開發tcp 3478 和 udp 3478端口,方便客戶端連接stun和turn服務器。
并且要開放中繼端口范圍udp 49152-65535。
啟動webrtc-streamer
step1 下載webrtc-streamer
從https://github.com/mpromonet/webrtc-streamer/releases/latest下載軟件包。
step2 啟動webrtc-streamer服務
進入到軟件目錄,然后執行下面的命令:
./webrtc-streamer -v debug -H 8800 -s<云主機ip>:3478 -t<用戶名>:<密碼>@<云主機>:3478
注意:將云主機地址替換成安裝coturn服務的云主機公網IP,用戶名和密碼就是在turnserver.conf中設置的用戶名和密碼,直接替換就行。
step3 將webrtc-streamer做成開機啟動。
這個步驟可以參考Linux添加systemd服務,使用systemctl start xxx啟動服務。
前端頁面示例代碼
index.html文件內容如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta content="width=device-width, initial-scale=1.0" name="viewport" /><script src="js/webrtcstreamer.js"></script><title>視頻監控-測試</title><style> .content{width: 100%;height: 100%;position: absolute;background-color: aliceblue;}.item{width: 49.5%;height: 49.5%;float: left; margin: 3px;}video {width: 100%;height: 100%;object-fit: fill;}</style>
</head><body><div class="content"><div class="item"><video id="video1" muted autoplay loop></video></div><div class="item"><video id="video2" muted autoplay loop></video></div><div class="item"><video id="video3" muted autoplay loop></video></div><div class="item"><video id="video4" muted autoplay loop></video></div></div>
</body>
<script>// let webRtcServer = null;function init() {var videourl1 = "<替換為實際的海康威視RTSP地址1>";let ID1 = "video1";realViewHik(ID1, videourl1)var videourl2 = "<替換為實際的海康威視RTSP地址2>";let ID2 = "video2";realViewHik(ID2, videourl2)var videourl3 = "替換為實際的海康威視RTSP地址3";let ID3 = "video3";realViewHik( ID3, videourl3)var videourl4 = "替換為實際的海康威視RTSP地址4";let ID4 = "video4";realViewHik(ID4, videourl4)}function realViewHik(elem, rtspUrl) {let webRtcServer = new WebRtcStreamer(elem, "http://<webrtc-streamer的ip地址>:8800");let option = "rtptransport=tcp";webRtcServer.connect(rtspUrl, null, option, null)}window.onload = function () {init();}
</script></html>
其中<script src="js/webrtcstreamer.js"></script>
是引用的webrtc-streamer中的webrtcstreamer.js文件,該文件在軟件包的webrtc-streamer-v0.8.5-Linux-x86_64-Release/html
路徑下,可以直接拷貝到js
目錄下使用。
原理解讀
WebRTC協議
WebRTC(Web Real-Time Communication)是一種開源技術,旨在通過簡單的應用程序接口(API)實現瀏覽器和移動應用之間的實時音視頻通信和數據共享,而無需安裝插件或第三方軟件。它由Google主導開發,現已成為W3C和IETF的標準。
核心功能
- 實時音視頻通信
- 支持瀏覽器之間直接傳輸高清視頻和音頻,延遲低(通常 < 500ms)。
- 點對點(P2P)傳輸
- 數據直接在用戶設備間傳輸,減少服務器中轉,提升效率。
- 數據通道(Data Channel)
- 支持傳輸任意數據(如文件、游戲指令、文本),類似WebSocket但延遲更低。
- 加密傳輸
- 默認使用DTLS-SRTP加密,確保通信安全。
關鍵技術組件
- MediaStream(getUserMedia)
訪問攝像頭和麥克風,獲取音視頻流。 - RTCPeerConnection
建立P2P連接,處理編解碼、網絡穿透(NAT)和流量控制。 - RTCDataChannel
提供雙向數據傳輸,適合低延遲場景(如游戲、文件共享)。 - ICE/STUN/TURN
- ICE(Interactive Connectivity Establishment):協調最佳連接路徑。
- STUN:獲取公網IP,解決NAT穿透問題。
- TURN:在中繼服務器轉發數據,用于嚴格的防火墻環境。
WebRTC-Streamer建立連接的時序圖如下
WebRTC建立點對點通信的過程如下圖所示
參考資料
流媒體協議介紹(rtp/rtcp/rtsp/rtmp/mms/hls)
史上最詳細的webrtc-streamer訪問攝像機視頻流教程