Skip to content

margal2/CamPi

Repository files navigation

CamPi — ONVIF Camera DVR for Raspberry Pi

A self-hosted, bandwidth-conscious camera monitoring system. Continuously records a rolling 10-minute buffer from any RTSP/ONVIF camera and serves a modern web UI for on-demand snapshots and clip playback — zero data leaves your LAN.


Features

  • Rolling buffer — Continuous 10-minute (configurable) recording via ffmpeg
  • On-demand only — Snapshots and video served only when you click a button
  • Modern dark UI — Dashboard, gallery, clips browser, settings, diagnostics
  • Diagnostics — CPU, RAM, temperature, disk, recorder uptime, error log
  • Settings page — Camera IP, RTSP path, codec, retention, storage cap, MQTT
  • Plugin system — MQTT stub included; easy to add more (webhook, Telegram, etc.)
  • Systemd service — Auto-starts on boot, restarts on failure

Requirements

  • Raspberry Pi (any model with enough storage; Pi 4/5 recommended)
  • Raspberry Pi OS / Debian Bookworm (aarch64 or armhf)
  • Camera with RTSP stream (ONVIF compatible recommended)
  • Network access between Pi and camera

Quick Install

git clone https://github.com/yourname/campi  # or copy files to ~/campi
cd ~/campi
sudo bash install.sh

The installer will:

  1. Install ffmpeg and Python 3 via apt
  2. Create a Python virtual environment and install dependencies
  3. Create media/ subdirectories for clips, snapshots, exports
  4. Write a default config.json
  5. Install and start a systemd service (campi.service)

After install, open http://<raspberry-pi-ip>:8081 (default port; configurable in config.json).

Live preview supports WebRTC (via go2rtc, with aiortc fallback) and MJPEG; use the stream selector on the dashboard (Auto / Force WebRTC / Force MJPEG).


First-Time Setup

  1. Navigate to Settings in the web UI
  2. Enter your camera's IP address, username, password
  3. Set the RTSP stream path (check your camera manual; common values below)
  4. Click Test Connection — if a snapshot appears, you're good
  5. Save Settings — the recorder restarts automatically

Common RTSP paths by brand

Brand Typical path
Hikvision /Streaming/Channels/101
Dahua /cam/realmonitor?channel=1&subtype=0
Reolink /h264Preview_01_main
Amcrest /cam/realmonitor?channel=1&subtype=0
Generic /stream1 or /video1

File Layout

campi/
├── app.py              Main Flask application + API routes
├── recorder.py         ffmpeg-based rolling buffer recorder
├── config.py           Settings manager (JSON-backed)
├── config.json         Your settings (auto-created)
├── requirements.txt
├── install.sh
├── templates/
│   ├── base.html       Shared shell, sidebar, topbar
│   ├── index.html      Dashboard
│   ├── snapshots.html  Snapshot gallery
│   ├── clips.html      Clip browser
│   ├── settings.html   Settings form
│   └── diagnostics.html System health
├── plugins/
│   └── mqtt_plugin.py  MQTT extension stub
└── media/              Created at runtime
    ├── clips/          Rolling buffer segments (seg_*.mp4)
    ├── snapshots/      Captured frames (snap_*.jpg)
    └── exports/        Merged clip exports (export_*.mp4)

API Reference

Method Endpoint Description
GET /api/snapshot Capture fresh snapshot, return path
GET /api/snapshot/latest Path of latest saved snapshot
GET /api/snapshots/list List snapshots (?limit=N)
DELETE /api/snapshots/clear Delete all snapshots
GET /api/clips/list List buffer segments
GET /api/clips/last10 Export & return merged last-10-min clip
GET /api/settings Get current settings (passwords redacted)
POST /api/settings Update settings (JSON body)
GET /api/diagnostics Full system health JSON
POST /api/recorder/start Start recorder
POST /api/recorder/stop Stop recorder
POST /api/recorder/restart Restart recorder
GET /api/plugins List active plugins

Adding a Plugin

  1. Create plugins/myplugin.py with a register(app, config, recorder) function
  2. Import and call it from app.py (after recorder = Recorder(config))
  3. The plugin can publish routes, subscribe to events, or run background threads
  4. See plugins/mqtt_plugin.py for the pattern

Configuration Reference

Key Default Description
camera_ip 192.168.1.100 Camera LAN IP
camera_user admin RTSP/ONVIF username
camera_password admin RTSP/ONVIF password
rtsp_port 554 RTSP port
rtsp_path /stream1 Stream path on camera
rtsp_url_override "" Full RTSP URL (overrides all above if set)
buffer_minutes 10 Rolling buffer retention in minutes
segment_seconds 60 Length of each buffer segment file
video_codec copy copy = no re-encode; h264 / h265 = encode
snapshot_interval_s 0 Auto-snapshot interval (0 = on-demand only)
max_storage_mb 2048 Hard storage cap; oldest clips deleted first
web_port 8080 Flask listen port
autostart true Start recorder on app launch
mqtt_enabled false Enable MQTT plugin

Logs

journalctl -u campi -f          # Follow live logs
journalctl -u campi --since today

Service management

sudo systemctl start campi
sudo systemctl stop campi
sudo systemctl restart campi
sudo systemctl status campi

About

Nekdo nam paci okna a je celkem nigr

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors