摄像头现在能直接开播了——MiBeeNVR v0.8.1 直播推流上线
一个跑在树莓派上的开源 NVR凭什么能跟 OBS 抢活干这篇讲讲我们怎么把监控摄像头 → 直播间这条路从能用走到好用中间踩了多少协议层的坑。上图手机 App 上看到的直播画面推流由 MiBeeNVR 原生 Go relay 完成无 FFmpeg 依赖。先说结论MiBeeNVR v0.8.1 支持将任意接入的摄像头画面通过 RTMP 协议直接推流到直播平台。纯 Go 实现不需要额外安装 FFmpeg不依赖外部进程配置好推流地址就能开播。⚠️ 目前作者仅在斗鱼平台完成实测其它平台理论上兼容同为 FMS 标准但尚未验证。遇到问题请到 GitHub Issues 反馈。树莓派 3B 以上即可运行支持 H.264/H.265 摄像头。MiBeeNVR 是什么MiBeeNVR 是一个开源的网络视频录像机NVR项目用 Go 语言编写专为嵌入式设备树莓派、香蕉派等优化。在 v0.8.1 之前它已经具备多路摄像头管理与录像RTSP/ONVIF/小米双摄H.264/H.265 硬件转码延时摄影录制与合成LL-HLS / WebRTC 低延迟播放Docker 一键部署唯独缺一样东西直播推流。社区里一直有人问能不能把摄像头画面直接推到直播间——养宠物的想开宠物直播间做安防的想做个公开监控频道玩硬件的就想折腾。v0.8.1 把这个能力补上了。直播推流看着简单做起来要命第一步先跑通最直观的方案是调 FFmpeg——它是直播行业的瑞士军刀OBS 底层也用它。在 MiBeeNVR 的转推输出里配一个 RTMP 目标后端起一个 FFmpeg 子进程画面确实能推到直播间。[Image: MiBeeNVR 转推输出配置界面截图]但问题是FFmpeg 是外部进程。要单独安装、单独管理生命周期、占用额外内存。在一个目标是树莓派上轻量运行的项目里拖着一个几十 MB 的外部进程跑推流不够优雅。我们想要的是纯 Go 实现的 RTMP 推流嵌进 NVR 进程里零外部依赖。第二步纯 Go 推流的六层地狱RTMP 协议看着简单——不就是握手、连接、推数据嘛。但真要对接国内直播平台它们的后端都是 Adobe FMS 兼容实现会发现每一层都能卡住你。我们遇到的不是一个问题是六层叠加的问题L1握手digestHMAC-SHA256签名L2chunksize分块大小不匹配L3chunkheaderType0/1/2/3格式L4后台读消息缓冲区撑爆L5元数据字段缺width/height/fpsL6streamID字节序大端vs小端⭐✅推流成功前四层修完握手通过了、连接建立了、推流命令成功了——但第一个视频帧发出去 74 毫秒连接就被对方重置了。这个 74ms 非常关键它说明不是网络超时那种要等 5 秒而是对方在帧级别就拒绝了你的数据。最终 Boss一个字节序的故事最后的根因藏得极深以至于我们花了整整一天才找到。RTMP 消息里有个字段叫MessageStreamID用来标识消息属于哪条流。按 RTMP 规范这个字段应该是小端序little-endian。我们代码里就老老实实按规范写了小端序。但所有主流实现FFmpeg、OBS、gortmplib都用了大端序。直播平台也期望大端序。我们的代码在大部分消息上走的是第三方库的标准路径大端序但在某些自定义写入路径上用了我们自己的实现小端序。同一个连接里一会儿大端一会儿小端——对方收到这种精神分裂的数据包直接 RST 断开。发现这个 bug 靠的是进程内字节级 dump——把每个发出去的字节都记下来逐条解析 chunk header才发现 streamID 字段的大小端不一致。修复只改了 4 行代码但找到它花了一整天。Go标准WriterstreamID大端直播平台期望大端✅我们的WriterstreamID小端直播平台收到小端❌RST一句话总结规范说往左走全世界都往右走你跟着规范走就被全世界拒绝。最终效果六层全部修复后✅ 纯 Go relay 推流成功无 FFmpeg 依赖✅ TCP 连接稳定保持持续推流无中断✅ 树莓派摄像头画面实时推到直播间延迟约 2-3 秒✅ 支持 H.264 摄像头后续将支持 H.265 推流⚠️不建议开启use_ffmpeg选项。FFmpeg 推流存在已知问题播放中途可能因帧率不匹配导致卡顿且不会自动恢复。纯 Go relay 路径已经过充分验证是推荐的推流方式。 纯 Go relay 是本次开发的重点。如果在其它平台遇到 Go 推流的问题请优先提 Issue 反馈 Go 方面的问题帮助项目持续改进推流能力——而不是切回 FFmpeg。怎么用方式一MiBeeNVR 界面配置在摄像头设置里找到转推输出填入直播平台的 RTMP 推流地址即可rtmp://推流地址/live/推流码推流码从直播平台的推流设置里获取。方式二Docker 部署docker run -d \--name mibee-nvr \-p 8080:8080 \-v mibee-nvr-data:/var/lib/mibee-nvr \ghcr.io/mi-bee-studio/mibee-nvr:latest打开http://设备IP:8080进入管理界面添加摄像头后配置转推输出。测试情况与注意事项已测试平台斗鱼直播直播伴侣模式局域网推流✅理论兼容所有 FMS 标准的直播平台后端。但各平台实现细节有差异未经实测的平台可能遇到问题——遇到问题请到 GitHub Issues 反馈作者会跟进。⚠️ 重要提醒不建议长期在国内直播平台持续推流。各平台有自己的推流政策和限制长时间无人值守的摄像头推流可能触发限流降低码率/分辨率推流码过期后断连账号警告甚至封禁请务必了解你所用平台的相关政策遵守平台规则。MiBeeNVR 提供的是技术能力怎么用、用在哪个平台、推什么内容责任在用户自己。踩坑感悟这次做直播推流最大的感悟有三条1. 对比实验是调试的黄金标准当 Go 代码推流失败时我们不确定是代码问题还是环境问题。直到在同一个设备上用 FFmpeg 命令行手动推流成功才确认是 Go 协议层的锅。没有这个对照再多猜测都是空谈。2. 二进制协议的 bug必须看字节字节序这种问题靠读代码是看不出来的——因为代码看起来是对的按规范写的。只有把实际发出的字节 dump 出来逐条解析才能发现大小端不一致。调试二进制协议先加 dump再分析。3. 规范不等于现实RTMP 规范说 MessageStreamID 是小端但全世界都用大端。这种规范与实践脱节的情况在旧协议里非常常见。当你按规范写代码却到处碰壁时去看看别人的实现是怎么做的——事实标准比纸面规范更有说服力。关于 MiBeeNVRMiBeeNVR 是 Mi-Bee-Studio 的开源项目使用 Go 语言编写已为树莓派等嵌入式设备优化。GitHub: https://github.com/Mi-Bee-Studio/MiBeeNvr主要特性多路摄像头管理RTSP / ONVIF / 小米双摄H.264/H.265 硬件转码V4L2 / VAAPI / NVENC 自动探测延时摄影录制与合成纯 Go muxer零编码开销LL-HLS / WebRTC 低延迟播放RTMP 直播推流v0.8.1 新增纯 Go 实现Docker 一键部署运行环境树莓派 3B 及以上 / x86_64 / ARM64 / DockerMiBeeNVR v0.8.1 已发布完整变更列表见 GitHub Release Notes。如果你也在用树莓派做有意思的项目欢迎来 GitHub 交流。