Add pure-ffmpeg RTSP capture and camera audio for sunrise videos
Removes dependency on MotionEye or any NVR software. Everything is now
CLI/ffmpeg configured entirely from sky-cam.conf.
capture.sh
Long-running systemd service (one per camera) that pulls frames from the
camera's RTSP stream at CAPTURE_INTERVAL seconds, writing HH-MM-SS.jpg
into BASE_DIR/<cam>/YYYY-MM-DD/. Restarts at midnight for the new date
directory; auto-reconnects on camera disconnect.
sunrise-audio-capture.sh
One-shot service triggered at 03:00. Waits until (sunrise minus
SUNRISE_PRE_MIN minus AUDIO_PRE_BUFFER_MIN), then records the RTSP audio
stream for the full sunrise window. Output deleted after mixing.
daily_sunrise_video.sh
Step 3 now mixes in sunrise-audio.m4a when AUDIO_ENABLED=true and the
file exists. Audio is centred on actual sunrise time at natural speed
while the video plays as the sped-up timelapse. Uses filter_complex
when audio is present (can't combine -vf with -filter_complex).
install.sh
Generates sky-cam-capture-<cam>.service for each camera with CAM_RTSP_<cam>
set, and sky-cam-audio-capture.{service,timer} when AUDIO_ENABLED=true.
sky-cam.conf
New settings: CAM_RTSP_<cam>, CAPTURE_INTERVAL, AUDIO_ENABLED,
AUDIO_PRE_BUFFER_MIN, CAPTURE_AUDIO_BITRATE.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
This commit is contained in:
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# capture.sh <cam-name> — continuous JPEG frame capture from a camera's RTSP
|
||||
# stream. Replaces MotionEye or any NVR for sky-cam's timelapse pipeline.
|
||||
# Pure ffmpeg — no NVR software required.
|
||||
#
|
||||
# Run as a long-running systemd service (Type=simple), one per camera.
|
||||
# install.sh generates sky-cam-capture-<cam>.service automatically when
|
||||
# CAM_RTSP_<cam> is set in sky-cam.conf.
|
||||
#
|
||||
# Writes: BASE_DIR/<cam>/YYYY-MM-DD/HH-MM-SS.jpg
|
||||
# Restarts ffmpeg at midnight so images land in the correct date directory.
|
||||
# On camera disconnect, waits 30 s then reconnects automatically.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
source "$SCRIPT_DIR/sky-cam.conf"
|
||||
export TZ="$TIMEZONE"
|
||||
|
||||
CAM="${1:-$CAM_NAME}"
|
||||
|
||||
rtsp_var="CAM_RTSP_${CAM}"
|
||||
RTSP_URL="${!rtsp_var:-}"
|
||||
if [ -z "$RTSP_URL" ]; then
|
||||
echo "ERROR: CAM_RTSP_${CAM} not set in sky-cam.conf"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INTERVAL="${CAPTURE_INTERVAL:-10}"
|
||||
echo "Starting capture: cam=$CAM interval=${INTERVAL}s"
|
||||
|
||||
while true; do
|
||||
today=$(date +%Y-%m-%d)
|
||||
dir="$BASE_DIR/$CAM/$today"
|
||||
mkdir -p "$dir"
|
||||
|
||||
# Run until midnight + 5 s so the new day's directory is ready on restart
|
||||
midnight=$(date -d "tomorrow 00:00:00" +%s)
|
||||
now=$(date +%s)
|
||||
duration=$(( midnight - now + 5 ))
|
||||
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Capturing → $dir (rollover in ${duration}s)"
|
||||
|
||||
# -strftime 1 expands %H-%M-%S in the output path using the frame timestamp
|
||||
ffmpeg -loglevel warning \
|
||||
-rtsp_transport tcp \
|
||||
-i "$RTSP_URL" \
|
||||
-t "$duration" \
|
||||
-vf "fps=1/${INTERVAL}" \
|
||||
-f image2 \
|
||||
-strftime 1 \
|
||||
-q:v 2 \
|
||||
"${dir}/%H-%M-%S.jpg" || true
|
||||
|
||||
# If ffmpeg exited before midnight the camera dropped — wait then retry
|
||||
if [ "$(date +%s)" -lt "$midnight" ]; then
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$CAM] stream lost — retrying in 30s"
|
||||
sleep 30
|
||||
else
|
||||
sleep 2 # brief pause at midnight before day rollover restart
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user