ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

WebRTC与RTSP融合:webrtc-streamer实现摄像头网页低延迟监控

WebRTC与RTSP融合:webrtc-streamer实现摄像头网页低延迟监控 简介这是一套基于webrtc-streamer的网络摄像头实时监控部署方案面向需要快速搭建免插件网页视频监控的开发者或运维人员兼容Win7至Win11系统建议在Win11下使用webrtc-streamer-v0.7.2版本以获取更好兼容性。压缩包共183个文件约10.69MB主要包含52个JavaScript脚本、48个HTML页面以及CSS样式、字体图标、配置文件等内置exe主程序与bat启动脚本涵盖WebRTC流媒体服务、前端播放页面和PoseNet等模型资源。已有4410人学习下载。资源已预先写好有窗口和无窗口两种bat启动方式避免直接双击exe触发问题运行后仅需修改HTML中的RTSP地址即可接入摄像头实测开启30路视频延迟约1秒并且支持所有主流浏览器、无需安装插件。压缩包内还附带了BlaZeFace、Body-Pix、coco-ssd等前端AI模型便于在监控画面基础上进一步扩展人体检测等智能分析功能。 做网络摄像头的网页实时监控绕不开“延迟”和“兼容性”这两座大山。以前想在浏览器里直接看IPC的RTSP流要么装插件要么转HLS走几秒延迟体验一言难尽。webrtc-streamer这个开源项目把WebRTC的能力引到传统摄像头领域能直接拉取RTSP/RTMP这类标准协议流在浏览器无插件播放延迟可以做到几百毫秒级别。这篇文章我把部署、接入、调优和排错的全过程整理出来照着操作基本能跑通。1. 项目核心思路为什么是webrtc-streamer1.1 浏览器播放监控流的方案对比在决定用webrtc-streamer之前我先梳理一下目前主流做法后面对选型会有更清晰的感觉。方案延迟兼容性实施成本典型场景HLS先转码再切片5~10秒最好所有现代浏览器都支持需要ffmpeg流媒体服务器直播、回放不追求实时FLV MSE1~3秒Chrome/Firefox效果好Safari差需要http-flv流媒体服务直播平台通用方案RTSP直接播放最低基本不可行浏览器原生不支持无基本不存在WebRTCwebrtc-streamer0.2~1秒主流浏览器都支持一个轻量服务即可安防实时监控、远程控制HLS虽然兼容性无解但延迟高到没法用于“实时监控”场景——你看到画面的时候现场可能已经过去好几秒了这在看门禁、看车间设备时没法接受。FLVMSE方案延迟能接受但Safari支持不理想而且需要自己搭流媒体服务器。webrtc-streamer的方案是把摄像机RTSP流直接转成WebRTC会话浏览器端用标准WebRTC API播放不用额外插件延迟和时间戳抖动控制都更优。1.2 WebRTC低延迟的核心原理WebRTC本质上是浏览器之间的实时通信协议webrtc-streamer把它“翻译”成了摄像头侧的拉流能力。它底层用的是UDP传输配合SRTP加密和FEC前向纠错避免了TCP重传带来的延迟抖动。WebRTC还会动态调整发送码率通过网络拥塞控制算法感知带宽变化让视频在可用带宽内尽量清晰。这种机制对安防监控场景特别合适因为摄像头码流是持续性的不像点播视频有突发性。webrtc-streamer内部集成了GStreamer管道和libwebrtc自动完成RTSP的解封装、解码必要时转码和WebRTC编码对外暴露一个HTTP接口网页端只需要调用它提供的JavaScript库就行。2. 环境准备与部署2.1 Docker部署推荐方案如果不想折腾源码编译环境直接用Docker镜像最省事。官方镜像名是mpromonet/webrtc-streamer一条命令就能起服务docker run -d --name webrtc-streamer \ -p 8000:8000 \ -p 8001:8001 \ mpromonet/webrtc-streamer \ -H 0.0.0.0 \ -p 8000参数解释一下-H指定监听地址0.0.0.0表示所有网卡都能访问-p指定HTTP端口方便后面网页访问8001是可选的信令端口如果不需要可以不开。启动后浏览器访问http://服务器IP:8000能看到默认的HTML测试页面说明服务正常。注意Docker部署时容器默认只暴露8000端口如果摄像头RTSP地址在宿主机局域网内容器内访问没问题。但某些定制化Docker网络环境可能访问不到摄像头可以用--network host模式启动让容器直接共享宿主机网络栈。2.2 源码编译部署源码编译适合需要二次开发、定制H264/H265编码参数的场景。依赖较多我实测在Ubuntu 22.04上的过程是这样sudo apt update sudo apt install -y cmake libglib2.0-dev libssl-dev \ libsoup2.4-dev libgstreamer1.0-dev \ libgstreamer-plugins-base1.0-dev \ gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \ gstreamer1.0-plugins-ugly gstreamer1.0-libav git clone https://github.com/mpromonet/webrtc-streamer.git cd webrtc-streamer cmake . make -j$(nproc)这个编译过程最难受的点在于CMake会自动从Google和GitHub下载libwebrtc预编译库国内网络条件差的话很容易卡在下载步骤。如果编译失败先检查能不能访问相关域名或者改用我上面说的Docker方式编译踩坑的性价比真的很低。2.3 服务启动与初步验证编译完成后或Docker启动后可以用以下命令直接传入摄像头地址启动./webrtc-streamer -H 0.0.0.0 -p 8000 rtsp://admin:password192.168.1.108:554/stream1也可以用配置文件管理多个摄像头config文件每行一个URL用-c参数指定。启动后访问http://localhost:8000如果页面能正常打开且日志里出现HTTP server started说明服务就绪。3. 摄像头接入与前端播放实战3.1 RTSP地址的获取与验证无论海康、大华还是TP-LINK的摄像头RTSP地址格式都类似rtsp://用户名:密码IP地址:端口/流路径。不同品牌的路径后缀不同海康常见的是/h264/ch1/main/av_stream大华是/cam/realmonitor?channel1subtype0。登录摄像头管理后台一般在“配置-网络-高级设置-集成协议”里能看到RTSP地址示例。拿到地址后先用VLC验证一下能不能播放这一步非常关键打开VLC - 媒体 - 打开网络串流 - 输入RTSP地址如果VLC能正常显示画面说明地址、端口、账号密码都没问题如果VLC都放不出来就得先排查网络连通性、账号权限别急着怪webrtc-streamer3.2 前端页面最小实现webrtc-streamer自带的webrtcstreamer.js可以在服务根目录访问到。网页端基本代码如下!DOCTYPE html html head meta charsetUTF-8 title网络摄像头实时监控/title style video { width: 640px; height: 360px; background: #000; } /style /head body h3IP Camera Live/h3 video idvideo autoplay muted playsinline/video div idstatsRTT: -- ms/div script src/webrtcstreamer.js/script script let webRtcServer new WebRtcStreamer( video, location.hostname :8000 ); webRtcServer.connect( rtsp://admin:password192.168.1.108:554/stream1, null, null, null, null, video, null, null ); /script /body /html关键点说明new WebRtcStreamer(元素ID, 服务端地址)的第二个参数是webrtc-streamer服务的地址不能写localhost因为浏览器需要向这个地址发起WebSocket连接和WebRTC协商connect()方法第一个参数是要播放的RTSP地址后端不需要事先配置也能动态传入muted属性必加因为WebRTC播放通常会自动播放限制静音状态允许自动播放playsinline对iOS Safari有作用避免视频自动全屏3.3 延迟测量与画质调优我实测下来局域网内webrtc-streamer的端到端延迟能稳定在300~500ms左右。这个延迟怎么量化除了肉眼观察可以利用webrtc-streamer暴露的getStats()接口setInterval(async () { const stats await webRtcServer.getStats(); if (stats.rtt stats.jitter) { document.getElementById(stats).textContent RTT: stats.rtt ms, Jitter: stats.jitter; } }, 2000);我在调试多路视频时发现把摄像头的主码流main stream和子码流sub stream灵活切换对延迟和带宽影响很大。监控画面用子码流分辨率低但延迟小需要看细节时再切主码流是比较实用的策略。如果你想更严谨地测量“画面延迟”可以在摄像头前面放一个计时秒表然后手机拍下电脑画面对比秒表时间差。这个土办法其实最直观。顺便提一个很多人在用的辅助技巧用OBS的虚拟摄像头功能把摄像头画面作为虚拟信号源接入测试工具配合高帧率录屏分析端到端延迟。这种方式比较接近真实用户画面链路也能用来对比不同转码参数的延迟差异。为了降低延迟我调整过以下参数调整项推荐值理由摄像头编码H.264 Baseline/High解码性能好兼容性最强分辨率主码流1080P子码流720P网络差时降级用子码流帧率15~25fps帧率过低时画面卡顿感明显GOP大小1~2秒GOP太长关键帧间隔大起播慢码率限制4~8Mbps控制单路带宽占用实际上webrtc-streamer本身也会对码率做动态调整但摄像头源头码流如果太大UDP丢包率会上升画面会出现马赛克。我建议把码流控制在10Mbps以内尤其是多路并发时。4. 常见问题与排查技巧实录4.1 黑屏或无法播放我遇到过的黑屏原因按概率排序RTSP地址或账号错误先用VLC验证VLC能放webrtc-streamer基本也能放摄像头并发连接数限制很多摄像头默认只允许2~4路RTSP会话如果之前有VLC、NVR占着再连就失败。重启摄像头或先关掉其他工具再试编解码不支持webrtc-streamer对H.264支持最好H.265则要看版本是否启用了对应解码器。如果摄像头默认输出H.265登录后台改成H.264再试防火墙拦截端口webrtc-streamer的WebRTC媒体流走UDP端口防火墙要放行相关UDP端口4.2 延迟忽高忽低延迟波动大大概率不是webrtc-streamer的问题而是摄像头或网络链路的问题。排查思路网络抖动测试在服务器上持续ping摄像头IP看是否有明显丢包ping 192.168.1.108 -t如果有丢包先处理网络带宽占用多个客户端同时拉同一路流摄像头发码能力跟不上容易造成延迟堆积UDP不通WebRTC默认优先UDP如果服务器和浏览器之间UDP被防火墙阻断会退化到TCP延迟升高。可以通过webrtc-streamer日志看ICE连接类型确认是否走UDP4.3 浏览器直接访问报错我们经常遇到用http://192.168.1.X:8000访问页面没问题但要发布到公网或局域网其他机器某些浏览器强制要求HTTPS。这是因为WebRTC的三个核心接口getUserMedia、RTCPeerConnection、getDisplayMedia在非安全上下文下不可用。如果只在内网用http://局域网IP:8000是可以的。如果要部署到公网或用域名访问必须加一层Nginx做HTTPS反向代理server { listen 443 ssl; server_name cam.example.com; ssl_certificate /etc/nginx/ssl/cam.crt; ssl_certificate_key /etc/nginx/ssl/cam.key; location / { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } }这里特别要注意Upgrade和Connection头WebRTC信令走了WebSocketNginx不转发这两个头的话握手会失败。4.4 多路视频同时播放卡顿我同时播放4路1080P流时服务器CPU和带宽压力都不小。webrtc-streamer是单线程libwebrtc编码器多路并行时可能成为瓶颈。我的优化方案是前端按需播放摄像头画面在屏幕外时先停止连接进来再重新连接这比同时维持4路不断流稳定得多把摄像头改为子码流播放1080P画面在缩略图场景下看不出区别但带宽占用直接降到1/3如果主机性能允许可以运行多个webrtc-streamer实例不同实例分配不同摄像头组前端按摄像头分组选择对应的服务端口4.5 鉴权与安全加固webrtc-streamer默认不校验访问者身份任何拿到IP和端口的人都能看监控画面。生产环境必须加一层访问控制。最简单的做法是Nginx加Basic Authlocation / { auth_basic Restricted; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://127.0.0.1:8000; }更安全的做法是给webrtc-streamer加上--authentication参数在服务端做token校验避免完全裸奔。5. 踩坑后的几个心得最后分享几个我实操后的体会。先用VLC验证RTSP永远是排查问题的第一步。很多用户说webrtc-streamer播放不了最后发现是摄像头地址列表换版本后路径变了。VLC作为基准工具能快速缩小问题范围别上来就改代码。Docker部署是最省心的路径。源码编译虽然在后面自定义编码参数时更灵活但从零部署的效率来看Docker真的省了太多事。建议先Docker跑通流程再按需回源码。H.264兼容性远好于H.265。如果摄像头支持双编码优先选H.264。H.265在部分浏览器和webrtc-streamer版本上可能走不通排查起来很痛苦。延迟测量要有量化手段。用getStats的RTT数据做实时监控再配合秒表法测量端到端延迟能让你对系统状态有准确认知而不是靠“看着好像流畅”来判断。webrtc-streamer目前是我在网页监控项目里的首选方案部署简洁、延迟可控、兼容性也够广。如果你也想在网页里看摄像头画面照着这套流程走一遍应该能避开大多数坑。本文还有配套的精品资源点击获取
返回列表