本地动态侦测与音频监控
在 ottor-laptop 上运行的零 Token 消耗本地安防系统,结合摄像头动态侦测、九宫格拼图推送和 whisper.cpp 语音识别。
概述
Rabbit 独立开发的本地安防监控系统,分为视觉侦测和音频监控两个独立服务。核心设计理念是”完全本地化,零 Token 消耗” — 图像变化检测使用 ImageMagick 本地算力,不调用任何 AI API;语音识别使用本地编译的 whisper.cpp。
视觉动态侦测服务
技术架构
每 5 秒循环:
fswebcam → current.jpg
ImageMagick compare → 计算 RMSE
RMSE > 4.5% → 存入待发送队列 + 打时间戳
每 30 秒汇总:
有变化 → montage 拼图 + curl 推送到 Mattermost
无变化 → 静默,不发消息
核心依赖
| 工具 | 用途 |
|---|---|
fswebcam | 摄像头抓帧 |
ImageMagick compare | RMSE 像素差异比对(零 Token) |
ImageMagick montage | 多图网格拼接 |
ffmpeg | 音频格式转换(WAV→MP3, 64kbps) |
curl | Mattermost REST API 推送 |
关键参数
| 参数 | 值 | 说明 |
|---|---|---|
| 拍照间隔 | 5 秒 | 平衡 CPU 和覆盖率 |
| RMSE 阈值 | 4.5% | 过滤光线闪烁/摄像头噪点 |
| 汇总间隔 | 30 秒 | 有变化才发,无变化静默 |
| 拼图布局 | 动态正方形 COLS=ceil(sqrt(N)) | 1张→1x1, 4张→2x2, 9张→3x3 |
| 图片间距 | 0(+0+0无缝拼接) | 监控分屏风格 |
部署方式
- 以
nohup后台进程或systemd用户服务运行 - Cron 最小粒度 1 分钟,无法满足 5 秒/30 秒需求,因此使用守护进程
- 脚本路径:
motion_detector_client.sh
调试历史
- ffmpeg 卡死问题:nohup 环境下 ffmpeg 读取 stdin 导致挂起 → 加
-nostdin+< /dev/null - 后台录音竞争条件:录音子进程未完成就开始合并 → 加
wait等待 - 误报过多:RMSE 提取逻辑 bug(awk 抓错字段) → 修正浮点数提取
- 拼图套拼图:底层脚本已做 montage,上层又拼了一次 → 优化底层动态布局
音频监控服务
工作流程
每 3 分钟循环:
arecord 录音 → WAV
ffmpeg silenceremove → 去静音
whisper.cpp (small 模型) → 本地转文字
文本带时间戳积累
每 30 分钟汇总:
LLM 总结 (gpt-5-mini) → Mattermost 推送
技术细节
| 组件 | 说明 |
|---|---|
| 录音工具 | arecord(ALSA) |
| 去静音 | ffmpeg silenceremove 滤镜 |
| 语音识别 | whisper.cpp + small 模型(~1-3GB,支持中英文) |
| 总结模型 | github-copilot/gpt-5-mini(便宜) |
| 录音间隔 | 3 分钟(原 1 分钟,降低 CPU 压力) |
| 汇总间隔 | 30 分钟 |
音频优化
- 原始 WAV:44.1kHz, 16bit, 双声道 → 30 秒约 5.2 MB
- gzip 压缩:→ 3.7 MB
- 最终方案:ffmpeg 转 64kbps MP3 → 约 240 KB(远小于 1 MB 目标)
两个服务的关系
| 维度 | 视觉侦测 | 音频监控 |
|---|---|---|
| Token 消耗 | 零 | 仅总结时少量 |
| 检测方式 | ImageMagick RMSE | whisper.cpp |
| 触发条件 | 画面变化 | 持续录音 |
| 推送内容 | 九宫格拼图 | 文字总结 |
初期视觉侦测包含音频录制,后因独立音频监控服务上线,从视觉侦测中移除了音频部分,两个服务各司其职。
与 GrowLog AI 的集成
视觉侦测抓拍的图片通过 motion_detector_client.sh 推送到 GrowLog AI 后端(端口 4000),每小时通过 growlog_report.js 生成合集图发送到 Mattermost。
相关页面
- ottor-pc-cloud-bot — 开发和维护者
- monitoring-and-cron — 定时任务体系