diff --git a/README.md b/README.md index 2ed5e63..7bce176 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,6 @@ nano sky-cam.conf | `CAPTURE_INTERVAL` | Seconds between captured frames (default: 10) | | `SCHEDULE_SUNRISE` | When to start the sunrise job — default `03:00`, script waits internally until the capture window closes | | `SCHEDULE_SEASONS_` | When to run the Four Seasons daily clip — processes **yesterday's** images; runs after midnight | -| `SCHEDULE_FULLDAY_` | When to run the full-day timelapse — also processes yesterday; schedule after SEASONS | ### 4. Set up credentials @@ -137,10 +136,9 @@ Camera JPEGs + audio │ Step 2: speed-adjust to exactly match music → saved permanently │ Step 3: mix music + fades + attribution overlay → Montage.mp4 │ Last movement of Autumn → triggers year-end-join.sh - │ - └─ fullday-video.sh (runs at SCHEDULE_FULLDAY_, processes yesterday) - Encode all of yesterday's JPEGs at FULLDAY_FPS - Delete videos older than RETENTION_DAYS + │ On completion → notify with verify-mvt.sh command + └─ verify-mvt.sh (run manually after notification) + Review montage, approve to delete source JPEG folders ``` ### Resilience @@ -251,5 +249,4 @@ journalctl --user -u sky-cam-watchdog-east.service -f ```bash journalctl --user -u sky-cam-sunrise.service journalctl --user -u sky-cam-seasons-east.service -journalctl --user -u sky-cam-fullday-east.service ``` diff --git a/capture-watchdog.sh b/capture-watchdog.sh index 19c459d..be740b2 100755 --- a/capture-watchdog.sh +++ b/capture-watchdog.sh @@ -12,7 +12,11 @@ SCRIPT_DIR="$(dirname "$(realpath "$0")")" source "$SCRIPT_DIR/sky-cam.conf" export TZ="$TIMEZONE" -CAM="${1:-$SUNRISE_CAM}" +CAM="${1:-}" +if [ -z "$CAM" ]; then + echo "Usage: $0 " + exit 1 +fi STALE_SECS="${CAPTURE_STALE_SECS:-30}" CHECK_INTERVAL=$(( STALE_SECS / 3 )) [ "$CHECK_INTERVAL" -lt 5 ] && CHECK_INTERVAL=5 diff --git a/capture.sh b/capture.sh index a85e007..d5d026d 100755 --- a/capture.sh +++ b/capture.sh @@ -17,7 +17,11 @@ SCRIPT_DIR="$(dirname "$(realpath "$0")")" source "$SCRIPT_DIR/sky-cam.conf" export TZ="$TIMEZONE" -CAM="${1:-$SUNRISE_CAM}" +CAM="${1:-}" +if [ -z "$CAM" ]; then + echo "Usage: $0 " + exit 1 +fi rtsp_var="CAM_RTSP_${CAM}" RTSP_URL="${!rtsp_var:-}" diff --git a/migrate-seasons.sh b/migrate-seasons.sh index 3161a03..7e562bf 100755 --- a/migrate-seasons.sh +++ b/migrate-seasons.sh @@ -41,7 +41,11 @@ while [[ $# -gt 0 ]]; do shift done -[ -z "$CAM" ] && CAM="$SUNRISE_CAM" +if [ -z "$CAM" ]; then + echo "Usage: $0 --cam [--dry-run] [OLD_ROOT]" + echo " e.g. $0 --cam east ~/drives/local-2tb/movies/sunrise" + exit 1 +fi NEW_ROOT="$MOVIES_DIR/$CAM/2025" echo "Old archive : $OLD_ROOT" diff --git a/montage-mvt.sh b/montage-mvt.sh index d5bf98f..c181583 100755 --- a/montage-mvt.sh +++ b/montage-mvt.sh @@ -207,8 +207,8 @@ if ffmpeg -loglevel warning \ actual_dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$output_file") dur_delta=$(echo "scale=1; $actual_dur - $music_duration" | bc | sed 's/^-//') stream_types=$(ffprobe -v error -show_entries stream=codec_type -of csv=p=0 "$output_file" 2>/dev/null) - has_video=$(echo "$stream_types" | grep -c "video" || true) - has_audio=$(echo "$stream_types" | grep -c "audio" || true) + has_video=$(echo "$stream_types" | grep -c "video" || echo 0) + has_audio=$(echo "$stream_types" | grep -c "audio" || echo 0) checks="duration=${actual_dur}s (drift ${dur_delta}s)" [ "$has_video" -gt 0 ] && checks="$checks video=ok" || checks="$checks video=MISSING" [ "$has_audio" -gt 0 ] && checks="$checks audio=ok" || checks="$checks audio=MISSING" diff --git a/sky-cam.conf b/sky-cam.conf index 65c29d7..fa512a6 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -21,9 +21,8 @@ # # systemctl --user daemon-reload # systemctl --user enable --now sky-cam-sunrise.timer -# systemctl --user enable --now sky-cam-seasons-sunrise.timer -# systemctl --user enable --now sky-cam-fullday-sunrise.timer -# # one sky-cam-seasons-.timer and sky-cam-fullday-.timer per camera +# # one sky-cam-seasons-.timer per camera, e.g.: +# systemctl --user enable --now sky-cam-seasons-east.timer # # Check status: # systemctl --user list-timers 'sky-cam-*' diff --git a/verify-mvt.sh b/verify-mvt.sh index eafbe7b..6fa0e76 100755 --- a/verify-mvt.sh +++ b/verify-mvt.sh @@ -40,13 +40,7 @@ if [ -z "$montage_file" ] || [ ! -f "$montage_file" ]; then fi # ── Get movement date range from season_info ────────────────────────────────── -_info="$(python3 "$SCRIPT_DIR/season_info.py" "$MVT_START" 2>/dev/null)" 2>/dev/null || true - -# Use the sped file's date prefix to find a representative date in the movement -sped_file=$(find "$MOVIES_DIR/$CAM_NAME/$ASTRO_YEAR/$SEASON/Mvt${MVT_NUM}" \ - -maxdepth 1 -name "*-Sped.mp4" 2>/dev/null | head -n 1 || true) - -# Get MVT_START from the montage filename (format: YYYY-MM-DD_Season_MvtN-Montage.mp4) +# Extract date from montage filename (format: YYYY-MM-DD_Season_MvtN-Montage.mp4) mvt_start_date=$(basename "$montage_file" | cut -d_ -f1) _info="$(python3 "$SCRIPT_DIR/season_info.py" "$mvt_start_date")" eval "$_info" @@ -89,30 +83,23 @@ printf " File size : %s\n" "$file_size" printf " Daily clips : %d / %d days\n" "$final_count" "$DAYS_IN_MVT" printf " Music : %s\n" "$(basename "${music_file:-NOT FOUND}")" -# Count JPEG folders available for deletion +# Count JPEG folders and sum their sizes jpeg_count=0 -jpeg_size=0 +jpeg_bytes=0 d="$MVT_START" while [[ "$d" < "$MVT_END" || "$d" == "$MVT_END" ]]; do dir="$BASE_DIR/$CAM_NAME/$d" if [ -d "$dir" ]; then jpeg_count=$(( jpeg_count + 1 )) + jpeg_bytes=$(( jpeg_bytes + $(du -sb "$dir" 2>/dev/null | cut -f1 || echo 0) )) fi d=$(date -d "$d + 1 day" +%Y-%m-%d) done if [ "$jpeg_count" -gt 0 ]; then - jpeg_size=$(du -sh "$BASE_DIR/$CAM_NAME" --exclude="*" 2>/dev/null || true) - # Sum only the movement date folders - total_jpeg_bytes=0 - d="$MVT_START" - while [[ "$d" < "$MVT_END" || "$d" == "$MVT_END" ]]; do - dir="$BASE_DIR/$CAM_NAME/$d" - [ -d "$dir" ] && total_jpeg_bytes=$(du -sb "$dir" 2>/dev/null | cut -f1 || echo 0) || true - d=$(date -d "$d + 1 day" +%Y-%m-%d) - done - printf " JPEG folders : %d date folders (%s → %s)\n" \ - "$jpeg_count" "$MVT_START" "$MVT_END" + jpeg_size=$(numfmt --to=iec-i --suffix=B "$jpeg_bytes" 2>/dev/null || echo "${jpeg_bytes}B") + printf " JPEG folders : %d date folders, %s (%s → %s)\n" \ + "$jpeg_count" "$jpeg_size" "$MVT_START" "$MVT_END" else printf " JPEG folders : none found (already deleted)\n" fi @@ -148,7 +135,7 @@ while true; do continue fi echo "" - echo " Will delete $jpeg_count JPEG date folders ($MVT_START → $MVT_END) for camera [$CAM_NAME]." + echo " Will delete $jpeg_count JPEG date folders ($MVT_START → $MVT_END) for camera [$CAM_NAME] — ${jpeg_size}." echo " The montage video and daily clips are kept." read -rp " Confirm? [yes/no]: " confirm if [ "$confirm" = "yes" ]; then