ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Docker部署go2rtc:统一接入RTSP摄像头,实现浏览器WebRTC低延迟预览

Docker部署go2rtc:统一接入RTSP摄像头,实现浏览器WebRTC低延迟预览 搞监控项目、做智能家居或者单纯想在网页里看看自家摄像头的朋友应该都体会过接入设备有多烦。手头三五个摄像头海康的、大华的、杂牌的RTSP 地址一家一个格式浏览器又原生不支持 RTSP想在网页里低延迟观看还得装插件、装客户端体验稀碎。go2rtc 这个轻量级流媒体网关就是专门解决这类问题的它能把 RTSP、RTMP、HLS、MJPEG、WebRTC 这些五花八门的协议统一管理起来尤其在浏览器低延迟预览摄像头这一块体验比很多商业平台还顺滑。今天我用 Docker 把整套服务跑起来从镜像加速、容器部署到多品牌摄像头接入完整走一遍顺便把踩过的坑都整理出来照着抄就行。1. 为什么需要 go2rtc摄像头接入的协议困局先把场景说清楚。绝大多数网络摄像头都支持 RTSP 协议但 RTSP 是个“老古董”它自己跑在 554 端口上用的是 RTP/UDP 传输浏览器不做特殊处理根本播不了。于是各家厂商就搞出了自己的客户端或者要求装 Web 插件海康的 web 插件、大华的 web 插件换台电脑、换个浏览器又要重装一遍烦得不行。再往后HLS 和 RTMP 慢慢变成网页播放的主流但 HLS 延迟高RTMP 又是 Flash 时代的遗留产物现代浏览器一样不原生支持。真正适合摄像头实时预览的其实是 WebRTC——延迟能做到 500ms 以内浏览器原生支持不需要任何插件。麻烦的是市面上几乎没有摄像头原生支持 WebRTC。1.1 摄像头生态的碎片化现状先看一组我日常打交道的设备。海康威视的 RTSP 地址长这样rtsp://admin:password192.168.1.64:554/Streaming/Channels/102这个/102表示通道 1 的子码流如果你想要主码流就得写/101。大华的地址格式又不一样走的是rtsp://admin:password192.168.1.65:554/cam/realmonitor?channel1subtype1。TP-LINK 是rtsp://user:passip:554/stream1。杂牌摄像头更是百花齐放有的还要自己去 ONVIF 探测设备才知道真实地址。海康大华这些设备虽然也都支持 ONVIF 标准但 ONVIF 主要管设备发现、云台控制这些“管理面”真正的视频流还是要靠 RTSP 拉。再加上很多摄像头支持 H.265 编码浏览器对 H.265 的 WebRTC 支持又很差这就带来了第二个问题就算你拿到了 RTSP 地址也没法直接在网页里看。所以实际做项目时通常需要一层“协议转换中间层”把摄像头吐出来的 RTSP 流转成浏览器能直接消费的协议再扔给前端播放器。1.2 go2rtc 的核心价值一个入口、全协议转换go2rtc 就是干这个的。它最初在 Home Assistant 社区里火起来因为 Home Assistant 的 WebRTC 摄像头组件就想找一个能把 RTSP 转 WebRTC 的工具。后来大家发现这个工具单独拿出来也特别好用慢慢就变成独立部署的流媒体网关。它的核心逻辑很简单你给它一堆视频源地址它统一拉流、统一管理然后对外提供多种输出协议。你可以用 WebRTC 在浏览器低延迟观看也可以用 HLS 或者 MJPEG 给老系统、低性能设备用还可以把它当作 RTSP 服务器让 NVR 录像机来拉流。整个服务是 Go 写的单二进制文件就能跑内存占用极低跑在树莓派、NAS、或者一台 1 核 1G 的小云主机上都毫无压力。这跟动不动就要几个 G 内存的完整流媒体服务器比如 MistServer、ZLMediaKit相比轻量太多了。1.3 适用场景和整体架构这套方案适合谁我自己归纳下来主要是三类第一类是家里有摄像头、想在浏览器或手机上看实时画面的玩家第二类是在做智能家居集成、想把摄像头统一接进 Home Assistant 或者其他平台的开发者第三类是做小型安防项目、需要给客户提供网页端实时预览但又不想买商业平台的工程商。图像识别、巡检机器人、智能车这些项目里的摄像头画面如果也需要通过网页低延迟查看同样用得上。整体架构就是一条单向链路摄像头 → RTSP/ONVIF → go2rtc → WebRTC/HLS/MJPEG → 浏览器。go2rtc 在这条链路里相当于一个网关不存录像、不做推流分发虽然它也支持核心职责是解协议、转协议。接下来就用 Docker 把这层网关搭起来。2. Docker 环境准备与镜像加速go2rtc 支持多种安装方式官方甚至提供了 Windows 和 macOS 的桌面版但我要重点讲 Docker 部署原因有两个一是 Docker 把运行环境隔离得干干净净升级、回滚、迁移都方便二是国内摄像头的网络环境比较特殊go2rtc 有时候要跟摄像头所在网段通信Docker 的网络模式可以灵活调整。部署前先把两个前置条件确认清楚。2.1 前期准备Docker 与 Compose机器上得先有 Docker 和 Docker Compose 插件。Linux 服务器一般一条命令装 Docker然后用docker compose version确认 Compose 可用。Windows 和 macOS 用户直接装 Docker Desktop 就行注意开启 WSL2 或 Hyper-V 后端。有一点要提醒如果用的是 Docker Desktop 的 Windows 环境go2rtc 的容器网络会走 NAT和摄像头通信时要注意网段问题Linux 环境可以开 host 网络模式少很多麻烦。检查完版本之后我习惯先建一个独立的目录把配置文件和容器绑定的目录都放进去这样后面备份、迁移都很清晰mkdir -p /opt/go2rtc cd /opt/go2rtc这个目录在启动容器时会挂载进容器内部config 文件、日志、临时文件都在里面不会污染宿主机。2.2 镜像拉取与加速配置说句实话go2rtc 的镜像本身很小但国内拉 Docker Hub 镜像排队的情况大家也懂有时一条docker pull alexxit/go2rtc能卡十分钟进度条纹丝不动。这不是网络故障是镜像仓库的连通性问题解决办法是给 Docker 配置镜像加速器。打开/etc/docker/daemon.jsonWindows 下是 Docker Desktop 的设置界面把加速地址写进去{ registry-mirrors: [ https://docker.m.daocloud.io, https://hub-mirror.c.163.com, https://mirror.ccs.tencentyun.com ] }改完重启 Dockersudo systemctl restart docker加速地址的可用范围变化很快如果发现某个地址失效直接删掉换成新的就行。如果是在云厂商的服务器上优先去控制台拿他们提供的专属加速地址稳定性和速度都是最好的。2.3 两种部署方式docker run 与 docker composego2rtc 官方镜像叫alexxit/go2rtc部署方式有两种。第一种是三行命令快速启动docker run -d \ --name go2rtc \ --restart unless-stopped \ -p 1984:1984 \ -p 8554:8554 \ -p 8555:8555/udp \ -v /opt/go2rtc/go2rtc.yaml:/config/go2rtc.yaml \ alexxit/go2rtc端口说明1984 是 Web 管理界面和 API 端口WebRTC 播放会用到8554 是 go2rtc 自带的 RTSP 服务端口8555/UDP 是 WebRTC 的媒体通道端口。容器启动后打开http://服务器IP:1984就能看到管理界面。第二种是用 Compose 文件适合需要长期维护、配置较多的情况。先写一个docker-compose.ymlservices: go2rtc: image: alexxit/go2rtc container_name: go2rtc restart: unless-stopped network_mode: host volumes: - /opt/go2rtc/go2rtc.yaml:/config/go2rtc.yaml注意这里我用的network_mode: host也就是直接把容器网络挂在宿主机上go2rtc 监听端口和访问摄像头都像在宿主机本地操作一样。好处很明显WebRTC 的 UDP 端口不用一个个映射摄像头如果和宿主机在同一网段通信毫无障碍。但 host 模式在 Docker Desktop 的 Windows/Mac 上支持不完整所以这两个平台还是用第一种docker run加-p映射端口的方式。启动命令docker compose up -d跑起来之后先看下日志确认没有报错docker logs -f go2rtc正常的话日志里会打印出监听端口和 WebRTC 初始化信息然后浏览器访问管理界面就能看到 go2rtc 的首页。2.4 配置文件和启动验证go2rtc 的配置文件是 YAML 格式默认路径在容器内的/config/go2rtc.yaml。首次启动时如果文件不存在go2rtc 会自动创建一个带默认配置的文件出来。我习惯先手动建好把基础的log和webrtc配置放进去log: level: info webrtc: listen: :8555log.level默认是 info调试的时候可以改成 debug能打印出每个流的详细状态。webrtc.listen指定媒体端口保持和 Docker 映射的 8555/udp 一致即可。配置好之后在管理页面右上角应该能看到 go2rtc 的版本号和服务状态。到这里部署环境就算搭好了下一节开始接入摄像头。3. 多协议摄像头接入实战go2rtc 接入视频源的核心就是配置文件的streams字段结构很简单key: valuekey 是你给这个流起的名字value 是视频源地址。可以写 RTSP、RTMP、HLS、HTTP-FLV、MJPEG 地址也可以用ffmpeg:前缀让内置 FFmpeg 拉本机摄像头或其他设备。下面从协议选型开始讲再把海康大华这类常见设备的配置挨个过一遍。3.1 常见视频流协议及其适用场景开始配之前先花一分钟理清这些协议之间的关系选错了后面会走很多弯路。协议传输方式延迟浏览器支持适用场景RTSPTCP/UDP RTP200ms 级不支持原生播放摄像头/录像机首选协议RTMPTCP1-3s不支持原生播放推流、老旧系统兼容HLSHTTP TS 切片5-15s原生支持iOS/Android移动端、大范围分发WebRTCUDP SRTP500ms原生支持浏览器端低延迟实时预览MJPEGHTTP JPEG 帧200-500ms标签原生支持低端设备、嵌入式页面你可能会问为什么不直接把摄像头接到 NVR 录像机再用 NVR 的客户端看因为 NVR 的客户端大多要求装插件或者只支持自家生态无法统一接入多品牌设备。go2rtc 的意义就在于“桥接”RTSP 进来WebRTC 出去浏览器零插件直接看。3.2 海康、大华等摄像头接入配置下面用实际的配置文件演示。假设我有两个摄像头一台海康、一台大华把它们接入 go2rtcstreams: hik_front: - rtsp://admin:password192.168.1.64:554/Streaming/Channels/101 hik_front_sub: - rtsp://admin:password192.168.1.64:554/Streaming/Channels/102 dahua_entrance: - rtsp://admin:password192.168.1.65:554/cam/realmonitor?channel1subtype1这里有几个经验要点。第一海康的 URL 中/101是通道 1 主码流/102是通道 1 子码流。主码流分辨率高、码率高用于录像存储子码流分辨率低、码率低用于实时预览。我建议在 go2rtc 里尽量用子码流预览因为 WebRTC 走 UDP高码率在主码流上容易引起卡顿如果你需要观看清晰画面那就用主码流但要保证摄像头到 go2rtc 主机的网络带宽足够。第二大华的 URL 里subtype1表示子码流subtype0是主码流。它家早期有些固件对 URL 长度和特殊字符比较挑剔如果发现拉流失败优先检查?和有没有被 YAML 转义。YAML 里这么长的地址我一般直接加引号包起来避免特殊字符解析出错。第三如果你手头的摄像头品牌比较偏不确定 RTSP 地址格式可以用 ONVIF 探测。go2rtc 的 Web 管理界面上有一个添加源的功能输入摄像头 IP、用户名、密码它可以直接用 ONVIF 协议发现设备并自动生成拉流地址省去手动拼 URL 的麻烦。配置修改完在 Web 管理界面上刷新一下hik_front、dahua_entrance这些流应该都能看到预览画面。go2rtc 界面自带播放器点进任意一个流就能直接播放同时有 WebRTC 和 HLS 两个播放选项。3.3 浏览器低延迟预览WebRTC 登场如果只是能在页面上看到画面其实传统方案也能做到go2rtc 真正拉开差距的是 WebRTC 预览。在管理界面点击流的 WebRTC 播放实测延迟可以做到 300ms 左右基本是“所见即所得”云台转动、人走过来几乎感觉不到延迟。这对于远程看门口快递、看车间设备状态、看宠物体验比 HLS 那种 5 秒起步的延迟强太多。WebRTC 的原理简单说就是浏览器和 go2rtc 之间建立一个基于 UDP 的加密媒体通道视频帧以极低延迟实时传输。但 UDP 穿透 NAT 是个常见问题——如果你的 go2rtc 部署在带防火墙的服务器上需要确保 UDP 端口 8555 是开放的。WebRTC 传输失败最常见的表现是管理界面能看到流信息但点播放一直转圈。排查思路是先到浏览器开发者工具的 Console 里看有没有 ICE 错误如果没有明显的报错大概率是 UDP 端口被防火墙拦截了放行 8555/udp 就好。3.4 扩展玩法OBS、USB 摄像头与 Home Assistantgo2rtc 不止能接网络摄像头。如果你有一个 USB 摄像头或者树莓派的 CSI 摄像头模块可以用内置 FFmpeg 把它拉进流媒体服务streams: usb_cam: - ffmpeg:/dev/video0/dev/video0是 Linux 系统里 USB 摄像头对应的设备文件。这个特性在做智能小车、桌面监控、视频会议实验的时候特别好用不需要单独跑一套 FFmpeg 转流程序go2rtc 全部接管。另一个玩法是配合 OBS。OBS 可以抓取 go2rtc 输出的 RTMP 或 WebRTC 流作为素材比如把摄像头画面拉进 OBS 场景里做推流反过来OBS 虚拟摄像头的输出也可以通过 RTMP 推到 go2rtc统一供给其他平台使用。这种“互相嵌套”的组合在直播和多平台分发场景中非常灵活。如果玩 Home Assistantgo2rtc 更是原生集成。在 Home Assistant 的配置里把 go2rtc 地址填进去所有接入的摄像头直接变成 HA 里的 camera 实体再配合自动化规则比如检测到人移动就推送 WebRTC 画面到手机端流畅度和体验都很好。这也是我最初接触这个项目的原因。4. 常见问题与排查技巧实录Docker 部署 go2rtc 整体不复杂但实际跑起来总会在某个环节踩一两个坑。我把这段时间遇到过的典型问题整理成速查表再逐个展开讲。现象可能原因解决办法镜像拉取慢或超时Docker Hub 连通性差配置镜像加速器重启 Docker管理界面打不开容器没起来或端口冲突docker logs go2rtc看日志改端口WebRTC 无法打开UDP 端口未开放放行 8555/udp或改用 host 网络点击播放黑屏但卡住H.265 编码浏览器不支持用子码流或配置 FFmpeg 转 H.264音频没有声音PCM 编码浏览器不支持加装转码为 Opus 的 FFmpeg 配置摄像头拉流闪断摄像头并发拉流受限减少预览路数或降低码率画面卡顿严重码率过高或网络带宽不足改用子码流降低分辨率4.1 搭建与访问类的典型问题先讲镜像拉取的问题。docker pull alexxit/go2rtc卡住不动大概率是没配置镜像加速。这不是网络故障而是 Docker 默认访问 Docker Hub 的链路在国内不稳定。配置好daemon.json里的镜像地址后拉取速度快很多。还有一个临时技巧如果docker pull长时间没反应按CtrlC取消重新执行一次有时第二次会走另一个解析结果。容器跑起来但页面打不开先别急着改配置直接看日志最有效docker ps -a docker logs go2rtc日志里如果显示bind: address already in use说明 1984 端口被其他程序占了。这种情况我遇到过两次一次是机器上有其他 web 服务占用了端口另一次是之前误开了多个容器。解决办法是停掉旧的容器或者把宿主机的映射端口改成别的比如-p 1985:1984。4.2 画面、协议与兼容性问题接入摄像头之后发现画面黑屏但播放器不报错这是最常见的兼容性问题。90% 的情况是编码格式问题摄像头主码流默认输出 H.265浏览器 WebRTC 对 H.265 的支持极差黑屏是必然的。最简单的方案是让 go2rtc 用子码流拉流——子码流一般默认是 H.264。如果你确实需要高画质那就得让 go2rtc 内置 FFmpeg 做硬转码把 H.265 转成 H.264streams: hik_front_h264: - ffmpeg:rtsp://admin:password192.168.1.64:554/Streaming/Channels/101#videocopy#audiocopy但转码非常吃 CPU1 路 1080p 转码差不多要占满 1-2 个核部署机配置不够的话转两路就会明显卡顿。所以我的原则是能走子码流就不转码必须转码就上硬件的显卡加速软件转码只是兜底方案。还有一个容易混的问题就是“大华摄像头一直提示下载插件”那种与浏览器相关的弹窗。直接用浏览器打开大华摄像头的管理页面经常会被要求装插件。这是摄像头厂商自己的网页问题不是 go2rtc 的问题。把大华摄像头接入 go2rtc 后在浏览器里看的是 go2rtc 的页面跟摄像头自带的 Web 页面没有任何关系插件完全不用装。这也算 go2rtc 绕开厂商限制的一个额外好处。4.3 录像与存储规划的实用建议很多人部署完 go2rtc下一步就想接到 NVR 录像。这里分享一个存储规划经验正好对应“海康录像机设置老摄像头存储大文件大的话怎么弄”这类问题。首先要理解录像文件“大”的本质录像文件大小 码率 × 时间。码率越高画面越清楚文件也越膨胀。比如一台 400 万像素摄像头主码流码率约 8Mbps一天 24 小时录像大概是8Mbps ÷ 8 × 3600 × 24 86GB换算成字节一片 4TB 硬盘也就能存 45 天左右。如果换成子码流码率降到 2Mbps同样一块硬盘能存 4 个月。所以存储规划的第一原则是录像存主码流保证取证清晰度预览走子码流保证流畅不卡顿。NVR 接入多品牌摄像头时要手动添加设备 IP并在摄像头端开启 RTSP/ONVIF 协议。如果摄像头和 NVR 不在一个网段先解决网络路由问题再在 NVR 里添加对应网段的摄像头 IP同时留意摄像头 ONVIF 账号权限是否开放。老摄像头固件如果一直找不到流去摄像头官网升级一下固件或者在大华/海康的 SADP 工具里改一下 ONVIF 端口通常能解决。最后说一个我在实际项目中养成的习惯部署 go2rtc 时先在配置文件里分好“组”把不同用途的摄像头用不同名字标记比如front_door、warehouse、parking_lot而不是cam1、cam2。名字起得好后面接 Home Assistant、做自动化、甚至对接 NVR 的时候一眼就能看出哪路是哪台设备排查问题会省很多时间。这套 Docker go2rtc 的方案我用了一年多从最初只是想在家里的浏览器上看摄像头到现在做成了一套可以交付给客户的小型安防预览系统整体非常稳定。最后再分享一个小技巧go2rtc 管理界面上的流列表里每个流旁边有一个调试按钮点进去能看到源地址连接时间、码率、丢包率这些实时数据。出现问题的时候先看这个界面的数据再决定是网络问题、编码问题还是设备问题比盲目改配置高效得多。如果你也因为摄像头协议太乱、网页播放卡顿而头疼照着这篇文章把 go2rtc 跑起来应该能省下一大半折腾的时间。
返回列表