MiBeeNvr v0.4.0: 音频录制管线与多层健康监控架构
v0.3.1 发布之后又肝了 196 个提交。v0.4.0 是一个功能密度很高的版本:音频录制管线、多层健康监控引擎、HLS/LL-HLS 播放稳定性优化、UI 大改版。完整更新列表见 GitHub Release Notes。
上一篇介绍了 v0.3.x 的多协议流媒体和小米摄像头支持(v0.3.0 技术帖),没看过第一篇的可以先看 MiBeeNvr 介绍。
音频录制:从静音到有声
v0.3.x 时代录制的 MP4 文件只有视频轨。v0.4.0 引入了完整的音频捕获和封装管线,支持 RTSP 摄像头的 AAC 音频和 ONVIF/小米摄像头的 G.711 音频。
音频管线架构
音频处理的核心挑战在于:不同协议的摄像头使用不同的音频编码,而最终的 MP4 容器需要统一封装。
flowchart LR
subgraph "RTSP 摄像头"
A1[RTSP Source]
A2[AAC Audio]
end
subgraph "ONVIF / 小米"
B1[ONVIF/Xiaomi]
B2[G.711 μ-law]
B3[G.711 A-law]
end
subgraph "MiBeeNvr 音频管线"
C[StreamHub 音频广播]
D[MP4 Muxer]
end
subgraph "输出"
E[MP4 Segment<br/>Video + Audio]
end
A1 --> A2 --> C
B1 --> B2 --> C
B1 --> B3 --> C
C --> D
D --> E
classDef input fill:#E3F2FD,stroke:#1565C0,color:#1565C0
classDef process fill:#FFF3E0,stroke:#E65100,color:#BF360C
classDef output fill:#E8F5E9,stroke:#2E7D32,color:#1B5E20
class A1,A2,B1,B2,B3 input
class C,D process
class E output每摄像头音频开关
音频录制默认关闭,通过 audio_enabled 配置逐摄像头开启:
| |
G.711 音频封装
G.711(μ-law 和 A-law)是 IP 摄像头和小米摄像头的常见音频编码。MP4 容器本身不直接支持 G.711,所以 v0.4.0 使用了自定义 box type(ulaw / alaw)来封装 G.711 音频帧:
- AAC 音频 → 标准
mp4abox - G.711 μ-law →
ulawbox - G.711 A-law →
alawbox
这种方案的优点是不需要转码,直接把原始 G.711 帧塞进 MP4,零 CPU 开销。缺点是某些通用播放器可能不认识自定义 box,但 MiBeeNvr 的 Web 播放器能正确处理。
StreamHub 音频广播
v0.3.1 引入的 StreamHub 在 v0.4.0 中扩展了音频支持。录制器不仅广播视频帧,还同时广播音频帧。所有实时消费者(WebRTC、HTTP-FLV 等)都能获得音频数据,实现"录像有声音,实时预览也有声音"。
合并时的音频保留
segment 合并流程也做了适配,确保音频轨在合并后完整保留。之前合并只处理视频轨,现在会同时检查并保留音频轨信息。
多层健康监控:不只是"连没连上"
健康监控是 v0.4.0 最复杂的子系统。internal/health/ 包含 17 个源文件,覆盖了从连接检测到自动恢复的完整链路。
三层检测模型
flowchart TB
subgraph "Layer 1: 连接层"
A[Connection Monitor]
A1[RTSP 会话状态]
A2[ONVIF 响应检测]
A3[CS2 P2P 心跳]
end
subgraph "Layer 2: 码流层"
B[Stream Stats Collector]
B1[帧率统计]
B2[码率监测]
B3[关键帧间隔]
end
subgraph "Layer 3: 画面层"
C[Freeze Detector]
C1[画面冻结检测]
C2[黑屏检测]
end
A --> A1 & A2 & A3
B --> B1 & B2 & B3
C --> C1 & C2
A --> B --> C
classDef layer1 fill:#E3F2FD,stroke:#1565C0,color:#1565C0
classDef layer2 fill:#FFF3E0,stroke:#E65100,color:#BF360C
classDef layer3 fill:#FFEBEE,stroke:#C62828,color:#B71C1C
class A,A1,A2,A3 layer1
class B,B1,B2,B3 layer2
class C,C1,C2 layer3每层检测独立运行,有各自的阈值配置。检测结果汇总到健康评分引擎(health_score.go),生成一个综合分数。
健康评分引擎
评分引擎为每个摄像头维护一个实时健康分数,综合考虑三层检测结果:
- Layer 1 权重最高 — 连接断了什么都不用说
- Layer 2 次之 — 码流异常意味着画面质量下降
- Layer 3 兜底 — 连接和码流都正常但画面冻住了,可能是摄像头本身的问题
每层都有独立的阈值和冷却时间,避免短暂抖动触发不必要的告警。
自动恢复引擎
检测到问题之后怎么办?auto_remediate.go 实现了一个带安全边界的自动恢复引擎:
flowchart LR
A[健康检测异常] --> B{是否在安全边界内?}
B -->|是| C[指数退避重试]
B -->|否| D[停止恢复<br/>标记为故障]
C --> E{恢复成功?}
E -->|是| F[恢复正常<br/>重置计数器]
E -->|否| G[增加退避时间]
G --> B
classDef detect fill:#E3F2FD,stroke:#1565C0,color:#1565C0
classDef decision fill:#FFF3E0,stroke:#E65100,color:#BF360C
classDef success fill:#E8F5E9,stroke:#2E7D32,color:#1B5E20
classDef failure fill:#FFEBEE,stroke:#C62828,color:#B71C1C
class A detect
class B,E decision
class C,F success
class D,G failure关键设计决策:
- 安全边界 — 最多连续恢复 N 次,超过后停止,避免无限循环
- 指数退避 — 重试间隔逐渐增大(1s → 2s → 4s → 8s → …),不会把设备或网络搞崩
- 告警冷却 — 同一摄像头在冷却时间内不重复告警,避免告警风暴
健康历史与可视化
健康事件持久化存储,Web 界面提供时间线可视化:
- 每个摄像头的健康事件历史
- 异常发生时间和恢复时间
- 摄像头卡片上的实时健康指示灯
健康 API 端点:
GET /api/health— 系统整体健康状态GET /api/cameras/{id}/health— 单个摄像头健康详情
HLS/LL-HLS 稳定性优化
这次对 HLS 播放做了大量打磨,特别是针对树莓派等低性能设备。
IDR 帧等待
之前录制器可能在任意帧开始写 segment,导致播放器拿到一个不以关键帧开头的 segment —— 表现为黑帧。v0.4.0 改为等待下一个 IDR 帧才开始写入新 segment,牺牲一点 segment 边界精度,换来的是每个 segment 第一帧就是可解码的画面。
基于信用的帧率限流
引入了 credit-based FPS throttling 机制。核心思想是给消费者一个"帧预算",消费者消费一帧就减少一个信用,生产者只在有信用时才发送新帧。这让帧传递节奏更平滑,避免低性能设备上突发帧导致卡顿。
LL-HLS 参数调优
针对树莓派上的播放稳定性,调整了两个关键参数:
backBuffer:0.5 → 2.0 秒 — 更大的回放缓冲区liveSync:2 → 3 秒 — 更宽松的直播同步距离
这两个参数的调整让树莓派上的 LL-HLS 播放从"经常卡顿"变成了"基本流畅"。
子流降级
子流(sub-stream)失败时自动回退到主流。之前子流断了就直接停止播放,现在会尝试切换到主流继续,虽然分辨率可能降低但至少画面不断。
UI 大改版
摄像头页面 Tab 导航
摄像头页面重构为 Tab 导航:
- Active — 正在录制的摄像头
- Archived — 已归档的摄像头,展开式录像列表
之前活跃和归档摄像头混在一个列表里,现在分类清晰多了。
设置页面流媒体专区
设置页面的 Advanced 标签新增了流媒体协议配置专区,包括 WebRTC、HTTP-FLV、RTMP、SRT 的详细配置项。
健康历史页面
新增健康历史页面,支持中英文切换(i18n)。时间线可视化展示每个摄像头的健康事件。
其他改进
ARMv7 支持
新增 ARMv7 二进制构建,覆盖树莓派 2/3 等老设备。现在 Docker 镜像支持三种架构:
| 架构 | 适用设备 |
|---|---|
| linux/amd64 | PC、服务器 |
| linux/arm64 | 树莓派 4/5、Mac M 系列 |
| linux/arm/v7 | 树莓派 2/3 |
ONVIF 编码自动检测
添加 ONVIF 摄像头时,自动检测编码格式(H.264/H.265),不需要手动选择。
小米云端同步
新增 Xiaomi cloud sync 端点,可以同步摄像头元数据(名称、型号等),省去手动填写的麻烦。
安全加固
延续 v0.3.0 的安全加固传统,v0.4.0 又加固了:
- health/readyz 端点的速率限制
- 下载/FTP/WebDAV 的路径穿越防护
- 摄像头 URL 和 ONVIF IP 的输入验证
- SQL LIKE 注入防护
- 初始化密码最低 8 位
- 未配置密码时的认证绕过防护
质量保障
1651 个测试通过,60.7% 覆盖率。这个版本新增了健康监控的完整测试套件(连接检测、评分引擎、自动恢复),以及 HLS 播放的端到端测试。
总结
从 v0.3.1 到 v0.4.0,196 个提交,73 个新功能,54 个修复,21 个重构,9 个测试,16 个文档。
音频录制补上了 MiBeeNvr 最大的功能短板,健康监控系统让它在无人值守场景下更可靠,HLS 优化让低性能设备上的播放体验有了质的提升。
如果说 v0.3.x 是在解决"能不能用"的问题(多协议、小米摄像头),那 v0.4.0 开始解决"好不好用"的问题 —— 有声音、能自愈、不卡顿。
开源地址:
如果你在找一个轻量级、能录音、能自愈的开源 NVR,v0.4.0 值得试试。