CLI 用户手册
适用于 MiBeeNvr v0.13.0 · 命令名
mibee-nvr(预编译包可能带架构后缀,如mibee-nvr-amd64)
MiBee NVR 是「单二进制 + 子命令」形态:不带子命令直接运行即启动服务器,带子命令则执行对应的管理工具后退出。
mibee-nvr # 启动 NVR 服务器(长驻进程)
mibee-nvr <子命令> # 执行管理工具,完成后退出
mibee-nvr -version # 打印版本
启动服务器
mibee-nvr -config mibee-nvr.yaml
| 参数 | 默认值 | 说明 |
|---|---|---|
-config |
mibee-nvr.yaml |
配置文件路径 |
-version |
— | 打印版本后退出 |
没有配置文件时启动会自动初始化,浏览器打开后进入初始化向导。
子命令总览
| 子命令 | 用途 |
|---|---|
init |
交互式生成配置文件和管理员账户 |
hash-password |
生成密码哈希 |
health |
HTTP 健康探测(Docker HEALTHCHECK 用) |
encrypt-config |
加密配置中的明文密码 |
validate-config |
部署前校验配置文件(退出码 0 = 可启动) |
download-model |
下载浏览器端 AI 检测模型 |
merge-cameras |
合并两个重复的摄像头条目 |
timelapse-merge |
把任意时段的录像批量转成延时合并产物 |
eval-replay |
离线回放活动评分 / 自适应门控,调参前后对照 |
repair |
数据修复工具集(9 个子命令) |
cleanup |
按日期 / 孤儿文件清理录像 |
offload |
S3 冷备队列计数与本地副本逐出 |
update |
版本检查与裸机升级执行 |
gen-gb35114-certs |
签发 GB35114 A 级试点证书(仅 -tags gb35114 构建) |
init — 生成配置
生成配置文件并设置管理员账户:
mibee-nvr init --password 你的密码
| 参数 | 默认值 | 说明 |
|---|---|---|
--password |
(交互输入) | 管理员密码,至少 8 位;未提供时在终端提示输入 |
--username |
admin |
管理员用户名 |
--data-dir |
/var/lib/mibee-nvr |
数据目录(录像 + 数据库) |
--listen |
:9090 |
HTTP 监听地址 |
--config |
mibee-nvr.yaml |
配置文件输出路径 |
--force |
— | 覆盖已存在的配置文件(否则报错退出) |
生成的配置默认值:片段时长 30s、保留 30 天、FTP 2121、WebDAV /dav。
也可以完全跳过
init:无配置启动 → Web 向导完成(参阅初始化向导)。
hash-password — 生成密码哈希
mibee-nvr hash-password '你的密码'
# 输出: $2a$10$...
把输出粘贴到配置文件的 auth.password_hash 字段,适合在脚本中批量初始化。
health — 健康检查
对本地服务做 HTTP 探测(GET /api/health),成功退出码 0,失败退出码 1 —— 供 Docker HEALTHCHECK / systemd watchdog 使用:
mibee-nvr health # 探测 :9090
mibee-nvr health --addr :9191 # 显式指定地址
mibee-nvr health --config /data/mibee-nvr.yaml # 从配置读取 server.listen
地址解析优先级:--addr > --config 中的 server.listen > Docker 自动探测(读 NVR_DATA_DIR 数据目录下的配置)> 默认 :9090。host 网络模式下改过监听端口时无需加参数,命令会自动找到真实端口。
encrypt-config — 加密敏感字段
把配置文件中的明文敏感字段(摄像头密码等)就地加密:
mibee-nvr encrypt-config --config mibee-nvr.yaml
输出加密了哪些字段;已是密文或为空的字段会跳过。加密后服务照常读取,人工无法直接看到密码明文。
validate-config — 校验配置文件
手工编辑 YAML 后的部署前冒烟检查:走与服务器启动完全相同的 Load → Validate 流水线,但不启动任何东西。退出码 0 = NVR 用这份配置能正常启动,1 = 会启动失败(在 systemd 里就是崩溃重启循环):
mibee-nvr validate-config
mibee-nvr validate-config --config /data/mibee-nvr.yaml
# OK /data/mibee-nvr.yaml — the NVR would boot on this config
| 参数 | 默认值 | 说明 |
|---|---|---|
--config <path> |
mibee-nvr.yaml |
要校验的配置文件路径(与裸 mibee-nvr 启动时的默认路径一致) |
校验覆盖取值区间、格式与缺失必填项等非法值,并暴露加载阶段的悬空引用问题 —— 2026-09-11 M5 事故正是手改 YAML 删掉 vision 实例后摄像头仍引用它,服务重启循环了约两分钟。改完配置先跑一遍再重启服务。
download-model — 下载 AI 模型
下载浏览器端 AI 检测所需的 ONNX 模型(YOLOv11-nano,约 5.4MB,来自 Ultralytics 官方发布)到 Web 静态目录:
mibee-nvr download-model --config mibee-nvr.yaml
内置 5 次指数退避重试和大小 / 完整性校验,适合离线环境预下载后随包分发。模型用于浏览器端 AI 检测。
merge-cameras — 合并摄像头
把两个重复的摄像头条目端到端合并(例如同一台设备被 ONVIF 发现和小米接入各加了一次):
# 先预览(默认 dry-run)
mibee-nvr merge-cameras --source cam-old --target cam-new
# 确认无误后执行
mibee-nvr merge-cameras --source cam-old --target cam-new --execute
执行步骤:备份数据库 → 改写录像 / 事件的摄像头归属与文件路径 → 移动录像文件 → 从配置中移除源摄像头 → 删除源摄像头数据库行。任一步失败自动回滚。
| 参数 | 说明 |
|---|---|
--source <id> |
源摄像头 ID(数据搬离方,合并后删除) |
--target <id> |
目标摄像头 ID(数据并入方,保留) |
--execute |
真正执行(默认 dry-run 仅预览) |
--force |
存在孤儿记录时仍然继续 |
--config <path> |
配置文件路径(默认 mibee-nvr.yaml) |
timelapse-merge — 录像转延时合并
把任意时段、任意摄像头的既有录像(H264 / H265 / AVI / MJPEG)批量转成周期延时合并产物 —— POST /api/timelapse/{id}/merge 的 CLI 版,进程内直连数据库执行。采样间隔、输出帧率、源录像删除都是本次运行覆盖值,不改摄像头配置:
# 预览:所有 JPEG 摄像头、2026-08-26 起的全部录像
mibee-nvr timelapse-merge --camera all --encoding jpeg --start 2026-08-26
# 执行:1 秒采样 + 合并成功后删除源录像
mibee-nvr timelapse-merge --camera all --encoding jpeg --start 2026-08-26 \
--interval 1s --delete-sources --execute
行为要点:
- 按窗口(默认
natural-day,即自然日)枚举日期范围,逐窗口执行;已完成的窗口自动跳过(可安全重跑续传),尚未闭合的窗口跳过。 --delete-sources仅在对应窗口合并成功后删除源录像(DB 行 + 文件),MiBeeVision 处理中的录像始终跳过。- 命令可在 NVR 运行中执行(WAL 并发模型,与 cleanup/repair 一致);但 timelapse 已启用的摄像头会被拒绝 —— 其窗口归服务器合并调度器所有,需
--force或停服后运行。 - 执行时自动自降级(nice 19 + IO best-effort 最低档,
--no-throttle关闭):大窗口合并与在线录像平权竞争会拖垮录像(2026-09-12 事故:load 8-13 持续 4.5h,录像 17→10 台),事后 renice 无法挽回。 - 目录形源删除自动限速(每 200 个文件暂停
--delete-throttle):MJPEG/延时帧目录的百万级小文件 unlink 会让 ext4 日志(jbd2)饱和数十分钟,拖慢所有磁盘 IO。 - 合并中间产物(帧提取/复制目录)写在存储根
<root>/periodic-merge/tmp/下,不再用系统/tmp(1s 采样全天窗口约需 3.5-7GB,小根分区会 ENOSPC);合并输出采用流式生成(#747),内存占用与窗口大小无关。中断(Ctrl-C/崩溃)遗留的中间目录由 NVR 服务端启动清扫回收(宽限期storage.periodic_temp_grace_s,默认 24h,见 配置)。
| 参数 | 默认值 | 说明 |
|---|---|---|
--camera <ids|all> |
(必填) | 逗号分隔摄像头 ID 或 all |
--encoding <enc> |
— | 配合 --camera all 按编码过滤(如 jpeg) |
--start <YYYY-MM-DD> |
(必填) | 起始窗口日期(配置时区) |
--end <YYYY-MM-DD> |
昨天 | 结束窗口日期(含) |
--duration <label> |
natural-day |
窗口大小:8h / 12h / 24h / 7d / 30d 等 |
--interval <dur> |
摄像头 timelapse.interval,缺省 30s |
帧采样间隔(如 1s) |
--fps <n> |
摄像头 merge_output_fps,缺省 10 |
输出播放帧率 |
--delete-sources / --no-delete-sources |
摄像头 delete_recordings_after_merge |
覆盖本次运行的源录像删除开关 |
--delete-throttle <dur> |
200ms |
删除目录形源(MJPEG/延时帧目录)时的分块暂停,0 关闭 |
--execute |
dry-run | 真正执行 |
--force |
— | NVR 运行中仍处理 timelapse 已启用的摄像头 |
--no-throttle |
— | 跳过启动时自动自降级(nice 19 + IO best-effort) |
--config <path> |
mibee-nvr.yaml |
配置文件路径 |
eval-replay — 离线回放评估
把离线活动评分器或自适应录像门控在一组已完成录像的黄金语料(corpus)上重放,输出逐文件明细与按标签聚合的均值 —— 自适应录像(recording_mode: adaptive)调参先离线拿到调参前/后对照表,再上真实机器。详见自适应录像。
# 评分器回放(默认)
mibee-nvr eval-replay --corpus corpus.json
# 门控回放(默认参数)
mibee-nvr eval-replay --corpus corpus.json --gate
# 门控回放 + 候选参数对照(候选与默认并排两列)
mibee-nvr eval-replay --corpus corpus.json --gate --videoexit=false
corpus 是 JSON 数组,路径可写绝对路径或相对清单文件;标签自由(框架约定 rain / lowbitrate / static / active):
[{"path": "/mnt/data/nvr/cam-yard/seg.mp4", "camera": "cam-yard", "label": "rain"}]
| 参数 | 默认值 | 说明 |
|---|---|---|
--corpus <path> |
(必填) | 语料清单 JSON 路径 |
--gate |
评分器 | 回放自适应门控而非评分器 |
--fps <n> |
按文件推算 | 门控回放帧率(0 = frames/duration 推算) |
--spike <f> |
— | 候选门控:spike_factor |
--noisefloor-bytes <n> |
— | 候选门控:显式 noise_floor_bytes |
--autonoise true|false |
— | 候选门控:auto_noise_floor |
--videoexit true|false |
— | 候选门控:video_exit |
repair — 数据修复
针对运行期数据问题的一组修复工具,直接操作数据库。建议优先在服务停止时运行(运行中也安全 —— WAL 模式支持并发读,但大修停服更稳)。
mibee-nvr repair <子命令> [--dry-run | --execute] [--config mibee-nvr.yaml]
所有子命令默认 dry-run(只报告将改动什么),加 --execute 才真正落库。
| 子命令 | 用途 |
|---|---|
duration |
修复 duration=0 的录像:重新探测视频文件恢复真实时长(--prune 顺带删除无法修复的记录) |
merge-status |
重置「已合并」标记 —— 合并产物文件丢失时回退为未合并 |
fragments |
清理合并引擎放弃的碎片段(不兼容 / 失败) |
delete-by-format |
按格式批量删除某摄像头的录像,保留指定格式(如只留延时摄影段) |
prune-intermediate-mp4 |
清理已并入周期合并产物(8h/24h/7d/30d)的滚动合并中间 .mp4 |
reclaim-orphan-merges |
回收 Web UI 删除录像后遗留的孤儿合并 .mp4(只动无引用产物,不碰源段) |
normalize-endpoints |
规范化 ONVIF endpoint(省略默认端口 / 小写 / 去尾斜杠),修复去重查询不匹配 |
mjpeg-containerize |
把旧版目录形态 MJPEG 段(每帧一个 JPEG 文件)转成单文件 AVI 容器(#761);逐段「转换 → 校验 → 落库 → 删源」,校验失败则行不动 |
timelapse-mjpeg |
重写样本带「双重 JPEG 头」的 MJPEG 周期合并产物(不合规范的 RTSP 发送方把完整 JPEG 塞进 RFC 2435 载荷、解包器又前置了合成头,浏览器拒收):无损抽取每个样本内层完整 JPEG 重封装,并刷新 DB 行的帧数 / 大小;可抢救帧数不足 25%(源数据在流尾截断)时跳过留给运维决断 |
示例:
# 预览将修复多少条 duration=0 的录像
mibee-nvr repair duration
# 执行修复,并删除探测失败的坏文件
mibee-nvr repair duration --execute --prune
mjpeg-containerize 专用参数:
| 参数 | 默认 | 说明 |
|---|---|---|
--camera <id> |
全部 | 只转换该摄像头的段 |
--limit N |
全部 | 最多转换 N 段 |
--keep-old |
关 | 转换后保留源帧目录 |
--busy-retries N |
3 |
DB 行翻转遇 SQLITE_BUSY 的重试次数(0 = 单次尝试,不重试) |
--busy-wait <dur> |
2s |
BUSY 重试的线性退避基数(Go 时长格式,如 500ms、5s) |
CLI 与运行中的 NVR 共享 WAL 库——磁盘饱和时服务端合并事务可能拖过 busy_timeout,此时调大这两个值;快盘上默认 3 次的最坏等待是纯浪费,可调小(照 timelapse-merge --delete-throttle 先例)。
# 预览(默认 dry-run)
mibee-nvr repair mjpeg-containerize --camera yard-esp32
# 执行;磁盘饱和时放宽 BUSY 重试
mibee-nvr repair mjpeg-containerize --execute --busy-retries 5 --busy-wait 5s
cleanup — 录像清理
绕过保留策略的手动清理工具,同时删除文件、数据库行和孤儿 AI 事件:
# 预览删除某日期之前的录像
mibee-nvr cleanup --before 2026-08-01 --dry-run
# 执行
mibee-nvr cleanup --before 2026-08-01
# 清理孤儿文件(磁盘上有视频文件但数据库无记录)
mibee-nvr cleanup --orphans --dry-run
mibee-nvr cleanup --orphans
| 参数 | 说明 |
|---|---|
--before YYYY-MM-DD |
删除此日期之前的录像(文件 + DB 行 + AI 事件) |
--orphans |
扫描磁盘删除数据库无记录的视频文件(.mp4/.mkv/.avi/.dav/.flv) |
--dry-run |
只统计不删除(强烈建议先跑一遍) |
--config <path> |
配置文件路径(默认 mibee-nvr.yaml,用于定位存储根目录和数据库) |
日常清理请优先使用保留策略(
cleanup.retention_days);本命令适合迁移后瘦身、异常善后等场景。
offload — 对象存储冷备队列
storage.remote(S3 兼容对象存储冷备)的运维面。两个子命令都要求配置里 storage.remote.enabled: true,否则直接报错退出:
# 上传队列各状态计数 + 积压(pending+uploading)
mibee-nvr offload status
# 逐出已确认上传录像的本地副本(默认 dry-run 仅报告)
mibee-nvr offload evict --all-uploaded
mibee-nvr offload evict --camera front-door
# 真正执行
mibee-nvr offload evict --all-uploaded --execute
行为要点:
evict只删已确认上传(uploaded)录像的本地文件;--execute删除前对每个对象重新做一次远端HeadObject复核,复核失败该项 REFUSED、什么也不删。远端对象永不删除(远端清理交给 bucket lifecycle 策略)。- 默认按
storage.remote.evict.after_days计算可逐出窗口;after_days: 0(仅上传模式)必须显式加--all-uploaded才会逐出。 - 可对运行中的服务执行(WAL 并发读);大批量建议选空闲时段。
| 参数 | 说明 |
|---|---|
--all-uploaded |
无视 evict.after_days,纳入所有已确认上传 |
--camera <id> |
只处理该摄像头 |
--execute |
真正删除本地文件(默认 dry-run 报告) |
--config <path> |
配置文件路径(默认 mibee-nvr.yaml) |
整体管线(outbox 状态机、上传宽限、backlog 上限)与配置见对象存储冷备。
update — 版本检查与裸机升级
裸机(bare-metal systemd)部署的升级执行层(#647),配合 mibee-nvr-update.service root helper(polkit 授权)使用。--check 只读感知层,升级必须 root:
# 只看当前/最新版本与部署形态,不改任何东西
mibee-nvr update --check
# 手动升级到最新稳定版(需要 sudo)
sudo mibee-nvr update
sudo mibee-nvr update --version v0.13.0
# root helper 入口(update 服务的 ExecStart;请求文件由应用写入、只消费一次,任意结果都会被删除)
mibee-nvr update --apply-request /var/lib/mibee-nvr/update-request.json
| 参数 | 默认值 | 说明 |
|---|---|---|
--check |
— | 只打印 current / latest / available / deployment,不执行升级 |
--version <tag> |
最新稳定版 | 目标 release tag |
--apply-request <file> |
— | 消费应用写好的升级请求文件(helper 入口) |
--config <path> |
mibee-nvr.yaml |
配置文件路径 |
- 升级制品经 sha256 + ed25519 校验,升级后过健康门(对配置的
server.listen做本地健康探测),失败自动回滚到旧二进制。 - 仅限 Linux 裸机:Docker 部署永久禁用(容器不可变,用 Watchtower /
docker compose pull),Windows / macOS 桌面构建同样拒绝(自更新会错拿到 linux 二进制)。 update.download_mirror可把制品下载切到镜像源(版本检查仍走 GitHub API)。
自动升级开关(update.auto_apply)、服务与 polkit 安装见自动升级。
gen-gb35114-certs — 签发 GB35114 试点证书
仅存在于 -tags gb35114 构建(默认构建运行会提示重建方式)。为 GB35114 A 级安全注册签发自签试点材料:SM2 平台身份 + 由平台签发的设备身份,输出布局直接对应 gb28181.security35114 的三个路径键。详见 GB28181 指南 — GB35114 安全增强。
mibee-nvr gen-gb35114-certs --platform-id 34020000002000000001 \
--device-id 34020000001320000001,34020000001320000002 \
--out-dir gb35114-certs [--days 3650]
环境变量速查
| 变量 | 说明 |
|---|---|
NVR_PASSWORD |
首次启动设置管理员密码(无密码时 API 返回 503) |
NVR_LISTEN_PORT |
覆盖监听端口 |
NVR_DATA_DIR |
Docker 数据目录(health 子命令自动探测用) |
NVR_UID / NVR_GID |
容器内运行用户(对齐宿主目录权限) |