外网访问内网海康威视监控视频的方案: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文件内容如下:

视频监控-测试

其中是引用的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访问摄像机视频流教程