本地动态侦测与音频监控

在 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 compareRMSE 像素差异比对(零 Token)
ImageMagick montage多图网格拼接
ffmpeg音频格式转换(WAV→MP3, 64kbps)
curlMattermost 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

调试历史

  1. ffmpeg 卡死问题:nohup 环境下 ffmpeg 读取 stdin 导致挂起 → 加 -nostdin + < /dev/null
  2. 后台录音竞争条件:录音子进程未完成就开始合并 → 加 wait 等待
  3. 误报过多:RMSE 提取逻辑 bug(awk 抓错字段) → 修正浮点数提取
  4. 拼图套拼图:底层脚本已做 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 RMSEwhisper.cpp
触发条件画面变化持续录音
推送内容九宫格拼图文字总结

初期视觉侦测包含音频录制,后因独立音频监控服务上线,从视觉侦测中移除了音频部分,两个服务各司其职。

与 GrowLog AI 的集成

视觉侦测抓拍的图片通过 motion_detector_client.sh 推送到 GrowLog AI 后端(端口 4000),每小时通过 growlog_report.js 生成合集图发送到 Mattermost。

相关页面