家里有好几个摄像头,几台小米,一些自己用 ESP32 搭的,还有多台树莓派 CSI 摄像头。之前一直在用一些云存储方案,但总觉得不放心:厂商绑定、依赖网络、费用还不少。索性自己动手,写了个 NVR 系统,就叫 MiBeeNvr。
为什么做 MiBeeNvr
说实话,我对现有的云存储方案一直不太满意。先说小米摄像头吧,默认只能通过米家 app 查看,录像存储要么靠 SD 卡(容量有限,还得经常插拔),要么就得上云。云存储每个月几十块,而且最关键的是隐私问题——你不知道厂商什么时候会把你的视频数据拿去训练 AI,或者干脆就把数据卖给了第三方。更别提厂商绑定了,想换平台都难。
ESP32 摄像头也是类似的情况。自己用 ESP32 搭了几个摄像头,录像是存 SD 卡,但查看和回放都不方便。需要一个统一的管理平台。
市面上其他开源方案我也试过:ZoneMinder 需要 LAMP 堆栈,安装部署比我整个项目还复杂;Shinobi 配置复杂得一塌糊涂;还有些小众项目基本上都没维护了。Frigate 虽然不错,但主要是针对 AI 检测,而且依赖 Docker,太重了。
说白了就是想要一个:
- 单文件二进制,下载就能跑
- 资源占用要少,树莓派都能跑
- 支持多种摄像头,特别是小米私有协议
- Web 界面要清爽,不用折腾前端
- 自动清理旧录像,不会占满硬盘
折腾了一圈发现,现成方案都不太合适,那就自己写一个吧。
MiBeeNvr 是什么
MiBeeNvr 是一个用 Go 写的轻量级 NVR 系统,专门解决家用摄像头的本地存储问题。
整体架构
先看一张全局架构图,整个系统长这样:
三层结构:摄像头端负责采集,中间有协议桥接层处理私有协议,MiBeeNvr 核心做录制和存储,上面再挂各种访问方式。
录制流水线
视频流进入 MiBeeNvr 之后的处理流程:
说白了就是:RTSP → RTP 解包 → MP4 封装 → 分段存储。前端用的是 Svelte 5,整个 SPA 直接编译成静态资源然后 embed 到 Go 二进制里,这样部署时只需要一个文件,连 Web 服务器都省了。
后端技术栈:
- Go 1.26 + modernc.org/sqlite(纯 Go 实现,无 CGO 依赖)
- chi 路由库,简洁高效
- gortsplib 处理 RTSP/RTP 协议
- pion/rtp 处理实时流媒体
选 SQLite 是因为它单文件、纯 Go 实现、性能对家用场景完全够用、支持并发访问,最重要的是不需要额外装数据库。
设计理念
整个项目的设计哲学就是「简单粗暴」:
- 单个二进制文件,无任何外部依赖
- 支持交叉编译,AMD64/ARM64 都能跑
- 配置文件用 YAML,简单直观
- 内置 Web 界面,打开浏览器就能用
- 资源占用极少,树莓派 4 也能流畅运行
主要特性
- 支持多种摄像头协议:RTSP(H.264/H.265)、HTTP JPEG
- 内置 Web 界面,支持明暗主题切换
- 中文/英文双语支持
- WebDAV(可读写)、FTP、REST API
- MQTT 触发录制,适合智能家居集成
- Prometheus 监控指标
- 每个摄像头独立的保留策略
- MP4 分段录制,自动清理旧文件
- 支持 HLS 直播流(最多 4 个并发)
我的实际部署
我这边是用一台 ARM64 小主机跑的,512MB 内存,2GB 存储。整个系统跑得很稳定,基本上是设置完就不管了。
接了 4 个摄像头,各有特点:
- 树莓派 CSI 摄像头 - 通过 MediaMTX 做 RTSP 桥接,把 CSI 接口的视频流转换成标准 RTSP。配置
rtsp_h264。 - ESP32-S3 摄像头 - 自己搭的,跑 MJPEG 流,通过 HTTP 协议接入。配置
http_jpeg。 - 小米摄像头(阳台) - 通过 go2rtc 把小米私有协议转成 RTSP,2K 分辨率,配置
rtsp_h265。 - 小米摄像头(客厅) - 同上,1080P。
配置是 30 秒分段录制,保留 1 天。这个时间间隔是个权衡:太短了文件太多,太长了万一出事查起来不方便。开了 WebDAV(可读写)和 FTP,方便手机查看和备份。
Web 界面挺清爽的,摄像头管理、录像列表都有。
设置页面:
配置文件
完整的配置文件长这样,YAML 格式,一目了然:
server:
listen: ":9090"
storage:
root_dir: "/mnt/data/nvr"
segment_duration: "30s"
cameras:
- id: "rpi-csi-cam"
name: "RPi CSI Camera"
protocol: "rtsp_h264"
url: "rtsp://10.0.1.100:8554/stream"
enabled: true
- id: "esp32-cam"
name: "ESP32-S3 Camera"
protocol: "http_jpeg"
url: "http://10.0.1.101/capture"
enabled: true
- id: "xiaomi-balcony"
name: "Xiaomi Camera"
protocol: "rtsp_h265"
url: "rtsp://10.0.1.102:8554/xiaomi_stream"
enabled: true
cleanup:
retention_days: 30
disk_threshold_percent: 95
auth:
username: "admin"
password_hash: "用 mibee-nvr hash-password 命令生成"
webdav:
enabled: true
path_prefix: "/dav"
read_write: true
ftp:
enabled: true
port: 2121
小米摄像头接入
小米摄像头的协议问题是个大坑。它用自己私有的 “miss”(Mi Secure Streaming)协议,做了多层加密,不开放标准 RTSP 接口。也就是说,你就算知道摄像头的 IP,也没法用 VLC 直接拉流。
不过好在有 go2rtc 这个神器。整个接入链路是这样的:
整个过程不需要刷机、不需要拆摄像头、也不需要小米官方的云存储。go2rtc 帮你搞定了所有协议转换的事情。
go2rtc 部署
go2rtc 用 Docker 部署最省事:
# 创建配置文件
cat > go2rtc.yaml << EOF
streams:
xiaomi_balcony:
- xiaomi://your_account:cn@10.0.1.100?did=your_camera_did&model=isa.camera.hlc7
xiaomi_living_room:
- xiaomi://your_account:cn@10.0.1.101?did=your_camera_did&model=isa.camera.mj200
rtsp:
listen: ":8554"
EOF
# 运行容器
docker run -d --name go2rtc \
-p 8554:8554 \
-p 1984:1984 \
-v $(pwd)/go2rtc.yaml:/config.yaml \
alexxit/go2rtc
关键点:
xiaomi://协议需要小米账号和密码认证did是设备的唯一标识,model是设备型号(在米家 app 里能找到)- go2rtc 会自动处理 P2P 连接和 miss 协议解密
- 最终在 8554 端口暴露标准的 RTSP 流,MiBeeNvr 当普通摄像头接入就行
然后在 MiBeeNvr 的配置里指向 go2rtc:
cameras:
- id: "xiaomi-balcony"
name: "小米摄像头"
protocol: "rtsp_h265"
url: "rtsp://localhost:8554/xiaomi_balcony"
enabled: true
踩坑记录
小米摄像头的接入有不少坑:
- 首次联网:小米摄像头必须能连外网,因为需要和小米服务器做密钥交换。建立连接后,后续传输是局域网内的。
- 设备 ID 获取:每个摄像头的
did都不同,需要用 go2rtc 的 WebUI(端口 1984)自动发现,或者在米家 app 里翻。 - 不是所有型号都支持:go2rtc 维护了一个兼容列表,买摄像头之前最好先查一下。
- H.265 vs H.264:新款小米摄像头基本都是 H.265,MiBeeNvr 对两种编码都支持,但 H.265 省存储空间。
ESP32 摄像头项目
搞 MiBeeNvr 的时候,顺带做了几款 ESP32 摄像头固件。ESP32 摄像头这个坑踩了不少,但也挺有意思的。
三款固件定位不同:
所有固件都设计成 MiBeeNvr 的上游采集端:摄像头负责采集视频,MiBeeNvr 负责统一存储和管理。
MiBeeCam — ESP32-S3-A10 方案
GitHub · MIT 许可证
这个是最成功的方案。ESP32-S3-A10 开发板 + OV2640 摄像头(8225N 模块),16MB Flash,ESP-IDF v5.4.3 开发。功能上 MJPEG 流、帧差法移动检测、Web 配置界面、Prometheus 指标都有。说实话有块 LCD 屏幕调试方便很多。
AI_Thinker ESP32-CAM — 经典方案
GitHub · MIT 许可证
入门级选择,AI_Thinker ESP32-CAM 开发板到处都能买到,十几块钱一块。4MB Flash + 4MB PSRAM,跑 MJPEG 流没问题。亮点是支持 SD 卡存储和 NAS 上传(WebDAV/HTTP),还做了自适应暗场景检测——晚上会自动切换红外模式。缺点是没有屏幕调试不方便,Flash 只有 4MB。
MiBeeHomeCam — XIAO ESP32-S3 Sense
GitHub · GPL v3.0
最高级的方案。XIAO ESP32-S3 Sense 板子小巧精致,带 OV2640/OV3660 双摄像头支持,8MB Octal PSRAM 充分利用。亮点是 AVI 分段录制(不是简单的截图,是真的视频录制)、FTP/WebDAV 双协议上传、看门狗防死机、芯片温度监控、批量文件管理。适合长期稳定运行的场景。
选择建议
- 新手入门:选 AI_Thinker ESP32-CAM,便宜且资料多
- 日常使用:选 MiBeeCam,有屏幕调试方便
- 追求极致:选 XIAO ESP32-S3 Sense,功能最强
系统服务配置
为了稳定运行,用 systemd 管理 MiBeeNvr:
[Unit]
Description=MiBee NVR
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=nvr
ExecStart=/mnt/data/nvr/bin/mibee-nvr -config /mnt/data/nvr/mibee-nvr.yaml
WorkingDirectory=/mnt/data/nvr
Restart=on-failure
RestartSec=5
# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/mnt/data/nvr
PrivateTmp=true
[Install]
WantedBy=multi-user.target
保存到 /etc/systemd/system/mibee-nvr.service,然后 systemctl enable --now mibee-nvr 就完事了。自动开机启动,挂了也会自动重启。
开源地址
MiBeeNvr 已经开源,欢迎 star 和贡献:
- MiBeeNvr:
- 海外GitHub:github.com/Mi-Bee-Stud… (MIT 许可证)
- 国内Gitee:gitee.com/Mi-Bee-Stud…
- MiBeeCam:github.com/Mi-Bee-Stud… (MIT)
- AI_Thinker ESP32-CAM:github.com/Mi-Bee-Stud… (MIT)
- MiBeeHomeCam:github.com/Mi-Bee-Stud… (GPL v3.0)
文档比较全,部署和配置都有详细说明。
写在最后
说实话,折腾这个项目主要是因为对现有方案都不满意。云存储太贵,开源方案太重,商业产品又太封闭。自己写一个刚好:轻量、免费、可控。
对了,项目取名 MiBeeNvr,“Mi” 代表我(Mickey),“Bee” 代表?保密,“Nvr” 自然是网络录像机了。简洁好记,又有点意思。
如果你也有家用摄像头的需求,或者对 NVR 系统有什么想法,欢迎交流。有问题可以在 GitHub 上提 issue。