go2rtc实战:用Docker统一管理多品牌IPC摄像头并实现低延迟WebRTC播放
如果你手里同时有海康、大华、宇视或者某个杂牌 IPC 摄像头,大概率体验过这种割裂感:每台设备都有自己的 App,每个品牌都要注册账号、绑定设备,想在一台电脑上同时看所有画面,要么同时开三四个客户端,要么去折腾一台昂贵的 NVR。我去年给家里装了 4 个不同品牌的摄像头后,被这件事反复折磨,最后靠 go2rtc 彻底解决了。
go2rtc 是一个用 Go 写的轻量级流媒体平台,核心能力是把 RTSP、RTMP、ONVIF、HLS 这类五花八门的协议统一接管,再以 WebRTC、MSE、HLS 等方式输出到浏览器或下游系统。配合 Docker 部署,从拉镜像到三路摄像头画面同时出现在浏览器里,我实测十分钟左右就能搞定。这篇文章就讲讲我的部署过程、配置思路,以及踩过的几个有代表性的坑,给准备入门的同学一条可以直接"抄作业"的路线。
1. 三个摄像头三种 App:多协议割裂把我逼到换方案
1.1 go2rtc 到底是个什么角色
先说个容易混淆的点:go2rtc 不是 NVR(网络硬盘录像机),它不做长时间录像存储,它的定位更像是一个"流媒体交换机"或者叫"代理网关"。
从名字也能看出来,go2rtc 的初始目标是把各种来源的流(Source)转成浏览器能直接播放的 WebRTC 流。但发展到现在,它已经变成了一个支持多协议中转的多面手:
- 输入侧支持 RTSP、RTMP、HLS、HTTP-FLV、SRT、ONVIF、MJPEG,甚至一些特定品牌摄像头的私有协议。
- 输出侧支持 WebRTC、MSE、HLS、RTSP、RTMP、MJPEG、HTTP-FLV。
打个比方,你家的摄像头就是各种说着不同方言的人(H.264、H.265、MJPEG),go2rtc 相当于一个同声传译,把所有人的话翻译成你能听懂的普通话(浏览器直接播放的视频流),而且这个翻译过程非常轻量,不做额外的画面处理,纯粹是"搬运+转封装"。
我见过不少人在论坛里问"go2rtc 和 ffmpeg 有什么区别",简单解释:ffmpeg 是一个瑞士军刀,什么都干,但要你自己搭命令行、处理复杂的分支逻辑;go2rtc 则把"拉流-转码-推流"这条链路封装成了声明式配置,大多数场景下你不用写一条 ffmpeg 命令,写几行 YAML 就行。
1.2 和 Zoneminder、MotionEye 相比,我为什么留它
在决定 go2rtc 之前,我其实试过另外几套方案,这里说说我的真实感受。
第一套是 Zoneminder。功能确实重型,支持运动检测、录像回放、多用户权限管理,但对新手非常不友好,配置页面密密麻麻,光是把摄像头加进去就要理解一堆"Monitor/Storage/Source"的概念。我折腾了一个周末,摄像头画面终于出来了,但浏览器播放延迟三四秒,而且系统资源占用居高不下。Zoneminder 适合有专门服务器、愿意花时间深入研究的人,不适合我这种"只想快速看到画面"的场景。
第二套是 MotionEye。它比 Zoneminder 轻量很多,界面也漂亮,基于 Python 开发,Docker 安装很简便。但它对流媒体协议的支持相对单一,WebRTC 这种低延迟方案是没有的,默认走 MJPEG 或 HLS,延迟依然在 1 到 3 秒左右。作为轻量监控界面够用,但如果你想拿它做实时操作(比如云台控制、实时预览),体验会打折扣。
第三套才是 go2rtc。它的优势在我看来非常聚焦:
- 单二进制文件,资源占用极低
- Web UI 配置界面简单,设备状态一目了然
- 原生支持 WebRTC,延迟能压到 0.2 到 0.5 秒
- 能和 Home Assistant 无缝集成
- 配置完全声明式,全部写在 go2rtc.yaml 里
我最后把 go2rtc 作为"取流汇聚层"使用,Zoneminder 和 MotionEye 就不再折腾了。它在我的架构里承担的是"统一接入所有摄像头,并向浏览器和 HA 提供低延迟流"这个核心职责。
1.3 一个配置文件干完所有事
go2rtc 的配置逻辑非常朴素,核心就一个 YAML 文件。你不需要理解复杂的状态机,也不需要记住大量的集群概念,所有流都用
streams
关键字定义。
streams:
camera_living:
- rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101
camera_yard:
- rtsp://admin:password@192.168.1.65:554/cam/realmonitor?channel=1&subtype=0
写完之后,Web UI 上会自动出现两个可点击的画面入口,浏览器点开就能看。这种"写配置—刷新页面—看画面"的反馈链路,是我认为 go2rtc 最吸引人的地方。
2. Docker 部署细节:镜像选择、端口映射与配置挂载
2.1 官方镜像与版本选择
go2rtc 官方提供了 Docker 镜像,仓库名是
alexxit/go2rtc
。我见过有些人从第三方镜像源拉,其实没必要,官方镜像一直维护得很勤快,直接拉最新版就行。
docker pull alexxit/go2rtc:latest
如果你对版本敏感,可以锁定具体的 tag 而不是用 latest,比如
alexxit/go2rtc:1.9.7
。我个人在家庭环境直接用 latest,因为 go2rtc 的版本迭代很快,新版本往往会修复一些摄像头兼容性问题,追新反而省事。当然,生产环境我还是建议锁版本,避免更新到某个不兼容的版本导致业务中断。
镜像大小方面,go2rtc 的镜像只有几十 MB,比一堆包含完整 ffmpeg 静态编译的媒体服务器镜像要小得多,拉取速度非常快。
2.2 docker run 和 docker compose 两种方式实测
先给最直接的 docker run 命令:
docker run -d --name go2rtc \
-p 1984:1984 \
-p 8554:8554 \
-v $PWD/go2rtc.yaml:/config/go2rtc.yaml \
--restart unless-stopped \
alexxit/go2rtc:latest
简单解释下每个参数:
-
-d:后台运行。 -
--name go2rtc:容器命名,方便后续管理。 -
-p 1984:1984:Web 管理界面端口,浏览器访问http://宿主机IP:1984就能看到 UI。 -
-p 8554:8554:RTSP 服务端口,go2rtc 对外提供 RTSP 分发能力时使用。 -
-v $PWD/go2rtc.yaml:/config/go2rtc.yaml:把当前目录下的配置文件挂载到容器内。注意,路径一定要正确,我第一次部署时挂载错了目录,容器一直用默认的空配置启动,页面里啥都没有。 -
--restart unless-stopped:开机自启、异常退出自动重启,这个对长期运行的流媒体服务很关键。
如果你更习惯用 Docker Compose 管理,下面是对应的
docker-compose.yml
:
version: "3.8"
services:
go2rtc:
image: alexxit/go2rtc:latest
container_name: go2rtc
restart: unless-stopped
ports:
- "1984:1984"
- "8554:8554"
volumes:
- ./go2rtc.yaml:/config/go2rtc.yaml
environment:
- TZ=Asia/Shanghai
这里加了一个
TZ
环境变量,设置时区。如果你后续要给流加时间水印或者做录像分段,时区不对会导致时间显示完全错乱。
2.3 端口和网络模式的选择逻辑
go2rtc 默认主要监听两个端口:1984 和 8554。1984 是 Web UI 和 HTTP 播放端口,8554 是 RTSP 服务端口。如果你还需要接收 RTMP 推流或者走 SRT 协议,那就得额外把 1935、8888、8555 等端口也映射出来。
这里有一个关键选择:用桥接网络还是 host 网络模式。
我最初用的是标准的桥接模式(也就是上面 docker run 的写法,通过
-p
映射端口)。这个模式在大多数场景下都能正常工作,特别是你只需要通过 IP 地址直连摄像头 RTSP 流时。
但如果你要用 ONVIF 自动发现功能,强烈建议改用 host 网络模式。原因是 ONVIF 的设备发现依赖 UDP 组播,而 Docker 的 bridge 网络默认对组播支持不佳,摄像头发到局域网组播地址的响应包,容器里的 go2rtc 根本收不到。
host 模式的 compose 写法:
version: "3.8"
services:
go2rtc:
image: alexxit/go2rtc:latest
container_name: go2rtc
restart: unless-stopped
network_mode: host
volumes:
- ./go2rtc.yaml:/config/go2rtc.yaml
host 模式下不需要写
ports
映射,因为容器直接使用宿主机网络栈,监听的是宿主机端口。这种方式的优点是组播、UPnP 等局域网发现协议都能正常工作,缺点是端口冲突由你自己负责,比如宿主机已经占用了 1984 端口就会有问题。
我的建议是:如果你的摄像头品牌和型号已知,直接在配置文件里写 RTSP 地址,用桥接模式就够了,简单干净;如果你买的是一堆杂牌摄像头,不知道 RTSP 取流路径是什么,想靠 ONVIF 自动发现,那还是用 host 模式省心。
3. 摄像头接进来:RTSP 直连与 ONVIF 两种接入方式
3.1 各品牌 RTSP 取流地址格式汇总
接入摄像头第一道坎,就是搞清楚各家的 RTSP 取流地址。不同的厂商、不同的型号,取流路径格式差异很大。我把自己试过的几类典型格式整理成表,大家可以直接参考:
| 品牌 | 主码流 RTSP 地址 | 子码流 RTSP 地址 |
|---|---|---|
| 海康威视 |
rtsp://用户名:密码@IP:554/Streaming/Channels/101
|
rtsp://用户名:密码@IP:554/Streaming/Channels/102
|
| 大华 |
rtsp://用户名:密码@IP:554/cam/realmonitor?channel=1&subtype=0
|
rtsp://用户名:密码@IP:554/cam/realmonitor?channel=1&subtype=1
|
| 宇视 |
rtsp://用户名:密码@IP:554/unicast/c1/s0/live
|
rtsp://用户名:密码@IP:554/unicast/c1/s1/live
|
| TP-Link |
rtsp://用户名:密码@IP:554/stream1
|
rtsp://用户名:密码@IP:554/stream2
|
这里有个概念要理解:主码流和子码流。
主码流的分辨率高(通常是 1080p 或 4K),码流大,适合录像存档和全屏查看;子码流分辨率低(通常是 720p 甚至 CIF),码流小,适合多画面预览和手机流量环境。在 go2rtc 里,我通常会为同一台摄像头配置两个入口,一个叫
xxx_main
,一个叫
xxx_sub
,需要低延迟实时预览时用子码流,需要看细节时切换主码流。
不建议所有场景都直接拉主码流。如果你有 4 到 8 路摄像头全部走主码流,局域网带宽和 go2rtc 的内存压力都会明显上升。
3.2 在 go2rtc.yaml 里定义多个摄像头
下面是我的一个实际配置文件片段,包含三台不同品牌的摄像头:
streams:
hik_living_main:
- rtsp://admin:MyPass123@192.168.1.64:554/Streaming/Channels/101
hik_living_sub:
- rtsp://admin:MyPass123@192.168.1.64:554/Streaming/Channels/102
dahua_yard_main:
- rtsp://admin:Pass2024@192.168.1.65:554/cam/realmonitor?channel=1&subtype=0
unv_gate_sub:
- rtsp://admin:GatePass@192.168.1.66:554/unicast/c1/s1/live
写完保存后,重启容器让配置生效:
docker restart go2rtc
接着浏览器打开
http://宿主机IP:1984
,左侧菜单栏就能看到你这几个流的名字。点进去,它会自动用最优的方式开始播放。
这里有个小技巧:如果发现某个流无法播放,先看 Web UI 对应流名称旁边的状态指示灯。如果是红色,说明 go2rtc 拉流失败了,这时把鼠标悬停在流名称上可以看到报错信息,比如"unauthorized"(用户名密码错误)、"connection refused"(摄像头端口不通)或者"timeout"(摄像头无响应)。这些报错信息比你在浏览器控制台里瞎猜有用得多。
3.3 ONVIF 自动发现与接入
如果你的摄像头支持 ONVIF 协议(现在绝大多数 IPC 都支持),go2rtc 还能通过 ONVIF 协议自动解析出摄像头的 RTSP 地址。
配置方式也很简单:
streams:
unkown_camera:
- onvif://admin:MyPass123@192.168.1.100:80
这里的
192.168.1.100:80
是摄像头的 HTTP 管理端口,不是 RTSP 端口。go2rtc 会通过 ONVIF 协议向摄像头发起设备探测,自动获取到它的 RTSP 取流地址并开始拉流。
这个功能在什么场景下特别有用?就是你买了一个杂牌摄像头,说明书丢了,用扫描工具扫到了 IP,却不知道 RTSP 路径的时候。直接用 ONVIF 方式让 go2rtc 自己去"问"摄像头要地址,省去你翻手册的时间。
另外,go2rtc 的 Web UI 里还集成了一个"扫描局域网 ONVIF 设备"的功能。进到 Web UI 的配置页面,它会自动发现局域网内支持 ONVIF 的设备列表,你只需要输入设备的用户名密码就能快速添加。这个功能在 host 网络模式下使用效果最好,原因上一章说过,组播包在 bridge 模式下容易丢失。
3.4 无法通过 ONVIF 自动发现时的兜底方案
ONVIF 自动发现虽然方便,但也不是万能的。有些厂商为了"系统安全",把 ONVIF 功能在默认固件里关闭了,或者只开放给自家 App 使用。碰到这种情况,我通常先用
nmap
扫一下摄像头 IP 的常见端口:
nmap -p 80,554,8000,8899 192.168.1.100
看
554
(RTSP)和
80
(HTTP)端口是否开放。如果 554 开了,直接搜该品牌的 RTSP 取流路径;如果只有 80 开了,那试试 ONVIF 方式;如果连 80 都没开,只能把摄像头恢复出厂设置,用厂商默认端口再试。
这招虽然不是百分之百有效,但能快速排除"摄像头压根没开 RTSP 功能"这个可能。
4. 浏览器里看实时画面:WebRTC、MSE、HLS 三种链路怎么选
4.1 延迟和兼容性对比
go2rtc 最让我惊艳的部分,不是它能把 RTSP 流转成别的协议,而是它提供的低延迟播放链路。下面是拿同一台海康摄像头实测得到的三种播放方式的延迟表现:
| 播放方式 | 平均延迟 | 浏览器兼容性 | 适用场景 |
|---|---|---|---|
| WebRTC | 0.2~0.5 秒 | Chrome、Edge、Firefox、Safari 都支持 | 实时预览、云台控制、需要"所见即所得"的场景 |
| MSE | 1~3 秒 | Chrome、Edge、Firefox、Safari 都支持 | 普通监控画面查看 |
| HLS | 5~10 秒 | 全平台,包括 iOS Safari | 兼容性优先、延迟不敏感的场景 |
我第一次在 go2rtc 的 Web UI 里点开摄像头,画面几乎是"即点即出"的,心里确实震了一下。因为在这之前,我用的 MotionEye 走 HLS 播放,点开画面之后还要转圈两三秒,拖动窗口时画面还会卡顿。WebRTC 的体验完全不同,点开就出画面,拖动浏览器窗口几乎没有撕裂感。
WebRTC 为什么能这么低延迟?简单说,它用 UDP 传输视频数据,跳过了 TCP 的拥塞控制和重传逻辑,而且采用 P2P 的架构思路,服务端只负责转发必要的数据包。UDP 丢包确实会导致画面短暂花屏,但在局域网环境下,丢包率极低,WebRTC 的低延迟优势可以完全发挥。
4.2 go2rtc 怎么自动选择播放链路
你可能会问:既然 WebRTC 这么好,是不是所有场景都强制用 WebRTC?
其实不用你操心,go2rtc 在浏览器里做了一套自动降级机制。当你在 Web UI 点击一个流时,go2rtc 的 Web 页面 JavaScript 会按照下面这个优先级尝试:
- 优先尝试 WebRTC,如果浏览器和网络环境支持。
- WebRTC 连接失败(比如 WebRTC 需要的 UDP 端口被防火墙挡了),自动降级到 MSE。
- MSE 也不行(比如流编码格式是 MKV 封装且浏览器不认),最终退到 HLS。
这套自动降级的逻辑做得很成熟,用户基本无感。因为 go2rtc 会在同一个 HTTP 端口上同时提供 WebRTC、MSE 和 HLS 的访问入口,浏览器段脚本会根据握手结果自己决定用哪条路。
另外,MSE 和 HLS 的区别也值得一提。MSE(Media Source Extensions)是浏览器提供的一个 JavaScript API,go2rtc 把 RTSP 流转成 fMP4 片段通过 HTTP 推给浏览器,延迟比 HLS 低不少;HLS 则是把流切成一个个 TS 文件,通过 m3u8 索引文件播放,切片和加载都天然引入延迟。iOS 的 Safari 对 MSE 支持有限,所以在 iPhone 上访问时,go2rtc 往往会自动落到 HLS,这一点在移动端监控场景要留意。
4.3 在 Web UI 里一次看多路画面
go2rtc 的 Web UI 支持多路画面同时打开,这个功能很实用。
点击 UI 左上角的"+"号,把需要的流一个个添加进去,它就会以网格布局同时渲染多个播放器。我在部署 4 个摄像头之后,就是靠这个功能实现了"一张屏看全屋"。
但有一点需要注意:多路同时播放时,每一路默认都走 WebRTC,每一路都要占用一份 UDP 端口和网络资源。如果局域网带宽不够,建议在 UI 里把部分摄像头切换成 MSE 或 HLS,牺牲一点延迟,换取整体流畅度。
5. 折腾过程中的典型坑位:编码格式、URL 转义与网络模式
5.1 H.265 编码导致浏览器黑屏
这是我遇到的最大一个坑,也是用 go2rtc 接摄像头最容易踩的问题。
现在的摄像头,尤其是海康和大华的新款,默认主码流编码可能是 H.265(HEVC)。H.265 比 H.264 在同等画质下码率更低、存储更省,但对于浏览器播放来说是个麻烦。
Chrome 和 Firefox 对 H.265 的支持一直不完整,Chrome 在不少平台上只支持硬件解码的 H.265,如果硬件不支持,就会直接黑屏或者报错。Safari 对 H.265 支持得倒是很全面,但你不能要求全家都用 iPhone 看监控吧。
我当时的现象是:画面能出声音(如果有音频的话),但视频区域纯黑,右上角有报错日志。后来我把摄像头主码流的编码格式从 H.265 改成 H.264,问题立刻消失。
解决方案有三个,按推荐程度排序:
- 在摄像头后台管理界面,把视频编码改为 H.264。这个最彻底,浏览器兼容性最好,缺点是会增大一点存储占用。
- 在 go2rtc 里对指定流启用转码,把 H.265 转成 H.264。这需要给 go2rtc 额外配置 ffmpeg,缺点是转码吃 CPU,低功耗设备上跑不动。
- 保持 H.265 不管它,强制在支持 H.265 的浏览器上播放,比如 Safari 或者开启了硬件解码的 Edge。
我现在的做法是:主码流保持 H.264,因为我要在浏览器和 Home Assistant 里看;子码流如果摄像头支持 H.265,我就让它保持,反正子码流大部分时候只是为了多画面预览,清晰度要求不高。
转码配置可以参考下面这样(前提是你手动指定了 ffmpeg 路径):
streams:
camera_h265_main:
- rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101
- ffmpeg:camera_h265_main#video=h264#hardware
这条配置的意思是:先从
camera_h265_main
拉流,然后用 ffmpeg 把视频转成 H.264。
#hardware
表示优先尝试硬件转码(Intel Quick Sync 或者 NVIDIA NVENC),能大幅降低 CPU 占用。实际部署时,需要确认你的 ffmpeg 编译版本支持对应的硬件加速库。
5.2 密码里的特殊字符把取流地址干废了
第二个坑来自密码中的特殊字符。
我有一台摄像头的密码是
Pass@123
,它在摄像头后台里工作正常,但当我把它写进 go2rtc.yaml 时:
streams:
camera_1:
- rtsp://admin:Pass@123@192.168.1.64:554/Streaming/Channels/101
结果发现 go2rtc 一直报认证失败。原因很好理解——URL 解析器把第一个
@
后面的内容当成了主机地址,实际解析到的主机是
123@192.168.1.64
,这自然连不上。
解决办法是进行 URL 编码。在 RTSP 串里,以下字符需要特别注意:
| 字符 | URL 编码 |
|---|---|
@
|
%40
|
:
|
%3A
|
/
|
%2F
|
#
|
%23
|
?
|
%3F
|
&
|
%26
|
所以正确的写法是:
streams:
camera_1:
- rtsp://admin:Pass%40123@192.168.1.64:554/Streaming/Channels/101
更省心的做法是:给摄像头单独建一个"仅供流媒体访问"的低权限账号,密码里只包含字母和数字,避免一切转义烦恼。我在管理海康设备时,会在用户管理里新建一个
stream
用户,密码设成
stream2024
,把取流权限给它就够了,这样即使 go2rtc 配置泄露,也不至于让攻击者拿到摄像头的管理员权限。
5.3 Docker 网络模式选错,连不上摄像头
我在文章开头提到过桥接模式和 host 模式的差异。这里再补充一个典型的"选错网络模式"的排查案例。
有一次我把 go2rtc 部署在一台跑着很多容器的服务器上,为了方便端口管理,用了默认的 bridge 模式。之后访问 go2rtc 的 Web UI 正常,但添加摄像头之后一直拉流失败,报错是 "connect timeout"。
排查到最后发现,那台服务器上还有其他容器占用了大量内网 IP,Docker 的 bridge 网关与局域网段之间存在路由冲突,导致容器内发出的到摄像头 IP 的数据包被错误地路由到了 Docker 虚拟网卡上,而不是走宿主机局域网网卡。
这种情况排查起来很隐蔽,因为你在宿主机上用
ping
、
curl
都正常,但容器里就是连不通。我的建议是:
- 如果 go2rtc 只是单一服务,直接上 host 网络模式,省去端口映射和 NAT 的问题。
-
如果你必须在 bridge 模式下跑,注意看 Docker 的
bip(bridge IP 网段)配置,尽量选一个偏离内网网段的子网,比如 Docker 默认的172.17.0.0/16和家里的192.168.1.0/24不会冲突,但如果你改过 Docker 网段,就要小心了。
5.4 画面卡顿:子码流和主码流的实战取舍
还有一个很常见的卡顿问题,和网络带宽关系不大,纯粹是选择错误。
我最初把所有摄像头都配置成主码流接入,结果在 Web UI 里同时看四路画面时,画面会周期性卡顿。一开始我以为是 CPU 不够,后来用
docker stats
一看,go2rtc 的 CPU 占用不到 15%,内存也正常。
后来查了 cam 的实时码率才发现:四路 1080p 主码流的码率加起来接近 15 Mbps,而我的无线链路实际稳定吞吐只有 10 Mbps 左右。问题出在无线 AP 上。
解决方式很简单:把多画面预览的流从主码流切换到子码流。1080p 主码流改成 720p 子码流之后,四路总码率降到 3 Mbps 左右,画面立刻流畅了。
最终我的配置模式是:
- Web UI 默认使用子码流,保证多路预览不卡。
- 需要看细节的时候,在 UI 里手动切换到主码流入口。
6. 更进一步:Home Assistant 集成、推流分发与资源控制
6.1 和 Home Assistant 的无缝对接
如果你用 Home Assistant(以下简称 HA),go2rtc 的价值会翻倍。
go2rtc 的作者 AlexxIT 本身就是 HA 的知名集成作者,二者兼容性做得非常好。在 HA 里通过侧边栏添加 go2rtc 集成,填入 go2rtc 的 IP 和端口,HA 就能直接发现 go2rtc 里配置的所有摄像头流。
之后你可以把 go2rtc 里的流当成普通 camera 实体用:
camera:
- platform: generic
name: LivingRoom
still_image_url: http://192.168.1.10:1984/api/frame?src=hik_living_sub
stream_source: http://192.168.1.10:1984/api/stream?src=hik_living_sub
这样 HA 的仪表盘里就能实时显示摄像头画面,而且延迟非常低。配合 HA 的自动化,可以实现有人移动时把对应摄像头的画面推送到电视或手机上。
go2rtc 作为 HA 官方推荐的 stream 替代组件,一个重要原因是它天然支持 WebRTC,HA 自带的 stream 组件在某些平台上无法低延迟播放 H.265 流,而 go2rtc 可以在中间做协议转换和转封装。
6.2 把 go2rtc 的流推送到第三方平台
go2rtc 不仅能"拉",还能"推"。比如你希望把某一路摄像头的画面推送到云端直播平台,只需要在流配置后面追加一个 RTMP 推流地址:
streams:
camera_hik:
- rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101
- rtmp://your-rtmp-server.com/live/cam1
go2rtc 会一边从摄像头拉流,一边把同一路流转推到 RTMP 服务器。这个功能在做"公共场所视频监控分享"或者"跨区域视频汇聚"时非常实用。
需要注意的是,推流到外网平台时,你的上行带宽是瓶颈。1080p 主码流推流至少需要 4 Mbps 上行,如果带宽不够,还是推子码流吧。
6.3 资源占用与长期运行观察
最后说一下很多人关心的资源占用问题。
go2rtc 本身非常轻量。在我的测试机上(一台 N5105 软路由),同时跑 4 路 1080p 子码流和 2 路主码流,不做转码时,go2rtc 的 CPU 占用率稳定在 5% 到 10%,内存占用约 120 MB。这个负载对大多数软路由和小主机来说毫无压力。
如果启用了 H.265 转 H.264 的转码,CPU 占用会显著上升,具体取决于分辨率和帧率。在我的 N5105 上,单路 1080p 的 H.265 转 H.264 大约要吃 30% 左右的 CPU,如果你有 4 路以上的转码需求,建议考虑带 Intel Quick Sync 的 CPU,或者干脆在摄像头端把编码格式改成 H.264。
长期运行方面,我用 go2rtc 连续跑了三个多月,容器内存有缓慢增长的趋势,但没有出现明显的泄漏或者崩溃。Docker 自带的内存限制选项可以加上一层保护:
services:
go2rtc:
image: alexxit/go2rtc:latest
mem_limit: 512m
restart: unless-stopped
如果容器因为内存超限被杀掉,Docker 会自动重启,保证服务可用性。
6.4 我现在的完整配置模板
分享一个我现在还在用的完整配置模板,供大家参考:
log:
level: info
streams:
hik_living_main:
- rtsp://stream:stream2024@192.168.1.64:554/Streaming/Channels/101
hik_living_sub:
- rtsp://stream:stream2024@192.168.1.64:554/Streaming/Channels/102
dahua_yard_main:
- rtsp://stream:stream2024@192.168.1.65:554/cam/realmonitor?channel=1&subtype=0
unv_gate_sub:
- rtsp://stream:stream2024@192.168.1.66:554/unicast/c1/s1/live
all_cameras:
- hik_living_sub
- dahua_yard_main
- unv_gate_sub
最后这个
all_cameras
很有意思,它不是一个实际的摄像头,而是把多路流组合成一个新的流,在 Web UI 里点开它,go2rtc 会自动以多画面模式呈现所有子流。这样一个入口就能集中展示所有画面,比我手动逐个添加方便多了。
如果你也想搭建一套统一的多品牌摄像头监控系统,go2rtc 绝对值得你花一个下午试试。我个人实际用下来的体会是:它把"接入摄像头"这个原本繁琐的过程压缩到了"写几行 YAML",而且 Web UI 自带的排错信息也相当直观,真的推荐自己上手跑一遍,比看我文章有用得多。
更多推荐

所有评论(0)