MiBeeNvr v0.3.1: 多协议流媒体与小米摄像头内置支持
v0.2.0 发布之后又折腾了不少,这次 v0.3.x 带来了几个重量级更新:小米摄像头内置支持、归档录像功能、多协议流媒体架构(WebRTC/HTTP-FLV/RTMP/SRT/LL-HLS),以及一大波安全加固。从外部依赖到内置实现、从单协议到全协议支持的架构演进过程,比我想象的要曲折得多。
上一篇介绍了 v0.2.0 的 15 个新功能(v0.2.0 更新),没看过第一篇的可以先看 MiBeeNvr 介绍。v0.3.0 聚焦小米摄像头深度集成,v0.3.1 在此基础上带来了完整的多协议流媒体架构。完整更新列表见 GitHub Release Notes。
架构演变:从外部依赖到内置实现的曲折之路
小米摄像头支持的开发过程,是我做过最有趣的架构实验之一。整个过程经历了三个截然不同的阶段,每个阶段都有其独特的教训。
第一阶段:go2rtc 外部依赖 (v0.1.0 时代)
早期的 MiBeeNvr 完全依赖 go2rtc 来处理小米摄像头的协议转换:
graph TB
subgraph "小米摄像头"
A[Camera]
end
subgraph "外部容器"
B[go2rtc]
end
subgraph "MiBeeNvr"
C[RTSP 客户端]
D[HLS 编码]
E[存储管理]
end
A -->|"miss 协议"| B
B -->|"RTSP"| C
C -->|HLS| D
D -->|存储| E
classDef hardware fill:#e3f2fd,stroke:#1976d2
classDef process fill:#e8f5e9,stroke:#4caf50
classDef storage fill:#fff3e0,stroke:#ff9800
classDef network fill:#f3e5f5,stroke:#9c27b0
class A hardware
class B process
class C,D,E storage说实话,这个方案一开始看起来很优雅:用一个现成的 Docker 容器解决协议转换问题,主程序专心做 NVR 功能。但很快问题就来了:
- CS2 P2P 连接不稳定:小米摄像头的 P2P 连接大约 20 分钟就会超时卡死
- 调试困难:go2rtc 是独立项目,出了问题很难定位
- 运维复杂:需要管理两个 Docker 容器,端口冲突、资源争抢问题不断
归根结底,把核心功能依赖到外部容器上,本身就是个设计上的失误。
第二阶段:插件架构实验 (v0.2.0 到 v0.3.0 之间)
吸取教训之后,我决定把 go2rtc 的 Xiaomi 代码移植到 MiBeeNvr 里,做成插件系统。当时的想法很好:
- 通过 Go 接口注册实现协议解耦
- 使用
init()基础的插件机制 - 甚至实验了 gRPC 进程隔离
听起来很美好对吧?让架构变得可扩展,牺牲一点性能换来开发便利性。结果现实给了我一记响亮的耳光:
flowchart LR
subgraph "小米摄像头"
A[Camera]
end
subgraph "插件进程"
B[Plugin Process]
C[gRPC 通信]
end
subgraph "MiBeeNvr 主程序"
D[主 NVR 引擎]
E[HLS 编码]
F[存储管理]
end
A -->|"miss 协议"| B
B -->|gRPC| C
C -->|处理| D
D -->|HLS| E
E -->|存储| F
classDef hardware fill:#e3f2fd,stroke:#1976d2
classDef process fill:#e8f5e9,stroke:#4caf50
classDef storage fill:#fff3e0,stroke:#ff9800
classDef network fill:#f3e5f5,stroke:#9c27b0
class A hardware
class B,C process
class D,E,F storage实际使用中发现的问题:
- 架构过度复杂:实时预览多了好几层中间环节,性能下降明显
- 资源消耗增加:额外的进程和通信开销
- 新人门槛高:代码库变得难以理解,一个简单的功能需要跨进程通信
折腾了一圈才发现,有时候最简单的方案反而是最好的。
第三阶段:回归简洁 (v0.3.0)
最终在 v0.3.0 中,我彻底移除了插件系统,将 Xiaomi 代码迁移到内置的 internal/xiaomi/ 包中:
graph TB
subgraph "小米摄像头"
A[Camera]
end
subgraph "MiBeeNvr 核心"
B[internal/xiaomi/ 包]
C[核心 NVR 引擎]
D[HLS 编码]
E[存储管理]
end
A -->|"miss 协议"| B
B -->|直接处理| C
C -->|HLS| D
D -->|存储| E
classDef hardware fill:#e3f2fd,stroke:#1976d2
classDef process fill:#e8f5e9,stroke:#4caf50
classDef storage fill:#fff3e0,stroke:#ff9800
class A hardware
class B,C,D,E process正如 Release Notes 中所说:
“Plugin System Removed — Xiaomi migrated from gRPC plugin to built-in internal/xiaomi/ package”
“Full Xiaomi IP camera integration — no plugins, no external dependencies”
现在的架构就是一个单二进制文件,无需外部进程,无需 Docker 依赖。有时候,对于这个阶段的项目,简洁性比扩展性更重要。
小米摄像头功能详解
内置 CS2 P2P 协议
现在 MiBeeNvr 直接支持小米摄像头的 CS2 P2P 协议,不再需要 go2rtc 这个中间人。
云端认证流程
完整的认证流程包括:
- 使用小米账号登录
- 获取 passToken
- 自动发现设备列表
- 建立直连
支持的设备类型包括:
.camera.- 普通摄像头.cateye.- 猫眼摄像头.feeder.- 喂养器(HLC8 型号)
配置示例
在 mibeenvr.yaml 中添加小米摄像头配置:
| |
Web 界面
Web 界面提供了完整的账号管理功能:
- 小米账号登录页面
- 自动发现摄像头
- 一键添加功能
说实话,这个认证流程比我想象的要复杂,但最终实现出来的用户体验还算不错。
实际界面是这样的:

归档录像:独特的摄像机管理方式
归档录像功能是这次 v0.3.0 的一大亮点。这个需求的场景很简单:当你需要移除一个摄像头(坏了、搬家、升级)但又想保留历史录像时,传统 NVR 系统通常的做法是直接删除所有相关数据。
MiBeeNvr 提供了更人性化的解决方案:
flowchart LR
A[活跃摄像头] --> B[停止录制]
B --> C[合并片段]
C --> D[标记归档]
D --> E[从配置移除]
E --> F[录像保留]
classDef process fill:#e8f5e9,stroke:#4caf50
classDef storage fill:#fff3e0,stroke:#ff9800
classDef network fill:#f3e5f5,stroke:#9c27b0
class A,B,C,E process
class D,F storage三态摄像头管理
摄像头现在有三种状态:
- Active - 正在录制
- Disabled - 已暂停
- Archived - 只读(历史记录)
归档流程
归档操作很直观:
- 在摄像头列表中点击"归档"
- 弹出确认对话框
- 输入 “DELETE” 确认
- 系统自动合并片段并标记归档
- 摄像头从实时列表移除,但录像完整保留
归档后管理
归档后的录像支持:
- 播放历史录像
- 下载单个录像文件
- 删除指定录像
- 设置归档组保留期限
实际效果如下:

多协议流媒体:从 HLS 到全协议支持
v0.3.1 最重量级的变化是引入了完整的多协议流媒体架构。v0.3.0 时代只有 HLS 一种播放协议,延迟在 5-15 秒,对于实时监控来说体验不算好。这次直接上了 5 种协议,延迟最低可以到亚秒级。
StreamHub 多消费者扇出
核心架构变化是引入了 StreamHub —— 一个多消费者帧分发器。之前每路摄像头只能对接一个消费者(HLS 编码器),现在可以同时扇出到多个协议输出:
flowchart LR
A[摄像头源] --> B[StreamHub]
B --> C[HLS]
B --> D[WebRTC]
B --> E[HTTP-FLV]
B --> F[RTMP]
B --> G[SRT]
classDef input fill:#E3F2FD,stroke:#1565C0,color:#1565C0
classDef hub fill:#FFF3E0,stroke:#E65100,color:#BF360C
classDef output fill:#E8F5E9,stroke:#2E7D32,color:#1B5E20
class A input
class B hub
class C,D,E,F,G outputStreamHub 的设计很简单:每个录制器把帧广播到 StreamHub,消费者(HLS/WebRTC/FLV 管理器)各自订阅感兴趣的流。这样添加新协议只需要实现一个新的消费者,不需要动录制器的代码。
协议对比
五种协议各有适用场景:
| 协议 | 延迟 | 编码 | 方向 | 适用场景 |
|---|---|---|---|---|
| WebRTC (WHEP) | <1s | H.264 | 拉流 | 实时预览、对讲 |
| HTTP-FLV | 1-3s | H.264/H.265 | 拉流 | Web 低延迟监控 |
| LL-HLS | 2-5s | H.264/H.265 | 拉流 | 低延迟兼容方案 |
| HLS | 5-15s | H.264/H.265 | 拉流 | 最大兼容性 |
| RTMP | — | H.264 | 推流 | OBS 等推流工具 |
| SRT | — | H.264 | 推流 | 远程/不稳定网络推流 |
协议切换器
前端新增了 ProtocolSwitcher 组件,用户可以在播放界面一键切换协议。下拉菜单显示当前可用的协议和预估延迟,H.265 摄像头会自动排除不支持的协议(如 WebRTC)。
WebRTC WHEP 实现
WebRTC 通过 WHEP (WebRTC-HTTP Egress Protocol) 标准实现,后端用 pion/webrtc v4:
- 每个 H.264 摄像头最多 2 个 peer
- 空闲超时自动驱逐
- SDP 音频拒绝(纯视频场景)
- 僵尸连接检测 + 自动重连
说实话,WebRTC 的信令交换比我想象的简单多了,WHEP 协议把 SDP 交换简化成了一个 POST 请求。
RTMP 推流与 SRT 接收
除了拉流协议的丰富,v0.3.1 还增加了推流接入能力:
- RTMP:基于 gortmplib 实现,支持 stream key 认证,H.264 流直接进入 StreamHub
- SRT:基于 gosrt 实现,MPEG-TS 解复用后提取 H.264 NALU 送入 StreamHub
这意味着你可以用 OBS 推流到 MiBeeNvr,或者通过 SRT 在不稳定网络环境下远程推送视频流。
初始化向导:首次运行体验
v0.3.1 新增了 Setup Wizard,第一次打开应用时会自动进入配置向导:
- 自动检测浏览器支持的流媒体协议
- 推荐最佳协议(优先级:LL-HLS > WebRTC > HTTP-FLV > HLS)
- 设置管理员密码
- 创建初始配置
这修复了 v0.3.0 的一个痛点:Docker 部署时初始化页面不会自动显示,需要先尝试登录才会跳转。现在 /api/health 接口新增了 setup_required 字段,前端可以在页面加载时主动检测未初始化状态并自动跳转到 #/setup。
v0.3.1 体验优化
Dashboard 多协议支持
Dashboard 网格现在支持多协议播放。每个摄像头格子右上角显示协议徽章,颜色区分不同协议:WebRTC 绿色、FLV 橙色、HLS 蓝色、JPEG 灰色。默认协议在设置页面配置,不可用时自动降级到 HLS → JPEG。
Settings 页面重构
设置页面拆分成了 General 和 Advanced 两个标签页:
- General:清理策略、前端偏好、默认协议选择、协议指南
- Advanced:合并策略、WebDAV、流媒体配置(WebRTC/FLV/RTMP/SRT)、Feature Toggles
之前所有设置堆在一页里,现在分类清晰多了。
摄像头品牌兼容指南
新增了 20+ 摄像头品牌的兼容指南文档,包括海康、大华、宇视、Axis、TP-Link、小米等品牌的 RTSP 地址示例和配置方法。
v0.3.0 + v0.3.1 亮点汇总
安全加固(v0.3.0)
v0.3.0 包含了 15+ 个安全修复:
- 路径验证加强
- 认证机制硬化
- 速率限制优化
- 安全头设置
- SQL 注入防护
前端全面升级(v0.3.0)
前端完成了 Svelte 5 的完整迁移:
- 运行模式 (runes) 语法
- 移除所有遗留语法
- 国际化 500+ 个键值
HLS 改进(v0.3.0)
HLS 播放器优化:
- 指数退避自动重试
- 僵尸播放器检测
- 子流降级支持
v0.3.1 Bug 修复
- Docker 初始化页面修复:新增
setup_required字段到 health 接口,主动检测并跳转 - LL-HLS 优先级修正:协议推荐顺序改为 LL-HLS > WebRTC > HTTP-FLV > HLS
- 小米摄像头 PTS 修复:PTS 基准在重连时被重置导致 HLS 时间戳重启,移至
Start()只设一次 - ONVIF 错误传播:发现错误不再静默吞掉,返回结构化错误信息(NETWORK/TIMEOUT/NO_DEVICES/PARSE_ERROR)
- WebRTC 僵尸检测:Dashboard 多格子快速挂载/销毁时的 null 检查修复
- 统计图表单位:修复 GB 级数据显示为 MB 的阈值偏移问题
总结 + 开源链接
从 v0.2.0 到 v0.3.1,总共 160+ 个提交。v0.3.0 带来了小米摄像头内置支持和归档录像(141 commits, 45 features, 48 fixes),v0.3.1 在此基础上引入了完整的多协议流媒体架构(WebRTC/HTTP-FLV/RTMP/SRT/LL-HLS)、Setup Wizard 和一系列体验优化。
从外部依赖到插件实验,再到内置简洁实现;从单协议 HLS 到 StreamHub 扇出的全协议支持。两次架构演进让我深刻体会到:
有时候,最"正确"的架构并不是最灵活的那个。但对于流媒体来说,协议可扩展性确实是必须的。
开源地址:
折腾了这么久,从小米摄像头到全协议流媒体,MiBeeNvr 终于从一个简单的 NVR 走向了更通用的视频流平台。如果你也在折腾智能家居或者需要轻量级 NVR 方案,不妨试试看。