go2rtc 极速上手:零代码把 RTSP 摄像头塞进浏览器,延迟压到 300ms 以内
【免费下载链接】go2rtcUltimate camera streaming application项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc
浏览器直接打开 RTSP 地址,画面卡了 5 秒才出帧、回放满屏马赛克——安防场景里这根本没法忍。go2rtc 是一个零依赖的流媒体网关,把 RTSP 转 WebRTC 这一步全包了:摄像头流进、WebRTC 流出,浏览器原生播放,典型延迟 300ms 以内。读完这篇 go2rtc 部署教程,你会拿到:
- 3 种部署方式,每种都带一条验证命令
- 5 个品牌摄像头的适配配置速查
- 4 种播放姿势 + 3 类高频故障的排查动作
概念锚点:低延迟直播为什么是 WebRTC 的领地
先看四种协议各自的位置,你就明白 RTSP 摄像头浏览器播放为什么绕不开协议转换:
| 协议 | 延迟区间 | 浏览器原生支持 | 传输层 | 典型场景 |
|---|---|---|---|---|
| RTSP | 500-3000ms | 不支持 | TCP/UDP | 安防摄像头原生流 |
| WebRTC | 50-300ms | 原生支持 | UDP | 网页实时互动 |
| HLS | 10-30s | 原生支持 | HTTP | 点播/直播回看 |
| RTMP | 1-2s | 不支持(需 Flash) | TCP | 传统推流 |
为什么是 WebRTC?
- W3C 标准,Chrome/Firefox/Safari/Edge 全支持,无需插件
- 基于 UDP 传输,内置 NAT 穿透(ICE/STUN/TURN)
- 自适应码率与网络抖动补偿,延迟典型值 50-300ms
- 通过 JavaScript 的 RTCPeerConnection API 直接调用,嵌进网页零成本
左侧是 go2rtc 能吃的输入(RTSP/ONVIF/HTTP-FLV/私有协议……),右侧是吐出去的输出,WebRTC 只是其中一路——这也是它被称为"终极摄像头流媒体应用"的原因。
环境速查:RTSP 摄像头浏览器播放的硬件要求
不转码的话,主流硬件随便跑;涉及 FFmpeg 转码或 Docker 部署时,按下表留余量:
| 项目 | 推荐配置 | 最低配置 | 备注 |
|---|---|---|---|
| CPU | 4 核 i5 / Ryzen 5 | 2 核入门级 | 硬件转码需 AVX / QSV / VA-API 支持 |
| 内存 | 4GB | 2GB | Docker 部署额外预留约 1GB |
| 网络 | 100Mbps 有线 | 10Mbps Wi-Fi | 无线环境建议开启 QoS |
| 操作系统 | Ubuntu 22.04 LTS | Ubuntu 18.04 / Win 10 / macOS 11 | 支持 ARM(树莓派等) |
| 浏览器 | Chrome 136+ | Chrome 126 / Safari 14 | WebRTC 播 H265 需 Chrome 136+ / Safari 18+ |
3 种部署方式任选(按场景分流)
三种方式功能一致,按你的场景挑一个即可,每种末尾都有一条验证命令。
场景 A · 生产环境:二进制直装
适用:服务器 / 长期运行。单文件零依赖;如果后面要用ffmpeg:转码源,先在系统里装好 FFmpeg。
到项目仓库的 Release 页下载对应平台二进制(Linux x86_64 是go2rtc_linux_amd64,ARM 是go2rtc_linux_arm64,Windows/macOS 各有一对):
chmod +x go2rtc_linux_amd64 ./go2rtc_linux_amd64 version # 预期输出:go2rtc version 1.x.x场景 B · 开发调试:Docker 容器
适用:开发测试。镜像预装 FFmpeg 和 Python,转码源开箱即用:
docker pull alexxit/go2rtc:latest docker run -d \ --name go2rtc \ --network=host \ -v ./config:/config \ alexxit/go2rtc:latest curl -s http://localhost:1984/api/streams # 预期输出:JSON,含 streams 配置里的流名(如 "front_door")注意:不用
--network=host而走桥接网络时,必须手动映射三个端口:-p 1984:1984 -p 8554:8554 -p 8555:8555/tcp -p 8555:8555/udp。漏掉 8555 的 UDP,WebRTC 媒体数据就传不进来。
场景 C · 智能家居:Home Assistant 附加组件
适用:HA 用户。点击路径:设置 → 附加组件 → 添加仓库(粘贴官方 go2rtc 附加组件仓库地址)→ 找到 go2rtc 安装并启动。启动后打开组件 Web UI,Streams 页面出现你的摄像头,点开能出画面即为成功。
RTSP 源配置:3 种写法
go2rtc.yaml的默认查找路径,按部署方式分三种:
| 部署方式 | 配置文件路径 |
|---|---|
| 二进制 | 程序运行目录 |
| Docker | /config/go2rtc.yaml(即上面-v ./config:/config挂进去的目录) |
| HA 附加组件 | /config/addons_config/{组件目录}/go2rtc.yaml |
最简单的配置就是一行streams: 流名: URL:
# go2rtc.yaml streams: # 写法一:简易版,一行搞定主流品牌摄像头 front_door: rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101 # 写法二:高级版,多源 + FFmpeg 转码补 Opus 音频 living_room: - rtsp://user:pass@192.168.1.101/cam/realmonitor?channel=1&subtype=0 - ffmpeg:rtsp://user:pass@192.168.1.101/cam/realmonitor?channel=1&subtype=0#audio=opus # 音频转 Opus,WebRTC 可播 # 写法三:品牌专用协议,TP-Link Tapo 用云密码,无需用户名 tapo_camera: tapo://cloud-password@192.168.1.103多源写法是 go2rtc 的核心卖点之一:同一流的多个源会按浏览器支持的编解码器自动协商选路——比如摄像头音频是 AAC、浏览器只收 Opus,就自动走 FFmpeg 那条源出 Opus,视频仍走原生 RTSP,不做多余转码。配置可以在 WebUI 里直接编辑,带语法高亮和校验:
品牌摄像头适配速查
| 品牌 | 典型 RTSP 地址 | 特殊说明 |
|---|---|---|
| 海康 Hikvision | rtsp://user:pass@ip:554/Streaming/Channels/101 | 101 = 通道 1 主码流;双向音频走 ISAPI |
| 大华 Dahua | rtsp://user:pass@ip/cam/realmonitor?channel=1&subtype=0 | 建议加&unicast=true&proto=Onvif |
| TP-Link Tapo | tapo://cloud-password@ip | 用云密码,不支持用户名 |
| Reolink | rtsp://user:pass@ip/h264Preview_01_main | 部分型号 RTSP 实现较差,可用ffmpeg:包装 |
| Amcrest | rtsp://user:pass@ip/cam/realmonitor?channel=1&subtype=0 | 大华同款 URL 结构 |
WebRTC 服务:默认就开着
webrtc模块默认启用,启动即监听 8555/TCP+UDP,不需要任何额外配置。只在两种情况下动它:局域网 IP 不唯一时要手动指定 host candidate,公网访问时配 STUN/TURN:
webrtc: listen: ":8555" # WebRTC 服务端口(TCP/UDP) candidates: - 192.168.1.1:8555 # 局域网:手动加服务器 host candidate - stun:8555 # 公网动态 IP:go2rtc 自动通过 STUN 探测外网地址 ice_servers: - urls: ["stun:stun.l.google.com:19302"] # 公网强 NAT 环境再加 TURN:- urls: ["turn:user:pass@turn.example.com:3478"]注意:公网稳定访问需在路由器把 8555 端口TCP 和 UDP 都打洞放行;只开 TCP 时 UDP 打洞偶尔能通,但不保证。
验证一下:
curl -s http://localhost:1984/api/streams # 预期输出:JSON 流列表,如 {"front_door": {"streams": [{"protocol": "rtsp", ...}]}}播放验证:4 种姿势
① Web UI(最省事)
- 打开
http://localhost:1984 - Streams 页面找到目标流,点它的WebRTC按钮
- 浏览器弹出授权请求后点允许——首帧几乎立刻出现,这就是 <300ms 延迟的体感
这个 Net 页面值得常看:每条活跃连接的协议、编解码器、码率一目了然,排查"哪条链路在转码"第一手就在这里。
② HTML5 页面内嵌
零依赖,核心就是 WHEP 一问一答:你 POST 一个 offer,它回一个 answer:
<video id="video" autoplay playsinline controls></video> <script> const video = document.getElementById('video'); const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }); // 只收不发,不占用本地麦克风 pc.addTransceiver('video', { direction: 'recvonly' }); pc.addTransceiver('audio', { direction: 'recvonly' }); pc.createOffer().then(async (offer) => { await pc.setLocalDescription(offer); const res = await fetch('http://localhost:1984/api/webrtc?src=front_door', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: 'offer', sdp: pc.localDescription.sdp }) }); const answer = await res.json(); await pc.setRemoteDescription({ type: 'answer', sdp: answer.sdp }); }); // 成功标志:1 秒内 <video> 出画面 pc.ontrack = (e) => { video.srcObject = e.streams[0]; }; </script>③ 命令行
ffplay -fflags nobuffer -flags low_delay rtsp://192.168.1.123:8554/front_door # 预期:几乎无缓冲播放;低延迟参数官方 README Tips 同款④ 第三方客户端
- VLC:打开网络串流,填
rtsp://192.168.1.123:8554/front_door(偏好设置里把缓存调到最低) - 手机浏览器:直接访问
http://192.168.1.123:1984/webrtc.html?src=front_door - 其他程序:HTTP 渐进流
http://192.168.1.123:1984/api/stream.mp4?src=front_door
调优 & 排障:3 类高频故障 ⚠️
低延迟调优的核心动作只有一个:让链路尽量别转码、别缓冲。涉及转码时把 FFmpeg 预设调到最快:
streams: optimized: - rtsp://user:pass@192.168.1.101:554/Streaming/Channels/101 # 源是 H265 而目标浏览器不支持时:转码 H264 + 最快编码预设 - ffmpeg:optimized#video=h264#preset=ultrafast排障决策树,从外到内逐层确认:
三个高频故障,每个给你 2 个直接能做的动作:
只出声音不出画面
- 用
curl -s http://localhost:1984/api/streams确认流里的视频编码——是 H265 且浏览器旧,先转 H264 - 在流上加一条
ffmpeg:流名#video=h264转码源,go2rtc 会自动协商选路
延迟超过 500ms
- 客户端侧先测:
ffplay -fflags nobuffer -flags low_delay拉同一源,排除播放器缓冲因素 - 链路里有 H265 转码的话,把预设改成
#preset=ultrafast
Safari 黑屏
- 先确认流是 H264(Safari 18 以下不支持 WebRTC 播 H265)
- 若黑屏伴随麦克风权限弹窗失败,是安全上下文问题:纯拉流不受影响,需要双向音频时把 Web UI 换成 HTTPS 访问
注意:Safari 要求摄像头/麦克风授权必须在安全上下文(HTTPS 或 localhost)下进行,只看不说话则无此限制。
进阶玩法 🔥
一路流不够用了?三招收尾,总共 6 行配置:
streams: # 两路摄像头横向拼成一路 wall: "ffmpeg -i front_door -i living_room -filter_complex hstack -y wall.mp4" # 直接把任意流发布到 YouTube youtube: rtmp://a.rtmp.youtube.com/live2/STREAM_KEYcurl "http://localhost:1984/api/frame.jpeg?src=front_door" -o snapshot.jpg # 预期:本地生成一张当前帧 JPEG,配合 cron 就是定时快照要做人形检测,别在 go2rtc 里造轮子:让外部程序(如 Frigate)订阅http://localhost:1984/api/stream.mp4?src=front_door做 AI 分析,go2rtc 专心搬流。
收尾:现在可以去做的事 📌
- 收藏这篇的
go2rtc.yaml模板和品牌适配速查表,下次接摄像头直接抄 - 盯住项目 Release 页,编解码器兼容性(尤其 WebRTC H265)在持续变好
- 把
/api/streams和/api/webrtc两个端点接进你现有的智能家居或监控面板 - 在评论区分享你的部署配置,尤其是踩过的品牌坑
方向已经明确:WebRTC over QUIC 和更强的端到端加密,会把这点延迟继续往下压。
附录:仓库内参考资料
- 项目总览与完整配置说明:README.md
- WebRTC 模块文档(candidate / STUN / TURN 细节):internal/webrtc/README.md
- HTTP API 全部端点(OpenAPI 格式):website/api/openapi.yaml
- WebUI 使用文档:www/README.md
【免费下载链接】go2rtcUltimate camera streaming application项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考