ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

用Docker部署go2rtc:打造多协议摄像头统一接入的流媒体平台

2026/9/15 21:32:42 拓冰建站 浏览量
用Docker部署go2rtc:打造多协议摄像头统一接入的流媒体平台 最近几年摄像头几乎是白菜价海康、大华这些专业监控品牌也有不少两三百块的家用型号再加上树莓派 CSI 摄像头、ESP32-S3 USB 摄像头、手机摄像头各种协议混在一起真心让人头疼。家里或者小工作室想把这些设备统一接到同一个流媒体平台里看过去要么用各自的 App要么折腾 ffmpeg 写一堆进程脚本维护起来又烦又容易挂。后来我试着用 Docker 部署了 go2rtc吭哧吭哧调了一下午把不同类型的摄像头全部接了进去浏览器、VLC、手机都能看延迟还能稳在 0.5 秒以内。这篇就把我的部署过程、踩过的坑、调过的参数以及整套多协议流媒体平台的搭建思路完整写下来想搞摄像头统一接入的朋友可以直接照着抄作业。1. 为什么偏偏是 go2rtc多协议接入这件事真不是 ffmpeg 能轻松搞定的1.1 先弄明白 go2rtc 到底是干什么的很多第一次接触 go2rtc 的人会把它当成又一个 ffmpeg 封装其实它做的事比 ffmpeg 更“专一”。go2rtc 是一个用 Go 写的轻量级流媒体服务核心思路概括成一句话就是一个地址进多个协议出。源端不管是 RTSP、RTMP、HTTP-FLV、MJPEG、ONVIF还是 SIP它都能接输出端则统一提供 WebRTC、HLS、HTTP-FLV、MJPEG 和裸 TS 这些协议让不同的播放端自己挑合适的方式来看。这里的关键在于go2rtc 默认只做流复制proxy不做转码。意思就是摄像头推过来什么样它就转发成什么样只是换了个传输协议的壳所以延迟极低CPU 占用也非常小。我拿一台树莓派 4B 跑 go2rtc 容器同时转四路 1080p 的 RTSP 流内存占用不到 200MBCPU 也就偶尔跳一下。如果真需要转码它也能调用 FFmpeg但绝大多数场景下根本用不上。打个比方go2rtc 就像小区门口的快递驿站。驿站不管你的快递是顺丰、圆通还是京东送来的它只负责按楼栋分好你按自己的方式去取就行——你不用管快递公司之间互不互通。摄像头各自说方言没关系go2rtc 这个驿站能把方言翻译成大家都能听懂的普通话再按你的要求分发出去。1.2 和 ffmpeg / ZLMediaKit 对比go2rtc 赢在哪先看 ffmpeg。ffmpeg 是强大的命令行工具不是常驻服务。你要用 ffmpeg 把一路 RTSP 转成 HLS就得一直启动一个进程挂在那里摄像头多了就得写脚本来管理一堆进程还要处理崩溃重启、端口分配、鉴权这些问题。能人是能人但它把一个本来很重的工程问题丢给了你让你自己造轮子。再看 ZLMediaKit。ZLMediaKit 在功能赛道上确实比 go2rtc 全比如完善的推拉流鉴权、GB28181、SRT、WebRTC 网关等但配置项太多部署也更重适合有经验的开发者做正式项目。如果只是家里几路监控、小店里几个摄像头或者自建私有流媒体看板ZLMediaKit 就有点杀鸡用牛刀了。go2rtc 的定位恰好填补了中间空白轻量、常驻、多协议、自带 Web UI而且它内置了非常完整的 WebRTC 能力。浏览器可以直接通过 WebRTC 拉流不用装 VLC 插件、不用走 HLS 那套几秒延迟的路径这对实时监控场景来说太香了。另一个加分项是Home Assistant 从某个版本开始已经把 go2rtc 作为默认的流媒体集成之一玩智能家居的人对它应该不陌生。下面这张表是我自己对比后的结论给大家做个选型参考选型部署成本转码能力WebRTC适用场景ffmpeg 脚本低命令行强需额外搭配单路临时转码ZLMediaKit高强支持正式服务、多租户go2rtc极低弱可选ffmpeg原生支持家庭/工作室监控、HA集成商用 NVR看预算厂家封闭一般不开放不想折腾的人2. Docker 部署 go2rtc两种姿势总有一种适合你2.1 最快上手一条 docker run 命令如果你只是想先跑起来看看效果那一条命令就够了。我是在 Ubuntu 服务器上操作的Windows 上用 Docker Desktop 也完全一样docker run -d --name go2rtc --restartalways \ -p 1984:1984 \ -p 8554:8554 \ -p 8555:8555 \ -v /opt/go2rtc/config:/config \ alexxit/go2rtc这个镜像官方就叫alexxit/go2rtc作者就是 go2rtc 的原作者没有乱七八糟的第三方打包优先用它。镜像里已经包含了 go2rtc 主程序和可选的 FFmpeg 组件你不需要在宿主机上装任何东西。端口方面1984 是 Web 管理界面和 API 端口8554 是 RTSP 对外服务端口8555 是 RTMP 对外服务端口。这三个端口建议都映射出来因为你后面既要用浏览器看也可能要让 VLC、手机播放器走 RTSP/RTMP 拉流。挂载配置目录很重要。go2rtc 启动后会在/config下寻找go2rtc.yaml配置文件如果不存在首次启动会自动生成一个默认配置。我把宿主机的/opt/go2rtc/config挂载进去这样以后改配置不用重新做容器直接改宿主机文件再重启容器即可。2.2 进阶配置docker-compose 持久化配置如果你像我一样要长期跑、还要照顾多路摄像头强烈建议用 docker-compose 来管理。下面这个是我实际在用的 compose 文件比单条命令多了日志限制、时区和重启策略version: 3.8 services: go2rtc: image: alexxit/go2rtc:latest container_name: go2rtc restart: unless-stopped ports: - 1984:1984 - 8554:8554 - 8555:8555 environment: - TZAsia/Shanghai volumes: - /opt/go2rtc/config:/config - /opt/go2rtc/recordings:/recordings logging: driver: json-file options: max-size: 10m max-file: 3先解释几个容易被忽略的点TZAsia/Shanghai用来解决容器日志时间比本地慢 8 小时的问题不然你看 go2rtc 日志里流断线的时间点总要对半天。第二个挂载目录/recordings是给录像功能用的。go2rtc 新版本自带了简单的录制能力配置好模板后可以把流自动按天存成 MP4我后面专门说。logging限制日志大小是因为 go2rtc 在摄像头频繁断开时会疯狂刷日志。不限制的话Docker 的 json-file 日志文件能撑爆你的磁盘。启动命令就一句docker compose up -d更新镜像时也很方便docker compose pull docker compose up -d。2.3 跑起来之后先确认两件事容器起来后别急着配摄像头先做两个验证第一浏览器访问http://服务器IP:1984能看到 go2rtc 的 Web 管理界面。界面很直观左侧是流列表右侧是播放器顶部有添加流的入口。能看到界面就说明最基本的外部访问没问题。在 Ubuntu 这类服务器上尤其记得检查防火墙。很多朋友容器起了、端口映射也配了但网页就是打不开最后发现是 ufw 默认把 1984 端口挡了sudo ufw allow 1984/tcp sudo ufw allow 8554/tcp sudo ufw allow 8555/tcp第二调用一下 API 验证服务本身是健康的curl http://localhost:1984/api/streams正常情况下会返回一个 JSON 对象里面是当前配置的流列表。如果返回空数组{}说明配置还没加任何流这就是下一步要做的事。3. 摄像头接入从海康/大华到树莓派一次说清3.1 RTSP 协议接入最通用的方式RTSP 是监控摄像头的通用语言99% 的 IP 摄像头都支持。go2rtc 接 RTSP 流的配置格式特别简单在go2rtc.yaml里加一个流的名字然后列出源地址就行streams: yard: - rtsp://admin:your_password192.168.1.64:554/Streaming/Channels/101这里有一个很容易搞错的点不同品牌的 RTSP 地址格式不一样。我整理了一个常见对照表都是我实测过或者帮朋友配过的品牌RTSP 地址格式海康威视rtsp://用户名:密码IP:554/Streaming/Channels/101101为主码流102为子码流大华rtsp://用户名:密码IP:554/cam/realmonitor?channel1subtype0subtype0主码流1子码流TP-LINKrtsp://用户名:密码IP:554/stream1stream1主码流stream2子码流宇视rtsp://用户名:密码IP:554/ media/video1主码流和子码流的区别要理解清楚。主码流分辨率高、码率大适合录像和回放子码流分辨率低、码率小适合实时预览和多路同屏。go2rtc 接入时我一般主码流和子码流分开配成两个不同的流名比如yard_main和yard_sub预览用小码流录像用大码流互不干扰。配完以后可以在 Web UI 里点对应流名再点界面上的播放按钮能出画面就说明通了。如果不出画面先用 VLC 在电脑上验证这个 RTSP 地址能不能直接打开。VLC 能开说明地址没问题问题出在 go2rtcVLC 也开不了那就先去搞定摄像头本身的地址。3.2 ONVIF 自动发现与激活摄像头很多摄像头你根本不知道它的 RTSP 地址格式这时候走 ONVIF 就省事多了。ONVIF 是监控设备的标准协议只要摄像头支持go2rtc 就可以通过 ONVIF 探测到设备支持的码流和 RTSP 地址自动帮你填好不用再猜。在配置里加 ONVIF 源格式如下streams: camera_find: - onvif://admin:your_password192.168.1.108/onvif/device_servicego2rtc 拿到这个 ONVIF 地址后会自动去设备能力集里找 RTSP 主码流和子码流地址然后把它当普通流一样代理输出。实际效果就是你只填了一个 ONVIF 地址结果camera_find这个流能直接播放省去了手动找Streaming/Channels/101这种路径的功夫。如果摄像头支持 PTZ 云台ONVIF 接入后还顺便可以控制云台这是额外福利。这里必须提醒一句海康/大华的新摄像头第一次到手是收在“未激活”状态下的直接写 ONVIF 地址会报鉴权错误。解决办法是先用浏览器访问摄像头的 IP进网页管理后台按提示给摄像头设置管理员密码和加密方式激活完成后ONVIF 和 RTSP 才能正常工作。我遇到过太多次“为什么我配置没问题就是连不上”的情况最后全卡在激活这一步。3.3 特殊设备接入树莓派 CSI / USB 摄像头 / 手机摄像头专业监控摄像头好办难办的是那些业余摄像头。我也折腾过树莓派 OV5647 CSI 摄像头、ESP32-S3 USB 摄像头、手机摄像头这里把方案一并说清楚。树莓派 CSI 摄像头接 go2rtc核心是先把 CSI 信号转成 RTSP 或 MJPEG 流。我用的方法是先让树莓派跑一个轻量的 RTSP 服务把摄像头画面推上去再用 go2rtc 统一拉流。比如用libcamera配合v4l2rtspserver或者用一张rtsp-simple-server容器把树莓派变成一路 IP 摄像头。具体命令不展开思路就是别让 go2rtc 直接和 CSI 设备驱动打交道中间加一层标准 RTSP 桥接稳定性好很多。ESP32-S3 USB 摄像头更轻量通常直接输出的是 MJPEG 流网上有不少现成固件烧录后摄像头就成为一个 HTTP MJPEG 服务。go2rtc 可以直接接streams: esp_cam: - http://192.168.1.50:8080/stream接 MJPEG 源有个问题需要注意MJPEG 是一帧一张 JPEG 图片没有真正的压缩编码帧率和码率都不适合走 WebRTC 低延迟传输。go2rtc 对这种源一般会走转码或直接按 MJPEG 方式输出浏览器看没问题但延迟会比原生 RTSP 高。如果你追求低延迟还是建议用支持 H.264 硬编码的设备。手机摄像头是最灵活的应急方案。装一个“IP Webcam”之类的 App把手机变成一个 RTSP/MJPEG 流服务器go2rtc 同样可以接入。我出差时经常用一台闲置手机临时盯家里宠物App 里直接开启 RTSP 服务go2rtc 配好后人在外面也能从统一入口查看不用开手机 App。4. 多协议输出让浏览器、VLC、小程序各看各的4.1 三大输出协议选型WebRTC、HLS、HTTP-FLVgo2rtc 的好玩之处在于同一个流不同播放端可以用不同协议去拉。我后端只接入一路 RTSP输出端却可以同时给浏览器走 WebRTC、给苹果设备走 HLS、给老播放器走 RTSP互不影响。三个主流协议的选型我自己的经验是这样协议延迟浏览器兼容适用场景WebRTC0.2~0.5秒原生支持无需插件实时监控、门铃画面、低延迟预览HLS3~8秒Safari原生其他需hls.js分享链接、苹果生态、回放HTTP-FLV1~3秒需 flv.js 等库小程序、自研播放器、低延迟直播RTSP无附加延迟不支持VLC、NVR 等专业播放WebRTC 是 go2rtc 的招牌。因为它是 P2P 的可以把音频视频的 UDP 包直接让浏览器原生解码所以延迟能做到极低。go2rtc 的 Web 界面里点播放默认就是走 WebRTC我实测同一局域网下海康摄像头的画面延迟大概在 0.3 秒左右和手机直接看摄像头 App 的延迟类似基本够用。HLS 兼容性最强适合把监控画面分享给不常折腾的人。比如我给家人发一个 HLS 链接用 iPhone 自带的 Safari 浏览器打开就能看不用装任何软件。代价是延迟会到几秒甚至更高。HTTP-FLV 现在用得没以前多了不过在小程序/Web 播放器生态里还有一席之地。如果手上有自己写的播放器走 FLV 是可以的。go2rtc 的 Web UI 里每个流右侧都会列出当前可用的播放地址直接复制走就行不用死记接口格式。4.2 延迟调优从秒级到毫秒级关键在哪很多朋友兴致勃勃接好流一测延迟两三秒就开始怀疑 go2rtc 不行。其实延迟的大头根本不在 go2rtc而在链路里的三个环节摄像头编码延迟、协议封装延迟、播放器缓冲延迟。摄像头编码延迟是硬件层面的。很多家用摄像头默认开了图像增强、夜景降噪这些算法会占掉不少编码时间让画面出来就慢半拍。同一台摄像头你把它从“全彩模式”切到“普通模式”延迟可能直接降 100 多毫秒。还有的摄像头默认输出 25 帧帧率低导致画面看起来卡顿感知上也会觉得“很延迟”。如果你的摄像头后台能调节帧率尽量开到 15 帧以上。协议封装延迟是我们可以直接调的部分。如果你用 HLS 播放延迟取决于切片长度切片越短延迟越低但会有兼容性问题。go2rtc 里可以通过配置调整 HLS 的切片时长和切片数量官方参数叫hls建议切片控制在 1 秒左右能在兼容性和延迟之间平衡。播放器缓冲延迟最容易被忽略。VLC 默认缓冲很大拉 RTSP 流时显示的画面可能比真实时间慢一两秒这不能全怪 go2rtc。你在 VLC 里把网络缓存调小一些延迟就有明显改善。我最常用的延迟测试方法手机开秒表 App放在摄像头画面里然后拿播放器看同一块秒表对比播放画面和真实秒表的差距。测出来的就是端到端延迟。同一套设备我用 WebRTC 测大约 0.3 秒切到 HLS 后变成 4 秒多差了十几倍——所以实时预览千万别用 HLS。5. 实战搭建一个能用的多摄像头监控平台5.1 场景规划与完整配置示例拿一个我实际搭过的例子来说身边朋友小区门口的便利店要用一套监控设备如下店门口一个海康 POE 摄像头主码流 1080p子码流 720p店内一台大华摄像头走无线收银台后面一台树莓派 4B用的 OV5647 CSI 摄像头一部闲置安卓手机临时看仓库角落我的规划很简单所有设备接入 go2rtc统一在 1984 端口页面里看树莓派作为 go2rtc 宿主机跑 Docker 容器录像不要求实时只给门口的回看存成 MP4远程访问走路由器端口转发。最终go2rtc.yaml配置长这样log: level: info streams: gate_main: # 海康门口主码流录像用 - rtsp://admin:Passw0rd192.168.1.64:554/Streaming/Channels/101 gate_sub: # 海康门口子码流实时预览用 - rtsp://admin:Passw0rd192.168.1.64:554/Streaming/Channels/102 store_main: - rtsp://admin:admin123192.168.1.108:554/cam/realmonitor?channel1subtype0 counter_cam: - http://192.168.1.88:8080/stream # 树莓派CSI经v4l2rtspserver桥接后的MJPEG phone_cam: - http://192.168.1.66:8080/video # 手机IP Webcam的MJPEG地址 record: template: /recordings/{name}_{2006-01-02}.mp4 # 按日期存储文件名带流名和日期这里有个比较关键的设计思路预览和录像分离。门口的摄像头我配了两条流gate_main是大码流主码流专门用于录制回放保证清晰度gate_sub是小码流给实时预览用多开几个页面也不占太多带宽。如果不分开每次预览都拉主码流看两三个窗口就卡成 PPT。配置写好保存重启容器加载新配置docker restart go2rtc然后打开 Web UI左侧能看到 5 个流挨个点播放确认每路都能出画面。我调试时喜欢先点 WebRTC 播放能看到画面后再用 VLC 拉一下同一路流的 RTSP 地址验证多协议是否同时可用。5.2 验证效果延迟、并发、稳定性配置跑通之后我做了三项验证也算是这套方案上线前的体检。第一项是延迟测试。店里那台大华摄像头我开了 WebRTC 播放用秒表法实测延迟约 0.4 秒完全满足店员“人进店能立刻看清脸”的需求。接着我试了 HLS 播放延迟大概 4 秒用于回放可以实时监控就不适合了。第二项是并发测试。我同时开三个 WebRTC 页面、两个 HLS 页面、一台手机用 VLC 拉 RTSP树莓派的 CPU 占用依然很低只有摄像头网络占用明显。说明 go2rtc 本身不是瓶颈瓶颈在于摄像头侧能同时输出的连接数。第三项是稳定性。这套系统实际运行了两个月中间只有一次路由器断电导致所有流断掉恢复网络后 Docker 容器自动重启所有流又自动重连了没有人为干预过。靠谱。这里提醒一句如果你要长期录像磁盘空间要提前留足。1080p 主码流一天下来一般录 12 到 24 GB我的录制模板按天切文件然后写了个简单的 cron 脚本定期清理 7 天以前的录像避免磁盘被塞满。6. 常见问题与避坑指南6.1 摄像头拉不了流先按这个顺序排查按下面前五步走完我敢说八成问题都能找到先确认摄像头 IP 通不通ping 摄像头IPping 不通就去查网络和 POE 供电。再确认 RTSP 端口是否可达telnet 摄像头IP 554不通就检查摄像头后台有没有开启 RTSP 功能。然后验证用户名密码和地址格式用 VLC 直接拉流测VLC 能通而 go2rtc 不通再查 go2rtc 日志。接着检查摄像头连接数上限有些家用摄像头只允许同时 4 路或 8 路连接当你开着手机 App、VLC 再让 go2rtc 拉超出限制就直接断流。最后查摄像头时间同步摄像头时间和服务时间相差太大会导致某些鉴权流程失败表现为“偶尔能连大部分时间断”。排查过程中最忌讳到处乱改配置。我习惯把每一步验证的结果记下来至少能快速定位是网络层、协议层还是认证层的问题。6.2 Docker 运行时的坑如果用的是 Docker Desktop启动容器时经常碰到virtualization support之类的报错。这个方向在 Windows 上通常是 BIOS 里的虚拟化没开或者 Hyper-V 组件没装完整。我个人的建议是如果只是玩一下Windows 上跑 Docker Desktop 没问题要是打算长期做监控服务还是租个 Linux 小服务器或翻出一台旧电脑装 Ubuntu省心太多。另一个高频问题是镜像拉取慢。alexxit/go2rtc 镜像不算大但在某些网络环境下拉取速度很折磨人。解决办法是在 Docker 的 daemon 配置里加上国内能用的镜像加速器不同地区可用的加速站点也不太一样选一个自己实际测下来速度能接受的即可。还有端口被占用问题。1984、8554、8555 这几个端口不特殊宿主机上如果恰好有服务占用了容器启动会直接失败。我排查时习惯先netstat -tlnp | grep 1984看一眼。最后是配置挂载权限。Windows 下 Docker Desktop 挂载本机目录有时会因为文件权限不对导致 go2rtc 读不到配置。这时候把挂载目录的访问权限放开一些或者直接把配置放到容器内部复制出来改都能解决。6.3 几个提高幸福感的小技巧讲几个用下来体验提升最明显的技巧不保证每个版本都有但这套逻辑是对的。一是用 go2rtc 的 API 快速判断流是否活着。浏览器直接访问http://IP:1984/api/streams返回的 JSON 里每个流会有状态信息比自己盯画面猜要高效得多。二是接入 Home Assistant。go2rtc 在 HA 里有官方集成配好后在 HA 面板里直接就能看到摄像头画面还能联动自动化比如门口摄像头检测到人自动弹画面到电视上。三是自动录像加上推送提醒。go2rtc 的录制功能配合一些脚本/平台可以在录制启动时发送通知。四是摄像头支持 PTZ 的话ONVIF 接入后在 go2rtc 的 Web UI 里就能直接控制云台方向省了每次去翻原厂 App。最后再分享一个小小的实操体会这套方案我前后跑了半年最大的收获不是省下了几台 NVR 的钱而是把所有摄像头都收敛到了一个入口里接入、查看、录像、分享都变成可程序化的事。以后再有人问我“家里几个摄像头怎么统一看”我都会先问一句——“你试过 go2rtc 吗”