外网访问内网海康威视监控视频的方案: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访问摄像机视频流教程