Show HN: CheapSecurity – 轻量级自托管CCTV,适用于Linux单板计算机

Hacker News Top 工具

摘要

CheapSecurity 是一个轻量级、自托管的CCTV解决方案,适用于Linux单板计算机,提供注重隐私的家庭监控,支持运动检测、录像和Telegram提醒,无需云订阅。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/27 01:41

gmrandazzo/CheapSecurity

源代码:https://github.com/gmrandazzo/CheapSecurity

CheapSecurity

本项目提供了一个轻量级、自托管的 CCTV 解决方案,专为基于 Linux 的单板计算机(SBC)和标准 USB 摄像头设计。通过将所有视频数据完全控制在本地,它提供了一种经济实惠且注重隐私的家庭监控替代方案。

项目理念

  • 隐私优先:所有录像存储在本地,无需第三方云订阅,确保您的数据从不离开网络。
  • 经济高效:利用现有硬件(如闲置的 Linux 主板和 USB 摄像头)即可构建功能齐全的监控系统,无重复费用。
  • 极简架构:软件经过优化,可在低功耗设备上高效运行,即便在入门级硬件上也能保持高性能。

主要特性

  • 硬件无关性:与多种标准 USB 摄像头高度兼容。
  • 资源高效:专为基于 Linux 的主板(如 Raspberry Pi、Orange Pi 或类似 SBC)优化。
  • 数据主权:完全控制存储路径、保留策略和访问方式。
  • 简单部署:快速设置,易于维护。

功能

  • 实时 MJPEG 流 + 网页仪表板
  • 运动检测(帧差分法)
  • 自动录像(含运动前缓冲区)
  • 邮件提醒:运动开始时附带快照图片
  • Telegram 集成
    • 运动录像后自动上传视频
    • 机器人命令:/snapshot/video <秒数>/help
  • 夜间模式:低光增强(软件 CLAHE + 亮度/对比度增强)
  • 录像批量操作:全选、发送到 Telegram、下载 ZIP、删除
  • 存储清理:按时间、总大小和紧急低磁盘空间清理
  • systemd 自动启动就绪
  • 基于 GNU AGPLv3 许可

环境要求

  • Python 3.10 或更高版本
  • 支持 V4L2 的 OpenCV(请参阅下方安装选项)
  • USB 摄像头(默认 /dev/video0
  • 可选:Telegram 机器人令牌(用于 Telegram 通知)
  • 可选:SMTP 凭据(用于邮件提醒)

快速开始

  1. 确认 OpenCV 可用:

    python3 -c "import cv2; print(cv2.__version__)"
    

    如果未安装 OpenCV,您有两种选择:

    • 选项 A — 使用系统 OpenCV 包(推荐用于 ARM 主板,如 Odroid XU4,系统包通常针对主板进行了优化)。
    • 选项 B — 通过 pip 安装 OpenCV(在 x86/amd64 机器上或没有系统包时更方便)。由于应用不需要图形界面,请使用 opencv-python-headless
  2. 创建并激活虚拟环境,然后安装应用:

    选项 A:系统 OpenCV(推荐用于 ARM)

    这会创建一个可访问系统 site-packages 的 venv,使系统 cv2 在 venv 内可用。

    cd $HOME/CheapSecurity
    python3 -m venv venv --system-site-packages
    source venv/bin/activate
    pip install -e .
    

    选项 B:通过 pip 安装全部

    如果没有系统 OpenCV 或更倾向自包含的 venv,使用此选项。

    cd $HOME/CheapSecurity
    python3 -m venv venv
    source venv/bin/activate
    pip install opencv-python-headless
    pip install -e .
    

    注意: 在某些较旧的 ARM 主板上,pip 的 opencv-python-headless wheel 可能不可用或速度较慢。如果出现这种情况,请改用发行版包管理器安装 OpenCV 并使用选项 A。

  3. 查找您的摄像头设备(通常为 /dev/video0):

    v4l2-ctl --list-devices
    
  4. 复制 config.json.exampleconfig.json 并编辑:

    cp config.json.example config.json
    nano config.json
    
    • 设置摄像头设备、分辨率和帧率
    • 如需邮件提醒,填写 SMTP 凭据
    • 如需 Telegram 上传,填写 Telegram 机器人令牌和聊天 ID

    安全: config.json 已列入 .gitignore,绝不可提交。该文件包含密码和令牌。始终编辑 config.json,而非 config.json.example。如果添加新设置,请同时更新两个文件以保持示例文件同步。

  5. 运行应用:

    ./venv/bin/python -m cheapsecurity.app
    
  6. 在浏览器中打开仪表板:

    http://<主机IP>:5000
    

配置

编辑 config.json

部分说明
cameradeviceV4L2 设备索引(0 = /dev/video0
camerawidth, height, fps捕获分辨率与帧率
cameranight_mode启用低光增强
cameranight_mode_fps夜间模式目标 FPS(摄像头可能忽略)
cameranight_mode_gain夜间模式目标模拟增益(摄像头可能忽略)
cameranight_mode_brightness夜间模式亮度增强
cameranight_mode_contrast夜间模式对比度增强
motionthreshold像素差异阈值(0-255)
motionmin_area触发运动的最小轮廓面积(全分辨率像素)
motioncooldown_seconds运动停止后继续录制的秒数
motionscale运动检测的降采样因子(节省 CPU)
recordingdir视频保存目录
recordingmax_duration_seconds单个片段的最大长度
recordingpre_buffer_seconds运动前包含到片段中的秒数
recordingcodec首选 FourCC 编解码器(MJPG 低 CPU,mp4v 文件更小)
notificationsenabled运动时发送邮件提醒
notificationssmtpSMTP 服务器、端口、用户名、密码、TLS
notificationsfrom, to, subject邮件发件人/收件人/主题(多个收件人使用 ["a@...", "b@..."]
notificationsmin_interval_minutes提醒邮件最小间隔时间
telegramenabled运动录像后发送视频到 Telegram
telegrambot_token, chat_idTelegram Bot API 令牌和目标聊天
telegramsend_video是否自动上传视频文件
telegrammin_interval_minutesTelegram 上传最小间隔时间
telegrampoll_commands启用 /snapshot/video/help 机器人命令
storagemax_age_days删除早于该天数的录像(默认 3 天 = 72小时)
storagemax_size_gb如果总大小超过此值,删除最旧文件
storagecleanup_interval_minutes存储清理运行间隔
storagedelete_old_on_startup若为 false,应用重启时保留旧录像
storageemergency_free_space_gb若剩余磁盘空间低于此值,在录制新视频前删除旧录像
storageemergency_delete_count紧急清理时删除的最旧录像数量
webhost, port仪表板绑定地址和端口
webstream_scale实时流的降采样因子(节省带宽/CPU)
web.authenabled, username, password可选的 HTTP 基本认证

Telegram 设置

1. 创建机器人

  1. 打开 Telegram,向 @BotFather (https://t.me/BotFather) 发送消息。
  2. 发送 /newbot,按提示选择显示名称和用户名。
  3. 复制 机器人令牌(格式类似 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)。
  4. 保持令牌机密——任何持有该令牌的人都可以控制您的机器人。

2. 获取您的聊天 ID

  1. 用新机器人开始私聊,发送任意消息(例如 /start)。
  2. 在浏览器中打开以下 URL,将 <您的令牌> 替换为真实令牌:
    https://api.telegram.org/bot<您的令牌>/getUpdates
    
  3. 查找 "chat":{"id":123456789。该数字即为您的 聊天 ID
    • 如果 getUpdates 为空,请向机器人再发送一条消息后刷新。
    • 如果使用群组聊天,先将机器人添加到群组并在群中发送消息;群组的聊天 ID 为负数。
  4. 复制聊天 ID,包括群组的 - 号。

3. 配置应用

填写 config.json 中的 telegram 部分:

"telegram": {
  "enabled": true,
  "bot_token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz",
  "chat_id": "123456789",
  "send_video": true,
  "min_interval_minutes": 5,
  "poll_commands": true
}

然后重启服务:

sudo systemctl restart cheapsecurity@$(whoami).service

自动上传

运动片段保存后,视频会自动上传到您的 Telegram 聊天。上传受 min_interval_minutes 限制速率。

机器人命令

从您配置的聊天发送:

  • /snapshot — 接收当前摄像头图片
  • /video 10 — 录制并发送 10 秒视频(1–60 秒,默认 10)
  • /help — 列出命令 机器人仅响应您配置的 chat_id运动优先: 如果系统因检测到运动已正在录像,/video 请求不会中断它。机器人会回复正在录制运动视频,并将在完成后自动上传。

邮件提醒

config.json 中配置 notifications 部分。附件为运动开始时拍摄的图片。提醒受 min_interval_minutes 限制速率。

Gmail / Google Workspace 设置

Google 已不再允许“安全性较低的应用”使用常规 Gmail 密码。您必须创建一个应用密码

  1. 在 Google 账户中启用两步验证
    • https://myaccount.google.com/signinoptions/two-step-verification
  2. 创建应用密码:
    • 前往 https://myaccount.google.com/apppasswords
    • 选择应用:Mail
    • 选择设备:Other (Custom name) — 输入 “CheapSecurity”
    • 点击 Generate 并复制 16 位密码(例如 abcd efgh ijkl mnop)。
  3. config.json 中设置:
    "notifications": {
      "enabled": true,
      "smtp": {
        "server": "smtp.gmail.com",
        "port": 465,
        "username": "[email protected]",
        "password": "abcdefghijklmnop",
        "use_tls": true
      },
      "from": "[email protected]",
      "to": "[email protected]",
      "subject": "CheapSecurity motion alert",
      "min_interval_minutes": 5
    }
    
    • password 字段中使用应用密码(无空格),而不是您的 Google 账户密码。
    • 对于 Google Workspace 账户,用户名通常为完整的电子邮件地址。
    • 应用使用隐式 TLS(SMTP_SSL)在您配置的端口上。Gmail 在 465 端口接受此方式。

多个收件人

"to": [ "[email protected]", "[email protected]" ]

夜间模式

夜间模式结合了:

  • 软件增强(在 L 通道上使用 CLAHE)
  • 摄像头亮度/对比度增强
  • 尝试降低 FPS 并提高增益/ISO(如果摄像头支持)

可通过仪表板切换。增强效果应用于实时流、录像和提醒图片。

重要: 大多数 USB 摄像头不通过 V4L2 暴露 ISO/增益/曝光控制,因此 FPS/增益调整可能被忽略。真正的夜视需要红外感应摄像头红外照明灯

存储与清理

  • 录像保存在 recordings/ 目录中。
  • 周期性清理时删除早于 max_age_days 的录像(而非启动时,除非 delete_old_on_startuptrue)。
  • 如果剩余磁盘空间低于 emergency_free_space_gb,在开始录制新视频前删除最旧的 emergency_delete_count 个录像。
  • 周期性清理时删除早于 max_age_days 或超过 max_size_gb 的录像。

Web 界面

  • 实时流
  • 状态面板(分辨率、FPS、录像状态、运动状态)
  • 设置开关:夜间模式、邮件通知、Telegram 上传、内置基本认证
  • 录像列表(含每行复选框及批量操作):
    • 全选
    • 发送到 Telegram
    • 下载所选(ZIP)
    • 删除所选

生产部署

不要将 Flask 开发服务器暴露到公网。请使用 Gunicorn 配合内置认证或您信赖的反向代理。

1. 安装 Gunicorn

它已在 pyproject.toml 中定义:

cd $HOME/CheapSecurity
source venv/bin/activate
pip install -e .

2. 使用 systemd + Gunicorn 运行

从用户 shell 复制服务模板并启用:

sudo cp cheapsecurity.service /etc/systemd/system/[email protected]
sudo systemctl daemon-reload
sudo systemctl enable --now cheapsecurity@$(whoami).service

这会使 Gunicorn 绑定到 0.0.0.0:5000,使用一个工作进程和四个线程,以便仪表板和流直接在您的网络上可访问。仅使用一个工作进程,因为摄像头必须由单个进程打开。

安全: 若要暴露到公网,请在 Gunicorn 前放置一个带有 HTTPS 和认证的反向代理。如果仅限本地访问,请保持内置认证开启。

查看日志:

sudo journalctl -u cheapsecurity@$(whoami).service -f

项目结构

CheapSecurity/
├── src/
│   └── cheapsecurity/          # Python 包
│       ├── app.py              # 开发启动器
│       ├── cctv.py             # 运动检测、录像、提醒、Telegram 机器人
│       ├── web.py              # Flask 仪表板和 API
│       ├── wsgi.py             # 生产 WSGI 入口
│       ├── diagnose.py         # 诊断/故障排查脚本
│       ├── templates/          # HTML 模板
│       └── static/             # CSS/JS
├── tests/                      # 测试套件
├── config.json                 # 本地设置(已被 gitignore,绝不提交)
├── 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. 如果未检测到运动,尝试降低 motion.min_area 值。

许可协议

本项目基于 GNU Affero General Public License v3.0 或更高版本(AGPLv3)许可。详见 LICENSE

相似文章

我用过的最佳免订阅家庭安全摄像头

Wired

Wired 评测了最佳免订阅家庭安全摄像头,这些摄像头将录像存储在本地,重点推荐了 Eufy、Synology、TP-Link Tapo 和 Aqara 等注重隐私用户的首选品牌。

Defcon 上最酷的反监控工具 [视频]

Hacker News Top

在 Defcon 大会上,独立黑客们展示了多种经济实惠、开源的工具,用于检测智能摄像头、伪基站等监控技术,让反监控手段变得更易为公众所用。