A Raspberry Pi–based alternative to Ring-style cameras. This project monitors your space with motion-triggered recording, with the goal of connecting to a mobile app over VPN for real-time viewing.
RaspiObjRec runs on a Raspberry Pi and handles:
- Motion detection — Continuously watches the camera and only records when motion is detected.
- Video + audio — Saves video (and optional microphone audio) for each motion event.
- Format conversion — Converts recordings to MP4 for easier playback and sharing.
- Live MJPEG API — Optional
stream_server.pyserves/healthand/streamfor RaspiMobileConnect on the same LAN or over a private VPN.
| Stage | Description |
|---|---|
| Current | Camera runs continuously; saves video (and audio when configured) on motion; converts AVI → MP4. |
| Near term | Organize clips (e.g. by date/event) and optionally send frames to Roboflow for habit/behavior analysis of your dog. |
| VPN + mobile | Set up a VPN (e.g. WireGuard or Tailscale) so the Pi is reachable from outside your network. |
| Live view | MJPEG stream from stream_server.py → RaspiMobileConnect Live Feed tab (base URL + token from env). |
The RaspiMobileConnect app (see the RaspiMobileConnect folder in this workspace) is the intended mobile client for that live view and future controls.
- Raspberry Pi 4 (4GB)
- Logitech C270 HD Webcam
- 64GB MicroSD card (expand storage if footage outgrows it)
- Case (e.g. Miuzei-style Raspberry Pi case)
- Python — Main application logic
- OpenCV — Camera capture and motion detection
- FFmpeg — AVI → MP4 conversion
- sounddevice / soundfile — Microphone recording when motion is detected
- Roboflow (planned) — Computer vision and habit analysis
- Flask — HTTP server for MJPEG live view (
stream_server.py)
- System: install FFmpeg (e.g.
sudo apt install ffmpeg). - Python: create a venv, install deps:
If you use microphone recording, you may need system libs (e.g.
python3 -m venv objrecvenv source objrecvenv/bin/activate # or `objrecvenv\Scripts\activate` on Windows pip install -r requirements.txt
libsndfile1,portaudio19-dev). - Config: copy
.env.exampleto.envand set paths and options (see comments in.env.example). - Motion detection:
python main.py
Recordings are written to OUTPUT_DIR as AVI, then converted to MP4 (and optionally WAV for audio).
Separate process that exposes:
| Endpoint | Purpose |
|---|---|
GET /health |
JSON status (status, service, camera_index; includes camera_error if the camera fails). |
GET /stream |
MJPEG over HTTP (multipart/x-mixed-replace). |
Auth: If STREAM_TOKEN is set in .env, send Authorization: Bearer <token> or append ?token=<token> to the URL.
Camera exclusivity: Most USB cameras allow one capturing process. Do not run main.py and stream_server.py on the same CAMERA_INDEX at the same time. For testing the app, stop main.py and run:
python stream_server.pyBind address and port come from STREAM_HOST and STREAM_PORT (defaults 0.0.0.0:8765). Set STREAM_TOKEN for anything beyond quick LAN tests.
- Give the Pi a stable address (DHCP reservation or static IP on your router).
- On the Pi:
python stream_server.pywith.envconfigured. - On your phone’s browser, open
http://<pi-lan-ip>:8765/health(and/streamto confirm video). - In RaspiMobileConnect, set
EXPO_PUBLIC_STREAM_BASE_URL=http://<pi-lan-ip>:8765(see that project’s README), restart Expo, open the Live Feed tab.
Goal: the phone reaches the Pi at a private address (e.g. 10.x.x.x) so the same stream URL shape works as on LAN.
- WireGuard (self-hosted): Install WireGuard on the Pi, configure keys and
AllowedIPs, forward UDP (e.g.51820) from your router to the Pi if you need inbound connections. Point the app’sEXPO_PUBLIC_STREAM_BASE_URLat the Pi’s VPN IP (not the public IP). - Tailscale (or similar): Install on Pi and phone; use the Pi’s Tailscale IP in
EXPO_PUBLIC_STREAM_BASE_URL.
Hardening: Use ufw on the Pi: allow SSH and VPN; avoid exposing STREAM_PORT on the public internet—only on the LAN or VPN interface. Rotate STREAM_TOKEN if it leaks.
RaspiMobileConnect is the mobile client for the live feed:
- Configure
EXPO_PUBLIC_STREAM_BASE_URL(and optionalEXPO_PUBLIC_STREAM_TOKEN) to match this server. - RaspiObjRec stays the “backend”: motion detection, recording, and optional streaming. See the RaspiMobileConnect README for app-only setup.
