go2rtc:用Docker统一摄像接入,WebRTC低延迟看监控
家里装了三四个摄像头,牌子还不一样——客厅是海康,门口是大华,车库里一个杂牌 RTSP,再加上一个树莓派上接的 USB 摄像头。以前想看监控,得装两三个不同厂商的 App,电脑上还要开一个 VLC 手动拉流,手机里更是塞了一堆推送通知。后来我在 Docker 里部署了 go2rtc,这套混乱局面才算结束。
go2rtc 是个开源流媒体网关,天生就是干“多协议接入 + 统一输出”这件事的。它能把不同品牌、不同协议的摄像头流(RTSP、RTMP、HTTP-FLV、HLS、MJPEG、WebRTC、ONVIF 等)全部收集起来,再转化成浏览器、播放器、NVR、Home Assistant 都能直接消费的格式。最爽的是,它的 Web 界面里点一下就能用 WebRTC 看实时画面,延迟不到半秒,真正做到了“打开浏览器就能看监控”。
这篇文章我会从零开始,把自己实际部署 go2rtc 的过程、踩过的坑、优化过的细节全部写出来。不管你是家里有几个摄像头想统一看,还是想给 Home Assistant 或 Frigate 提供一个稳定的流媒体源,这篇都能直接照着抄。
1. go2rtc 到底是什么,凭什么解决多协议难题
1.1 一个中心,统一所有摄像头流
市面上摄像头品牌五花八门,协议也是各说各话。海康大华走的是 RTSP,但 URL 格式完全不同;一些国产 WiFi 摄像头只支持 RTMP 推流;老旧的 USB 摄像头在 Linux 下是 V4L2 设备;还有些方案需要 ONVIF 自动发现。你不可能为每一种摄像头都装一个客户端。
go2rtc 的思路很简单:在中间放一个“翻译官”,每种摄像头说各自方言,go2rtc 负责把它们翻译成统一的普通话。它内部会针对不同源类型调用不同的采集器,RTSP 源直接用内置 RTSP 客户端拉流,RTMP 源用 RTMP 客户端,V4L2 设备则直接读设备节点。采集到的原始流统一进入内部媒体管线,再由你选定的协议输出。
这带来的直接好处是,你不用再关心每个摄像头自己的 App 和插件。你只需要在 go2rtc 的配置文件里告诉它“摄像头 1 的地址是 xxx,协议是 RTSP;摄像头 2 走 RTMP;树莓派摄像头读 /dev/video0”,它就会把这些流全部接管。之后所有下游系统,无论是浏览器、VLC、Frigate 还是 Home Assistant,都只跟 go2rtc 一个节点打交道。
我家里目前接了 5 路摄像头,平时同时开着两三个浏览器标签页看实时画面,go2rtc 的内存占用稳定在 80MB 左右,非常轻量。这也是我选择它而不是重型 NVR 方案(比如 Blue Iris、ZoneMinder)的核心原因——够用、轻、省心。
1.2 为什么用 Docker 部署,而不是直接装二进制
go2rtc 官方提供 Linux 二进制、Windows 可执行文件、macOS 包,但我会毫不犹豫推荐 Docker 部署,原因主要有三个。
第一,环境隔离。go2rtc 依赖 ffmpeg,不同版本的 ffmpeg 或者缺少特定编译选项会直接影响某些协议(比如硬解 H.265、WebRTC 转码)的表现。如果直接装在宿主机上,你得处理 ffmpeg 版本冲突、系统库依赖,折腾一圈下来头都大了。Docker 镜像里已经把 go2rtc、ffmpeg、所有运行库打包好了,拉下来就能跑。
第二,升级和回滚简单。Docker 部署时,升级就是改一下镜像 tag 再 restart;如果新版本出了问题,改回旧 tag 重新启动就回滚了。我在 go2rtc 更新到 1.9.x 后遇到过一个 WebRTC 偶发断流的问题,当时一行的镜像 tag 改回 1.8.x 就恢复了,整个过程不到两分钟。
第三,配置文件和数据卷分离。go2rtc 的所有配置就是一个 YAML 文件,通过 Docker 挂载进容器,我可以直接用宿主机上的编辑器改配置,改完重启容器生效。换个环境部署时,带上这个 YAML 文件就相当于把整个服务迁移走了。Docker 化之后,我在一台小主机上同时跑了 go2rtc、Frigate、Home Assistant,彼此互不干扰,这也是“自建流媒体服务”最舒服的一种姿势。
2. 环境准备与 Docker 部署实操
2.1 宿主机 Docker 环境检查
开始之前先确认你宿主机上的 Docker 是好的。Linux 上用
docker --version
看版本,再跑一下
docker ps
确认 daemon 在运行。如果是 Windows 用 Docker Desktop,最常见的问题是启动时报 “virtualization support not detected”,这个基本是 BIOS 里虚拟化没开,或者 Windows 功能里的 Hyper-V/WSL2 没有启用。我的建议是:Windows 上安装 Docker Desktop 时选择 WSL2 后端,在“控制面板 -> 启用或关闭 Windows 功能”里勾选“虚拟机平台”和“适用于 Linux 的 Windows 子系统”,重启后再试。
还要确认 Docker Compose 插件在不在。现在 Docker 基本都自带
docker compose
命令了,你可以在终端敲一下
docker compose version
验证。没有的话,直接用
docker run
方式部署也可以,我下面两种方法都会讲。
另外留意一下端口占用情况。go2rtc 默认会用到 1984(Web 界面和 API)、8554(RTSP 输出)、8555(WebRTC over UDP),如果我后面配了 RTMP 输出,还会用到 1935。我在第一次部署时就是没注意,宿主机上有个服务占了 8554,导致 go2rtc 的 RTSP 输出端口一直起不来,所以建议先执行
ss -lntup | grep -E '1984|8554|8555|1935'
(Windows 用
netstat -an
)确认这些端口是空的。
2.2 docker run 一键启动 go2rtc
先创建一个放配置文件的目录,比如
~/go2rtc
,然后写一个最简单的配置文件
go2rtc.yaml
。这里我们先只留一个壳,后面再往里面填摄像头:
# ~/go2rtc/go2rtc.yaml
log:
level: info
streams: {}
然后执行 docker run:
docker run -d \
--name go2rtc \
--restart unless-stopped \
-e TZ=Asia/Shanghai \
-p 1984:1984 \
-p 8554:8554 \
-p 8555:8555/udp \
-v ~/go2rtc/go2rtc.yaml:/config/go2rtc.yaml \
alexxit/go2rtc
逐行解释一下参数。
-d
是后台运行,
--name
给容器起名,
--restart unless-stopped
保证 Docker 重启、宿主机重启之后容器能自动拉起,这一点对看监控这种 7x24 小时的服务非常关键。
-e TZ=Asia/Shanghai
设置时区,否则日志时间会和本地时间差 8 个小时,排查问题的时候很容易误导。端口映射那一行,
1984
是 Web 管理界面和 API 端口,
8554
是 RTSP 输出端口,
8555/udp
是 WebRTC 要用到的 UDP 端口,这里必须写成
8555:8555/udp
,不能漏掉 udp 后缀,否则 WebRTC 通话会建立不了。最后
-v
把宿主机上的配置文件挂载到容器里的
/config/go2rtc.yaml
。
启动完成后,浏览器访问
http://你的宿主机IP:1984
,能看到一个带有 “Streams” 和 “Play” 按钮的界面,部署就成功了。我第一次看到这个界面的时候挺意外,没想到一个小工具居然自带这样好用的播放器页面。
2.3 docker compose 管理配置
如果打算长期使用,我强烈建议用 docker compose 来管理。它可以把上面的所有参数固化到文件里,换机器部署时一条命令搞定。
docker-compose.yml
示例:
services:
go2rtc:
image: alexxit/go2rtc:latest
container_name: go2rtc
restart: unless-stopped
network_mode: host # 需要根据实际情况决定
environment:
- TZ=Asia/Shanghai
volumes:
- ./go2rtc.yaml:/config/go2rtc.yaml
- ./media:/media
ports:
- "1984:1984"
- "8554:8554"
- "8555:8555/udp"
- "1935:1935"
注意,我在上面示例里先写了
network_mode: host
又写了 ports,实际使用中这两者只能选一个。如果宿主机是 Linux,而且你不介意 go2rtc 直接占用宿主机端口,用 host 网络模式反而最省心——不需要映射端口,WebRTC 走 host 网络时各种地址协商也最不容易出问题。但如果宿主机是 Docker Desktop(Windows/Mac),host 模式支持有限,建议用 bridge 加 ports 映射的方式,也就是我在
docker run
演示里的那种。
配置写好后,在
docker-compose.yml
所在目录执行
docker compose up -d
就能启动。以后看日志用
docker compose logs -f go2rtc
,改配置后重启用
docker compose restart go2rtc
,统一且方便。
3. 摄像头接入配置详解
3.1 海康、大华等 RTSP 摄像头接入
接入 RTSP 摄像头是 go2rtc 最常用的场景。在
go2rtc.yaml
的
streams
段里,每个 key 就是这条流的名字,value 可以是单个 URL,也可以是 URL 数组。下面是我实际在用的配置:
streams:
living_room:
- rtsp://admin:your_password@192.168.1.64:554/Streaming/Channels/101
front_gate:
- rtsp://admin:your_password@192.168.1.108:554/cam/realmonitor?channel=1&subtype=0
海康的 RTSP 地址格式通常是
rtsp://用户名:密码@IP:554/Streaming/Channels/101
。最后一位
101
表示通道 1 主码流,
102
表示通道 1 子码流。大华则是
rtsp://用户名:密码@IP:554/cam/realmonitor?channel=1&subtype=0
,
subtype=0
是主码流,
subtype=1
是子码流。规划的时候,我一般主码流只用来录像或大屏查看,预览和手机端反而更推荐用子码流,能大幅降低带宽和解码压力。
这里有几个实操中的细节要特别留意。第一,密码里如果有
@
、
:
、
/
这种特殊字符,必须做 URL 编码,比如
@
要写成
%40
。我踩过这个坑,第一次配置门禁摄像头时密码里有
@
,go2rtc 日志一直报认证失败,排查了半天才发现是 URL 解析时把
@
当成了分隔符。
第二,可以把多个 URL 同时配置在一条流下面,go2rtc 会按顺序尝试:
living_room:
- rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101
- ffmpeg:rtsp://admin:password@192.168.1.64:554/Streaming/Channels/102#video=copy#audio=copy
第一行用自带 RTSP 客户端,兼容性不好时,第二行会走 ffmpeg 去拉流,相当于一个自动降级机制。
#video=copy#audio=copy
表示不转码,直接复用原始编码,节省 CPU。
第三,如果摄像头支持 ONVIF,可以在 streams 里写
onvif://admin:password@192.168.1.64
,go2rtc 会自动探测该设备的 RTSP 地址。我第一次接入一个杂牌摄像头时查不到 RTSP 地址,就是用这个方法自动发现的,省了不少事。
3.2 RTMP、HTTP-FLV、HLS 等其他协议接入
不是所有摄像头都支持 RTSP,特别是那些主打手机 App 的 WiFi 摄像头,往往只提供 RTMP 推流或 HTTP-FLV 拉流能力。go2rtc 对这类源同样直接支持。配置方式基本一致:
streams:
air_camera:
- rtmp://192.168.1.50/live/camera_stream
web_camera:
- http://192.168.1.88:8080/live.flv
hls_camera:
- http://192.168.1.66/hls/live.m3u8
mjpeg_camera:
- http://192.168.1.77/video_stream.mjpg
有意思的是,go2rtc 把协议前缀作为自动识别的依据,你不用额外告诉它这是 RTMP 还是 HTTP-FLV,它会根据 URL 前缀去调用对应的采集器。对于只提供 TS over HTTP 的摄像头(很多运营商定制摄像头是这样的),可以直接填
http://.../live.ts
,go2rtc 也能处理。
如果你手头有个设备只能推流到指定 RTMP 服务器,甚至可以把 go2rtc 的 RTMP 输出地址(
rtmp://go2rtc的IP:1935/任意路径
)直接配置成设备的推流目标。这样就把一个纯推流设备变成了一条可随时拉取的标准流,非常灵活。
3.3 树莓派 CSI / USB 摄像头(V4L2)接入
用树莓派做监控也是常见玩法,尤其是树莓派 4B 或 5 搭配 CSI 摄像头模块,或者插一个 USB 摄像头。这类设备在系统里是 V4L2 设备节点,比如
/dev/video0
。go2rtc 支持直接读取 V4L2 设备:
streams:
pi_cam:
- v4l2:device=/dev/video0
这里有个容器与宿主机交互的关键点:Docker 容器默认看不到宿主机设备,必须显式把设备传进去。在 docker run 里加:
--device /dev/video0:/dev/video0
在 docker compose 里对应:
devices:
- /dev/video0:/dev/video0
如果是 CSI 摄像头(比如树莓派官方摄像头模块),V4L2 节点可能体现在
/dev/video0
,但底层走的是 bcm2835-v4l2 驱动,内核先加载
bcm2835-v4l2
模块才会有
/dev/video0
出现。如果设备节点不存在,先
sudo modprobe bcm2835-v4l2
加载模块。用 USB 摄像头就简单得多,插上就能识别,一般就是
/dev/video0
或
/dev/video1
,不确定可以用
ls /dev/video*
查看。
接入后 go2rtc 会自动向摄像头申请一帧画面作为预览,Web 界面里点击播放时会走 WebRTC 实时流。像智能小车、巡检机器人这种场景,摄像头画面通过 go2rtc 转出去后,上位机直接用 WebRTC 或 HTTP-FLV 拉流,体验比直接拿 OpenCV 连串口或者 UVC 设备稳定得多。
3.4 WebRTC 低延迟播放与 STUN 配置
go2rtc 最让我惊艳的能力,就是内置 WebRTC 播放。传统方案里,浏览器原生不能直接播放 RTSP,通常做法是转 HLS 或 RTMP,延迟至少 3~10 秒。go2rtc 则原生实现了一个 WebRTC 网关,浏览器和 go2rtc 之间通过 WebRTC 协商音视频轨道,端到端延迟能压到 0.2~0.5 秒。这个延迟在监控场景里非常关键——门口有人按门铃,你要在手机上看实时画面,晚一秒钟体验都差很多。
要实现 WebRTC 播放,除了 1984 端口外,必须保证 8555 这个 UDP 端口可以从浏览器侧访问到 go2rtc 所在主机。如果你在局域网内,浏览器直接访问
http://192.168.x.x:1984
就能播放。如果要从外网访问,建议配合反向代理(比如 Nginx 或 Caddy)转发 1984 端口,同时还要把 UDP 8555 端口也映射出去。
go2rtc 默认使用内置的 NAT 探测机制,但如果跨网络、跨 NAT 访问频繁失败,可以在配置里指定 STUN 服务器:
webrtc:
stun:
- stun.l.google.com:19302
- stun.cloudflare.com:3478
STUN 的作用是帮助双方发现自己的公网地址和端口映射关系,在 WebRTC 的连接协商里属于标准做法。配置了 STUN 之后,跨网络访问的成功率会明显提升。我实测过,在手机 4G/5G 网络下访问家里 go2rtc 的 WebRTC 画面,如果没有 STUN 配置,经常会出现“连接中”转圈;加上 STUN 后基本几秒内就能出画面。
4. 多协议输出与周边系统联动
4.1 浏览器直接看多路画面
go2rtc 的 Web 界面在
http://宿主IP:1984
,首页会列出所有配置好的 streams 名称。点击任意一条流,它会自动尝试用 WebRTC 方式播放;如果浏览器不支持 H.265(Safari 新版支持,Chrome 不支持),界面会提示无法解码。页面右上角有 “Play all” 之类的小按钮(不同版本 UI 略有差异),可以一次性把多条流同时打开,形成类似监控墙的效果。
实际部署后你会发现,把浏览器标签页固定成监控墙这件事真的可以替代专用的监控客户端。我爸妈家装了两台摄像头,我给他们浏览器里存了一个书签,打开就是两路画面,他们再也不用去 App 里找“直播”按钮了。
如果界面里没有立即出画面,优先检查浏览器控制台有没有 WebRTC 相关报错,以及 8555 UDP 端口通不通。不要一上来就怀疑是摄像头的问题,我遇到过好几次“页面不出画面”的折腾,最后发现都是端口映射少了
udp
后缀。
4.2 把 go2rtc 作为统一流媒体源对外输出
go2rtc 不仅仅自己看,它还可以作为统一流媒体源对外提供 RTSP、HLS、RTMP、HTTP-FLV。举个例子,我在 go2rtc 里接入了一条海康 RTSP 流,命名
living_room
,那么对外输出格式就自动变成:
-
RTSP:
rtsp://宿主IP:8554/living_room -
HLS:
http://宿主IP:1984/api/hls/living_room.m3u8 -
HTTP-FLV:
http://宿主IP:1984/api/playlist/living_room.flv -
MJPEG 预览图:
http://宿主IP:1984/api/frame?src=living_room
这个能力让 go2rtc 成了一个“万能摄像头代理”。我在实际项目中,有一个老的录像机(NVR)只能识别 RTSP 源,而新买的摄像头只有 RTMP 输出,我就在 go2rtc 里把 RTMP 流转成 RTSP,然后让 NVR 去拉 go2rtc 的 8554 端口。整个链路里 go2rtc 就充当了一个协议转换器,老设备和新设备无缝衔接。
对外输出还有一个好处:当多个客户端同时拉取同一条流时,go2rtc 内部只向摄像头请求一份视频流,然后在内存里分发。这样摄像头不会因为并发访问过多而变卡。早前我用 VLC 直接拉摄像头 RTSP,两个窗口同时看就明显卡,换成 go2rtc 之后,同一个画面开五六个客户端都没压力。
4.3 接入 Home Assistant 与 Frigate
go2rtc 最主流的用法之一,是作为 Home Assistant 和 Frigate 的流媒体中转层。Frigate 是一个开源的 NVR + AI 物体识别系统,它自己内置了 go2rtc(新版本),但如果你的 Frigate 与 go2rtc 分开部署,也可以手动指定。
在 Home Assistant 里添加 go2rtc 的流,可以在配置里加:
camera:
- platform: generic
name: living_room
still_image_url: "http://192.168.1.10:1984/api/frame?src=living_room"
stream_source: "http://192.168.1.10:1984/api/stream?src=living_room"
这样 Home Assistant 的仪表盘上就能直接显示 go2rtc 管理的摄像头画面,同时仍然由 go2rtc 负责实际的拉流和协议转换。
Frigate 配置更是简单,在
frigate.yml
里加:
go2rtc:
streams:
living_room:
- rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101
Frigate 会直接把 go2rtc 作为其内部流媒体引擎来使用。如果你想单独跑一个 go2rtc 实例给多个服务共用,只要保持端口和配置文件独立即可。我家的方案就是 go2rtc 负责所有摄像头接入,Home Assistant 负责自动化联动(比如检测到人时推送截图),Frigate 负责录像和 AI 识别,三者各司其职,中间全靠 go2rtc 串起来。
5. 性能调优与长稳运行经验
5.1 硬件加速与转码参数
如果你只做“拉流 + 转发”,go2rtc 默认就做流拷贝,CPU 占用非常低。但一旦涉及转码(比如把 H.265 转成 H.264 给浏览器看,或者把多路画面合流),CPU 就会吃紧。多路 4K 摄像头同时转码时,一颗普通 x86 CPU 很容易被打满。
go2rtc 使用 ffmpeg 做转码,你可以在配置里指定硬件加速方式:
ffmpeg:
bin: ffmpeg
hw: vaapi
不同的硬件平台对应的
hw
值不一样:Intel 集显用
vaapi
(QSV 也可以尝试
qsv
),NVIDIA 独显用
cuda
,树莓派上用
v4l2m2m
,macOS 上用
videotoolbox
。我在一台 J4125 的小主机上,用 VAAPI 硬解转码 3 路 1080p 摄像头,CPU 占用不到 15%,体感非常明显。
如果摄像头被 go2rtc 拉起来后再交给下游系统(比如 Frigate)做检测,你还可以通过 ffmpeg 参数输出指定分辨率、帧率,减轻下游系统的压力。比如:
front_gate:
- ffmpeg:rtsp://admin:password@192.168.1.108:554/cam/realmonitor?channel=1&subtype=0#video=scale=1280:720#video=fps=15
这里
#video=scale=1280:720
表示把画面缩放到 720p,
#video=fps=15
限制帧率到 15。经过这样的处理,Frigate 做 AI 识别时速度会快很多,因为要处理的像素量直接降下来了。
5.2 并发访问优化与码流选择
摄像头本身也是一个嵌入式设备,性能和带宽都有限。如果你的摄像头被多个系统(go2rtc、NVR、厂商 App 同时)拉流,它很容易因为连接数过多而拒绝服务。我的建议是:摄像头侧只对 go2rtc 开放,go2rtc 作为唯一入口。
在这个架构下,你还可以在 go2rtc 里为同一条流配置主码流和子码流两条源:
driveway:
- rtsp://admin:password@192.168.1.108:554/cam/realmonitor?channel=1&subtype=1
driveway_high:
- rtsp://admin:password@192.168.1.108:554/cam/realmonitor?channel=1&subtype=0
预览和手机端用
driveway
(子码流),录像或大屏用
driveway_high
(主码流)。摄像头本身的编码负担会更小,网络带宽占用也更低。有些品牌的摄像头主码流是 4K,子码流是 720p,差距非常大。
5.3 让 go2rtc 长期稳定运行
监控类的服务讲究“开了就不动”,所以有几个稳定性细节值得设置。首先是容器的
restart: unless-stopped
,这个前面说过,作用是 Docker 重启后容器自动拉起。其次是日志轮转,Docker 默认会把容器日志无限存下去,时间长了会把磁盘写满,可以在
daemon.json
里配置日志轮转,或者单容器运行时加
--log-opt max-size=10m --log-opt max-file=3
。
再就是配置文件的备份习惯。go2rtc 的配置就一个 YAML 文件,非常轻量,定期复制到安全位置即可。我一般在改配置前都会先
cp go2rtc.yaml go2rtc.yaml.bak
,万一改错了,一条命令就能回滚。
还有一个容易被忽略的点:时区。Docker 容器默认 UTC 时间,日志和录像时间戳都会偏 8 小时。记得在 compose 里加
TZ=Asia/Shanghai
,这样 Web 界面里的时间就和本地一致。这个细节看起来小,但等你回头翻日志排查问题时,能省很多冤枉时间。
6. 常见问题与排查技巧实录
6.1 RTSP 反复断流、重连
症状是画面播几秒就卡住,go2rtc 日志里不断出现
reconnect
或
timeout
。最常见的原因是网络不稳定或者摄像头限制了并发连接数。解决思路分两层:先看 go2rtc 日志,确认是不是在反复重连;然后在 go2rtc 的摄像头 URL 上加参数,强制走 TCP 传输:
living_room:
- ffmpeg:rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101#transport=tcp
另外,如果摄像头本身只能支持 1~2 个并发连接,而你又同时开着厂商 App 和 go2rtc,必然导致互踢。这种情况我只能说,尽量让 go2rtc 做唯一拉流方,其他端统一从 go2rtc 取流。
6.2 Docker 端口映射导致 Web 界面打不开
最常见的原因有三类:
一是防火墙问题。Linux 宿主机的 ufw/firewalld 没有放行 1984 端口,或者容器端口映射没生效。先用
curl http://127.0.0.1:1984
在宿主机上验证,如果本机都访问不了,多半是容器没起来或配置有问题;本机能访问、局域网其他机器访问不了,那就是防火墙。
二是端口占用。Docker 端口映射失败时容器依然能启动,只是映射不生效,日志里会有
port is already allocated
的报错。解决方法是先
docker logs go2rtc
看一下,再检查宿主机端口占用情况。
三是 Docker Desktop 的端口转发问题。Windows / macOS 上 Docker Desktop 运行在虚拟机里,网络链路多了一层,有时候端口映射偶尔抽风。重启 Docker Desktop 通常就好了。
6.3 WebRTC 画面黑屏或一直转圈
WebRTC 黑屏是 go2rtc 使用中比较高频的问题,原因也五花八门,我按排查顺序整理如下:
先看 8555 UDP 端口是否可达。WebRTC 传输媒体数据走 UDP,TCP 端口映射通畅不代表 UDP 没问题。在浏览器按 F12,切到 Network 或 Console,如果看到
ICE failed
或者
candidate gathering
报错,大概率就是 UDP 不通。
再看编码格式。H.265(HEVC)在 Chrome/Firefox 里无法硬解,如果摄像头是 H.265 主码流,页面可能黑屏且无声音。解决方法是让 go2rtc 转码成 H.264,或者在流配置里强制使用子码流(通常子码流是 H.264)。
最后检查 WebRTC 相关配置。是否配置了 STUN,是否处于复杂的 NAT 环境。局域网内一般没问题,跨网访问时多配几个 STUN 服务器更稳妥。
6.4 其他高频问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 摄像头认证失败 | 用户名密码错误,或密码含特殊字符未编码 |
核对凭据,对
@ : /
等字符做 URL 编码
|
| 画面花屏/撕裂 | 网络丢包严重,或传输协议默认 UDP |
改为 TCP 传输:
#transport=tcp
|
| 子码流拉流失败 | 摄像头限制并发,或子码流地址错误 |
核对地址中
Channels/102
、
subtype=1
是否正确
|
| 浏览器播放无声 | 摄像头音频编码为 G.711,或 AAC 参数不兼容 |
在流配置中加音频转码参数,如
#audio=opus
|
| 容器一重启配置丢失 | 配置文件未正确挂载 |
确认宿主机路径与容器
/config/go2rtc.yaml
的映射
|
| Docker Desktop 启动失败 | 虚拟化未开启 / WSL2 未启用 | BIOS 开启虚拟化,安装 WSL2,重启 Docker Desktop |
碰到问题,我的习惯是第一时间看日志。go2rtc 的日志信息非常直白,比如
cannot open media source
表示拉流失败,
webrtc: peer disconnected
表示 WebRTC 连接断开。日志时间配上时区设置,再用
docker logs -f go2rtc
实时观察,大多数问题都能在几分钟内定位。
最后再分享一个小技巧:如果某个摄像头源不稳定,但你又不想让整个服务重启,可以在 go2rtc 的 Web 界面里直接把那条流删掉再重新加载。go2rtc 对运行中的会话管理比较灵活,改配置后不一定非要重启容器,很多时候只需要对单条流执行重新加载就够了。我在调整摄像头角度、改密码、更新固件之后,就不需要重启整个容器,直接在 Web 界面上操作即可,这是它比传统 NVR 顺手很多的地方。
更多推荐
所有评论(0)