Files
paproc-rt/README.md
2026-05-06 22:43:01 +02:00

3.8 KiB

Fern RTSP Timelapse

What

fern_timelapse.py is a small Linux-first Python 3.10+ CLI for two jobs:

  • capture: take one JPEG from an RTSP camera, but only inside a configured daily window.
  • compile: turn the saved JPEG sequence into a high-quality H.264 MP4.

It uses ffmpeg through subprocess, keeps timestamp-based filenames, writes rotating logs to disk, and retries failed captures with exponential backoff.

Why

The design is intentionally cron-friendly. Each capture run is single-shot and idempotent enough for scheduled execution, which keeps the runtime simple and easy to recover after reboots or network drops. The compile path builds a temporary numbered sequence from symlinks so you can keep human-readable timestamp filenames without fighting ffmpeg's numeric-image input rules.

Capture behavior

  • Default window: 10:00 to 16:00
  • End of window is exclusive, so the default window captures from 10:00 through 15:50
  • Default quality: high-quality JPEG via -q:v 2
  • Default output path shape: captures/YYYY/MM/DD/YYYY-MM-DD_HH-MM-SS_ferngrowth.jpg
  • Default log file: logs/fern_timelapse.log

Usage

Show command help:

python3 fern_timelapse.py --help
python3 fern_timelapse.py capture --help
python3 fern_timelapse.py compile --help

Capture one frame:

python3 fern_timelapse.py capture \
  --camera-host 192.168.1.50 \
  --camera-user user \
  --camera-password 'password' \
  --camera-path /stream1 \
  --output-dir /srv/fern-timelapse/captures \
  --window-start 10:00 \
  --window-end 16:00

Capture one frame even outside the allowed window:

python3 fern_timelapse.py capture \
  --camera-host 10.1.1.33 \
  --camera-user admin \
  --camera-password 'mirekadmin' \
  --camera-path /stream1 \
  --output-dir /mnt/main-pool/Mirek/kamera \
  --ignore-window

Your current camera parameters, assuming the RTSP path is /stream1:

python3 fern_timelapse.py capture \
  --camera-host 10.1.1.33 \
  --camera-user admin \
  --camera-password 'mirekadmin' \
  --camera-path /stream1 \
  --output-dir /srv/fern-timelapse/captures \
  --window-start 10:00 \
  --window-end 16:00

Compile the final MP4 at 30 FPS:

python3 fern_timelapse.py compile \
  --input-dir /srv/fern-timelapse/captures \
  --output-file /srv/fern-timelapse/output/ferngrowth_timelapse.mp4 \
  --fps 30 \
  --crf 17 \
  --preset slow

Cron

This entry runs every 10 minutes during the 6-hour daylight window and should produce about 36 frames per day:

*/10 10-15 * * * /usr/bin/python3 /home/ms/projekty/paproc-rt/fern_timelapse.py capture --camera-host 10.1.1.33 --camera-user admin --camera-password 'mirekadmin' --camera-path /stream1 --output-dir /srv/fern-timelapse/captures --window-start 10:00 --window-end 16:00 >> /srv/fern-timelapse/cron.log 2>&1

If you prefer a simpler cron expression, you can also run it more broadly and let the script self-skip outside the window.

If your camera does not expose RTSP on /stream1, adjust --camera-path. Common alternatives include /Streaming/Channels/101, /h264Preview_01_main, or vendor-specific paths.

Notes on exposure and white balance

There is no reliable generic ffmpeg flag that can force an RTSP camera to lock sensor-side auto-exposure or auto white balance. In practice, the cleanest fix for color flicker is:

  1. Lock exposure and white balance in the camera's own web UI, ONVIF controls, or vendor app.
  2. Keep lighting stable and avoid direct sun shifts.
  3. Use --ffmpeg-input-arg or --ffmpeg-output-arg only for camera- or workflow-specific ffmpeg flags that your device actually supports.

Examples:

python3 fern_timelapse.py capture \
  --camera-host 192.168.1.50 \
  --camera-user user \
  --camera-password 'password' \
  --camera-path /stream1 \
  --ffmpeg-input-arg=-fflags \
  --ffmpeg-input-arg=+discardcorrupt