外网访问内网海康威视监控视频的方案:WebRTC + Coturn 搭建

news2025/5/14 18:25:34

外网访问内网海康威视监控视频的方案: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的标准。

核心功能

  1. 实时音视频通信
    • 支持浏览器之间直接传输高清视频和音频,延迟低(通常 < 500ms)。
  2. 点对点(P2P)传输
    • 数据直接在用户设备间传输,减少服务器中转,提升效率。
  3. 数据通道(Data Channel)
    • 支持传输任意数据(如文件、游戏指令、文本),类似WebSocket但延迟更低。
  4. 加密传输
    • 默认使用DTLS-SRTP加密,确保通信安全。

关键技术组件

  • MediaStream(getUserMedia)
    访问摄像头和麦克风,获取音视频流。
  • RTCPeerConnection
    建立P2P连接,处理编解码、网络穿透(NAT)和流量控制。
  • RTCDataChannel
    提供双向数据传输,适合低延迟场景(如游戏、文件共享)。
  • ICE/STUN/TURN
    • ICE(Interactive Connectivity Establishment):协调最佳连接路径。
    • STUN:获取公网IP,解决NAT穿透问题。
    • TURN:在中继服务器转发数据,用于严格的防火墙环境。

WebRTC-Streamer建立连接的时序图如下

在这里插入图片描述

WebRTC建立点对点通信的过程如下图所示

设备A 信令服务器 设备B STUN 发送 SDP Offer 转发 Offer 发送 SDP Answer 转发 Answer 获取 ICE Candidate 获取 ICE Candidate 发送 ICE Candidate 发送 ICE Candidate 转发 B的Candidate 转发 A的Candidate 直接建立 P2P 连接 设备A 信令服务器 设备B STUN

参考资料

流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls)

史上最详细的webrtc-streamer访问摄像机视频流教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2373739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统下的延迟任务及定时任务

1、延迟任务 概念&#xff1a; 在系统中我们的维护工作大多数时在服务器行对闲置时进行 我们需要用延迟任务来解决自动进行的一次性的维护 延迟任务时一次性的&#xff0c;不会重复执行 当延迟任务产生输出后&#xff0c;这些输出会以邮件的形式发送给延迟任务发起者 在 RH…

【网络原理】数据链路层

目录 一. 以太网 二. 以太网数据帧 三. MAC地址 四. MTU 五. ARP协议 六. DNS 一. 以太网 以太网是一种基于有线或无线介质的计算机网络技术&#xff0c;定义了物理层和数据链路层的协议&#xff0c;用于在局域网中传输数据帧。 二. 以太网数据帧 1&#xff09;目标地址 …

相或为K(位运算)蓝桥杯(JAVA)

这个题是相或为k&#xff0c;考察相或的性质&#xff0c;用俩个数举例子&#xff0c;011001和011101后面的数不管和哪个数相或都不可能变成前面的数&#xff0c;所以利用这个性质我们可以用相与运算来把和k对应位置的1都积累起来&#xff0c;看最后能不能拼起来k如果能拼起来k那…

AI汽车时代的全面赋能者:德赛西威全栈能力再升级

AI汽车未来智慧出行场景正在描绘出巨大的商业图景&#xff0c;德赛西威已经抢先入局。 在2025年上海车展开幕前夕&#xff0c;德赛西威发布2030年全新使命愿景——“创领安全、愉悦和绿色的出行生活”&#xff0c;并推出全栈式智慧出行解决方案Smart Solution3.0、车路云一体式…

学习Python的第四天之网络爬虫

30岁程序员学习Python的第四天之网络爬虫的Scrapy库 Scrapy库的基本信息 Scrapy库的安装 在windows系统中通过管理员权限打开cmd。运行pip install scrapy即可安装。 通过命令scrapy -h可查看scrapy库是否安装成功. Scrapy库的基础信息 scrapy库是一种爬虫框架库 爬虫框…

5、开放式PLC梯形图编程组件 - /自动化与控制组件/open-plc-programming

76个工业组件库示例汇总 开放式PLC编程环境 这是一个开放式PLC编程环境的自定义组件&#xff0c;提供了一个面向智能仓储堆垛机控制的开放式PLC编程环境。该组件采用苹果科技风格设计&#xff0c;支持多厂商PLC硬件&#xff0c;具有直观的界面和丰富的功能。 功能特点 多语…

linux中常用的命令(三)

目录 1- ls(查看当前目录下的内容) 2- pwd (查看当前所在的文件夹) 3- cd [目录名]&#xff08;切换文件夹&#xff09; 4- touch [文件名] &#xff08;如果文件不存在&#xff0c;新建文件&#xff09; 5- mkdir[目录名] &#xff08;创建目录&#xff09; 6-rm[文件名]&…

Java 中 AQS 的实现原理

AQS 简介 AQS(全称AbstractQueuedSynchronizer)即抽象同步队列&#xff0c;它是实现同步器的基础组件&#xff0c;并发包中锁的底层就是使用AQS实现的。 由类图可以看到&#xff0c;AQS是一个FIFO的双向队列&#xff0c;其内部通过节点head和tail记录队首和队尾元素&#xff0…

『Python学习笔记』ubuntu解决matplotlit中文乱码的问题!

ubuntu解决matplotlit中文乱码的问题&#xff01; 文章目录 simhei.ttf字体下载链接&#xff1a;http://xiazaiziti.com/210356.html将字体放到合适的地方 sudo cp SimHei.ttf /usr/share/fonts/(base) zkfzkf:~$ fc-list | grep -i "SimHei" /usr/local/share/font…

鸿蒙知识总结

判断题 1、 在http模块中&#xff0c;多个请求可以使用同一个httpRequest对象&#xff0c;httpRequest对象可以复用。&#xff08;错误&#xff09; 2、订阅dataReceiverProgress响应事件是用来接收HTTP流式响应数据。&#xff08;错误&#xff09; 3、ArkTS中变量声明时不需要…

C++23 新特性:深入解析 std::views::join_with(P2441R2)

文章目录 std::views::join_with 基本用法处理字符串集合std::views::join_with 与其他视图的结合使用总结 随着C23标准的逐步推进&#xff0c;我们迎来了许多令人兴奋的新特性&#xff0c;其中之一就是 std::views::join_with。这个新特性是C23中引入的视图适配器&#xff0c…

数据可视化大屏——智慧社区内网比对平台

综述分析&#xff1a; 智慧社区内网数据比对信息系统 这段代码实现了一个智慧社区内网数据比对信息系统的前端界面&#xff0c;采用三栏式布局展示各类社区安全相关数据。界面主要由左侧数据统计、中间地图展示和右侧数据分析三部分组成&#xff0c;使用了多种图表可视化技术…

Jenkins企业级实战

目标 在Windows操作系统上使用Jenkins完成代码的自动拉取、编译、打包、发布工作。 实施 1.安装Java开发工具包&#xff08;JDK&#xff09; Jenkins是基于Java的应用程序&#xff0c;因此需要先安装JDK。可以从Oracle官网或OpenJDK下载适合的JDK版本。推荐java17版本&#x…

uniapp-商城-52-后台 商家信息(商家信息数据,云对象使用)

1、概述 已经通过好几个篇幅来说明商家信息&#xff0c;包括logo、商家名称&#xff0c;地址&#xff0c;电话以及商家简介。通过表单组件和标签&#xff0c;以及我们的文件上传标签&#xff0c;都做了说明。&#xff08;logo上传&#xff0c;用的文件上传组件是上传到公共的数…

MySQL 索引设计宝典:原理、原则与实战案例深度解析

目录 前言第一章&#xff1a;索引设计的基础原则 (知其然&#xff0c;更要知其所以然)第二章&#xff1a;实战案例&#xff1a;电商订单系统的索引设计第三章&#xff1a;索引设计的实践流程总结结语 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜…

C#上传文件到腾讯云的COS

测试环境&#xff1a; vs2022 .net 6控制台应用程序 测试步骤如下&#xff1a; 1 添加子用户&#xff0c;目前是为了拿到secretId和secretKey&#xff0c;打开添加子用户界面链接&#xff1a;https://console.cloud.tencent.com/cam 并为子用户添加API 密钥 2 通过链接htt…

C PRIMER PLUS——第9节:动态内存分配、存储类别、链接和内存管理

目录 1.动态内存分配 1.1 malloc 函数 1.2 calloc 函数 1.3 realloc 函数 1.4 free 函数 1.5常见错误 1.6综合例题 2.C语言的内存结构 3.存储类别 3.1作用域&#xff08;Scope&#xff09; 3.2链接&#xff08;Linkage&#xff09; 3.3存储期&#xff08;Storage Du…

作业...

基础配置 RI R2 R3 R4 R5 例如R1 BGP配置 1,R1和R2之间使用直连接口IP地址来建立EBGP对等体关系 2、R2、R3、R4之间配置OSPF协议&#xff0c;保证各设备之间的网络互通&#xff0c;且通过重发布的方式发布路由 查看R2、R3、R4的OSPF路由表&#xff1a; \ R2、R3、R4使用环…

IC ATE集成电路测试学习——电流测试的原理和方法

电流测试 我们可以通过电流来判断芯片的工作状态时&#xff0c;首先先了解下芯片的电流是如何产生的。 静态电流 理论上&#xff0c;CMOS结构的芯片静态时几乎不耗电 CMOS基本结构&#xff1a;Pmos Nmos 串联当逻辑电平稳定时&#xff1a; ➜ 要么Pmos导通&#xff0c;Nmo…

快速理解动态代理

什么是动态代理(Java核心技术卷1的解释) 动态代理是一种运行时生成代理对象的技术&#xff0c;其本质是通过字节码增强在不修改原始类代码的前提下&#xff0c;动态拦截并扩展目标对象的行为。它通过代理对象对原始方法的调用进行拦截&#xff0c;并在方法执行前后注入自定义逻…