Skip to content
 
 

Latest commit

 

History

73 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python script for a bird camera with automatic movement detection, recording and streaming. Sort of stable and ugly af right now, but seems to be working somehow (thanks ChatGPT!). After trying for weeks with ffmpeg, libcamera, picamera, frigate and whatever else Google suggested to get something coherent that can live stream and record on events with video AND audio I settled for this POS.

Client (Camera)

Client streams video and audio via an ffmpeg rtsp stream to the server.

Install picamera2

https://pypi.org/project/picamera2/

picamera2 in virtual environment

python3 -m venv --system-site-packages .venv

config

rename config_default.txt, change Server address, port, sensitivities etc.

systemd-service

[Unit]
Description=birbCam

[Service]
WorkingDirectory=</path/to/folder>/Camera/
User=<username>
ExecStart=</path/to/folder>/.venv/bin/python </path/to/folder>/Camera/cameraPython.py

pulseaudio

It is absolutely important to keep pulseaudio running when the user is logged out if using a microphone. Otherwise the systemd-process will shut down and crash the script. Here is what I did (I think, this is based on bash's history):

loginctl enable-linger <user>
sudo systemctl start user@<userid>.service
sudo -u <user> systemctl --user enable --now pulseaudio.socket pulseaudio.service

<userid> is the user's ID (id -u <user>)

Server

Dependencies

libgl: sudo apt install libgl1

mediamtx

For rtsp-Server

https://github.com/bluenviron/mediamtx

Useful

Source for the AI-stuff

https://pyimagesearch.com/2021/08/02/pytorch-object-detection-with-pre-trained-networks/

Source for the Webserver-stuff

https://pyimagesearch.com/2019/09/02/opencv-stream-video-to-web-browser-html-page/


How it works (high-level and generated by ChatGPT 5.0 because why not)

  • Camera (Raspberry Pi + Picamera2) publishes H264 + audio via ffmpeg to an RTSP endpoint.
  • MediaMTX (rtsp-simple-server) receives the stream and records MP4 segments on disk.
  • The Flask webapp:
    • shows the live HLS stream in the browser (dark mode UI),
    • organizes recordings into per-day folders (YYYY-MM-DD),
    • can export “last N seconds” from the current recordings via ffmpeg trim,
    • runs motion detection over recorded files to produce event clips.

Components

  • Camera
    • Picamera2 + FfmpegOutput → RTSP (and HLS via MediaMTX).
    • Audio typically comes from PulseAudio “default” source; keep user Pulse running after logout (linger + user service).
  • MediaMTX
    • Records MP4 files to BIRBCAM_MEDIA_DIR//.
  • Webapp (Flask)
    • Templates: base.html (shared header/dark mode), camera.html (live), recordings.html (split view: player left, picker right).
    • Static: style.css (dark theme), theme.js (toggle).
    • Recordings organized under Webapp/recordings///.
  • Motion detection
    • Scans recorded MP4s, finds motion windows, trims clips using ffmpeg.
    • State file .motion_state_.json keeps processed and produced lists; pruned to existing files to avoid growth.

Data flow

Camera → MediaMTX (RTSP) → MP4 files on disk → Webapp:

  • Live view reads HLS (m3u8) from MediaMTX.
  • Recordings view lists per-day folders and plays selected MP4.
  • “Save last 60s” builds a clip from the tail of the latest MP4s, with audio preserved when available.

Organization of recordings

  • Existing loose MP4s are moved into per-day folders automatically by the webapp.
  • UI groups by date and keeps a scrolling list of files on the right while the video player stays visible on the left.

Services and scheduling

  • Camera service (systemd):
    • Runs independently of SSH.
    • Set XDG_RUNTIME_DIR and PULSE_SERVER for user PulseAudio if using a mic.
    • Enable user lingering so Pulse persists after logout (loginctl enable-linger ).
  • Motion detection timer (systemd):
    • Type=oneshot service + timer (e.g., OnUnitActiveSec=5min or OnCalendar=*:0/5).
    • Script uses a non-blocking lock to prevent overlapping runs.

Configuration (env)

  • BIRBCAM_CAMERA: camera name (default: garten)
  • BIRBCAM_MEDIA_DIR: MediaMTX recordings root (default: /home/birb/mediamtx/recordings)
  • BIRBCAM_OUTPUT_DIR: Webapp outputs/recordings (default: /home/birb/BirbCam/Webapp/recordings)
  • Live view HLS URLs are configured in webapp.py (cameras dict).
  • Audio (camera service):
    • Pulse (recommended with Picamera2’s FfmpegOutput): PULSE_SERVER=/run/user//pulse/native
    • Keep Pulse alive via systemd --user and linger.

Known quirks

  • PulseAudio is per-user; if it stops on logout and Picamera2 is bound to Pulse, audio will break. Use user lingering so Pulse stays up.
  • Some USB mics are mono-only; if you test via ffmpeg/ALSA, use -ac 1 and consider plughw to handle conversion.

Quick start checklist

  1. Install ffmpeg and MediaMTX; confirm a working camera stream.
  2. Configure MediaMTX recordings directory and camera name (BIRBCAM_MEDIA_DIR, BIRBCAM_CAMERA).
  3. Start the Flask webapp; open / for dashboard, /camera/ for live, /recordings/ for organized clips.
  4. Set up systemd units for camera and motion detection, enable linger for audio stability.
  5. Use the “Save last 60s” button or let motion detection produce event clips automatically.
  • BIRBCAM_OUTPUT_DIR: Webapp outputs

About

EagleBirbCam

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages