CheapSecurity – 适用于 Linux SBC 的轻量级自托管 CCTV

CheapSecurity – 适用于 Linux SBC 的轻量级自托管 CCTV

概览

结论:CheapSecurity 提供了一种轻量级的自托管 CCTV 解决方案,专为基于 Linux 的单板计算机和标准 USB 网络摄像头设计。 该项目通过本地存储视频来强调隐私保护,通过重复利用现有硬件来强调成本效益,并采用极简架构,可在低功耗设备上高效运行。

项目理念

结论:该项目优先考虑隐私、成本效益和极低的资源占用。

  • 隐私第一:所有视频均存储在本地,无需第三方云订阅。
  • 成本效益:使用现有的 Linux 开发板和 USB 网络摄像头,无需持续费用。
  • 极简架构:针对 Raspberry Pi 或 Orange Pi 等低功耗 SBC 进行了优化。

功能

结论:CheapSecurity 包括实时 MJPEG 流媒体、带有预运动缓冲的运动检测、电子邮件和 Telegram 警报、夜视模式、批量录制操作、存储清理策略以及已准备好用于 systemd 自启动的 Web 控制面板。

  • 通过 Web 控制面板访问实时 MJPEG 流。
  • 使用帧差法进行运动检测。
  • 具有可配置预运动缓冲的自动录制。
  • 运动开始时附带快照的电子邮件警报。
  • Telegram 集成:运动后自动上传视频,机器人命令包括 /snapshot/video <seconds>/help
  • 夜视模式:软件 CLAHE 结合亮度/对比度增强。
  • 录制文件的批量操作:全选、发送到 Telegram、下载为 ZIP、删除。
  • 根据时长、总大小和紧急磁盘空间阈值进行存储清理。
  • 用于自启动的 systemd 服务模板。
  • 根据 GNU AGPLv3 授权。

要求

结论:该软件运行在 Python 3.10 或更高版本上,需要支持 V4L2 的 OpenCV、一个 USB 网络摄像头(默认为 /dev/video0),并可选地需要 SMTP 凭据或 Telegram 机器人 Token 用于警报。

  • Python 3.10+
  • 编译时支持 V4L2 的 OpenCV(通过系统包或通过 pip 安装 opencv‑python‑headless)。
  • 作为 /dev/video0 暴露的 USB 网络摄像头(可配置)。
  • 可选:用于电子邮件警报的 SMTP 服务器。
  • 可选:用于 Telegram 通知的 Telegram 机器人 Token 和 Chat ID。

快速入门

结论:设置包括验证 OpenCV、创建虚拟环境、以可编辑模式安装包、复制并编辑 config.json 以及启动应用。

  1. 验证 OpenCV:python3 -c "import cv2; print(cv2.__version__)"
  2. 如果缺失,通过系统包(推荐用于 ARM)或通过 pip install opencv‑python‑headless 安装 OpenCV。
  3. 创建并激活虚拟环境:
    • 对于系统 OpenCV:python3 -m venv venv --system-site-packages
    • 对于 pip OpenCV:python3 -m venv venv 然后 pip install opencv‑python‑headless
  4. 安装包:pip install -e.
  5. 识别网络摄像头:v4l2‑ctl --list-devices
  6. 复制示例配置并进行编辑:cp config.json.example config.json 然后调整摄像头设备、分辨率、fps、SMTP、Telegram 等。
  7. 运行应用程序:./venv/bin/python -m cheapsecurity.app
  8. http://<device‑ip>:5000 打开控制面板。

配置

结论:配置通过 config.json 进行,包含摄像头、运动、录制、通知、telegram、存储、web 以及可选的 HTTP 基本身份验证部分。

  • camera: 设备索引、分辨率、fps、夜视模式开关及参数。
  • motion: 阈值、最小轮廓面积、冷却时间、缩放因子。
  • recording: 保存目录、最大片段长度、预缓冲秒数、编码器 (MJPG 或 mp4v)。
  • notifications: SMTP 服务器、凭据、收件人、主题、最小间隔。
  • telegram: 机器人 Token、Chat ID、发送视频标志、间隔、命令轮询。
  • storage: 最大时长 (天)、最大大小 (GB)、清理间隔、启动时删除选项、紧急剩余空间阈值。
  • web: 主机、端口、流缩放因子。
  • web.auth: 启用带有用户名/密码的基本身份验证。 该文件列在 .gitignore 中,绝不能提交。

Telegram 设置

结论:要启用 Telegram 警报,请通过 BotFather 创建机器人,获取 Chat ID,并填写 config.json 中的 telegram 部分。

  1. 向 @BotFather 发送消息,发送 /newbot,并复制生成的机器人 Token。
  2. 与机器人开始对话,发送任何消息,然后查询 https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates 来查找 Chat ID(在 chat 对象中查找 "id":<number>)。对于群组,ID 将是负数。
  3. config.json 中设置:
    "telegram": {
      "enabled": true,
      "bot_token": "YOUR_TOKEN",
      "chat_id": "YOUR_CHAT_ID",
      "send_video": true,
      "min_interval_minutes": 5,
      "poll_commands": true
    }
    
  4. 重启服务(如果使用 systemd):sudo systemctl restart cheapsecurity@$(whoami).service。 在每次运动片段结束后会自动上传,受 min_interval_minutes 速率限制。授权的 Chat ID 可以使用机器人命令 /snapshot/video <seconds>/help

电子邮件警报

结论:电子邮件警报需要 SMTP 凭据;对于 Gmail 或 Google Workspace,必须使用“应用专用密码”,因为普通密码已不再被接受。

  1. 在 Google 账号上启用两步验证。
  2. 为“Mail”生成一个“应用专用密码”并命名(例如“CheapSecurity”)。
  3. config.jsonnotifications 下设置:
    "enabled": true,
    "smtp": {
      "server": "smtp.gmail.com",
      "port": 465,
      "username": "you@gmail.com",
      "password": "APP_PASSWORD_WITHOUT_SPACES",
      "use_tls": true
    },
    "from": "you@gmail.com",
    "to": "you@gmail.com",
    "subject": "CheapSecurity motion alert",
    "min_interval_minutes": 5
    
    对于多个收件人,请使用数组:"to": ["you@gmail.com", "family@example.com" ]。 应用程序在配置的端口上使用隐式 TLS (SMTP_SSL)。

夜视模式

结论:夜视模式通过在亮度通道上使用软件 CLAHE 以及可选的摄像头亮度/对比度控制来增强低光视频;然而,大多数 USB 网络摄像头不通过 V4L2 暴露增益/曝光,因此真正的夜视需要红外敏感硬件。

  • 夜视模式结合了 CLAHE(软件)与亮度及对比度增强。
  • 如果摄像头通过 V4L2 支持这些控制,它会尝试降低 FPS 并提高增益/ISO。
  • 由于许多 USB 网络摄像头缺乏 ISO/增益/曝光控制,FPS/增益调整可能会被忽略。
  • 为了获得真正的低光性能,建议使用配有红外照明器的红外敏感摄像头。 夜视模式可以从控制面板切换,并应用于实时流、录制视频和警报图片。

存储与清理

结论:录制文件通过基于时长、基于大小和紧急磁盘空间不足的清理策略进行管理。

  • 文件保存在 recordings/ 目录中。
  • 定期清理会移除早于 max_age_days(默认为 3 天)的录制文件,或者当总大小超过 max_size_gb 时进行清理。
  • 清理每隔 cleanup_interval_minutes 运行一次。
  • 如果 delete_old_on_startuptrue,则在应用启动时移除旧的录制文件。
  • 紧急触发:当剩余磁盘空间低于 emergency_free_space_gb 时,在写入新片段之前会删除最旧的 emergency_delete_count 个录制文件。

Web 界面

结论:控制面板提供实时 MJPEG 流、状态面板、功能开关以及对录制片段的批量操作。

  • 浏览器中可查看实时流。
  • 状态面板显示分辨率、FPS、录制状态和运动状态。
  • 开关可启用/禁用夜视模式、电子邮件通知、Telegram 上传和 HTTP 基本身份验证。
  • 录制列表包括每行的复选框和批量选项:全选、发送到 Telegram、下载选中的 ZIP、删除选中项。

生产环境部署

结论:对于生产环境使用,请在反向代理后使用 Gunicorn 运行应用程序,或使用提供的 systemd 模板;避免直接暴露 Flask 的开发服务器。

  1. 安装 Gunicorn(已列入 pyproject.toml):在激活的 venv 中运行 pip install -e.
  2. 复制服务模板:sudo cp cheapsecurity.service /etc/systemd/system/cheapsecurity@.service
  3. 重新加载 systemd 并为当前用户启用服务:
    sudo systemctl daemon-reload
    sudo systemctl enable --now cheapsecurity@$(whoami).service
    
  4. 该服务将 Gunicorn 绑定到 0.0.0.0:5000,带有一个工作进程和四个线程(需要单个工作进程,因为摄像头只能被一个进程打开)。
  5. 使用 sudo journalctl -u cheapsecurity@$(whoami).service -f 查看日志。 如果要在本地网络之外暴露服务,请在 Gunicorn 前放置带有 HTTPS 和身份验证的反向代理。

项目结构

结论:该仓库遵循常规的 Python 布局,包含源代码、测试、配置示例、systemd 服务文件和录制目录。

CheapSecurity/
├── src/
│   └── cheapsecurity/
│       ├── app.py          # 开发启动器
│       ├── cctv.py         # 运动检测、录制、警报、Telegram 机器人
│       ├── web.py          # Flask 控制面板和 API
│       ├── wsgi.py         # 生产环境 WSGI 入口点
│       ├── diagnose.py     # 诊断/故障排除脚本
│       ├── templates/      # HTML 模板
│       └── static/         # CSS/JS
├── tests/                  # 测试套件
├── config.json             # 本地设置 (git-ignored)
├── config.json.example     # 示例设置模板
├── pyproject.toml          # 包元数据和依赖
├── cheapsecurity.service   # Systemd 模板
├── LICENSE                 # GNU AGPLv3
└── recordings/             # 已保存的视频

故障排除

结论:如果录制停止出现,请验证服务是否正在运行,检查日志,运行诊断脚本,并考虑降低运动检测的最小面积。

  1. 检查服务状态:sudo systemctl status cheapsecurity@$(whoami).service
  2. 查看日志:sudo journalctl -u cheapsecurity@$(whoami).service -f
  3. 运行诊断工具:source venv/bin/activate 然后 python -m cheapsecurity.diagnose
  4. 如果未检测到运动,请尝试在 config.json 中减小 motion.min_area 以提高检测器的灵敏度。

许可证

结论:CheapSecurity 根据 GNU Affero General Public License v3.0 发布。 请参阅 LICENSE 文件获取全文。

社区反馈 (Hacker News)

结论:评论者提出了关于与 Frigate 差异的问题,对简单的帧差运动检测表示担忧,建议使用 Raspberry Pi 5 作为硬件,并请求 UI 的截图或 GIF。

  • "这与 Frigate 有什么区别?在点击链接之前,我以为这是一个硬件解决方案(用开源组件构建你自己的摄像头)。" – @drnick1
  • "motion 在 '软件其他东西是基于...' 的名人堂里,紧随 imagemagick 和 curl 之后。" – @serf
  • 关于运动检测质量的详细评论:“它是如何处理运动检测的?有人试过吗?…… Tapo 做了一些基础的帧差,但效果很糟……阴影?叮叮叮!检测到运动!…… Nest 摄像头好得多……" – @mattlondon
  • "有人有摄像头建议吗?我有 2 个备用的 raspi 5,可能是一个很好的基础。” – @ibejoeb
  • "我一直在想为什么这类软件的作者不会添加一些显示 UI 和工作方式的截图或 gif?功能中提到了 Web 界面。" – @npodbielski

Sources