The retention block ended with `[ test ] && echo`, which under `set -e` returns exit 1 when `deleted` is 0 — the normal case on most days. As the script's last command, that bash exit propagated to systemd, which marked the unit failed and fired the OnFailure ntfy even though the audio file was written successfully. Add `|| true` and an explicit `exit 0` so a no-op retention pass is treated as success.
97 lines
3.6 KiB
Bash
Executable File
97 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# sunrise-audio-capture.sh — record exactly SUNRISE_TARGET_SECS of audio
|
|
# centred on the actual sunrise moment, so daily_sunrise_video.sh can mix in
|
|
# real ambient sound (birds, rain, wind) at natural speed.
|
|
#
|
|
# Triggered at 03:00 by sky-cam-audio-capture.timer; waits internally until
|
|
# the right moment before recording. Exits immediately if AUDIO_ENABLED≠true.
|
|
#
|
|
# Recording window: floor(TARGET/2) seconds before sunrise,
|
|
# ceil(TARGET/2) seconds after (odd second goes to post).
|
|
#
|
|
# Output: BASE_DIR/<cam>/YYYY-MM-DD/sunrise-audio.m4a
|
|
# Deleted automatically by daily_sunrise_video.sh after mixing.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
|
source "$SCRIPT_DIR/sky-cam.conf"
|
|
export TZ="$TIMEZONE"
|
|
|
|
CAM="${1:-$SUNRISE_CAM}"
|
|
|
|
if [ "${AUDIO_ENABLED:-false}" != "true" ]; then
|
|
echo "AUDIO_ENABLED is not true — skipping."
|
|
exit 0
|
|
fi
|
|
|
|
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
|
|
|
|
# ── Sunrise time ──────────────────────────────────────────────────────────────
|
|
sunrise_time=$(python3 "$SCRIPT_DIR/sunrise.py")
|
|
if [ -z "$sunrise_time" ]; then
|
|
"$SCRIPT_DIR/notify.sh" "FAILED: audio capture — no sunrise time" \
|
|
"sunrise.py returned nothing — check internet/location config" || true
|
|
exit 1
|
|
fi
|
|
sunrise_time_local=$(TZ="$TIMEZONE" date -d "$sunrise_time" +"%H:%M:%S")
|
|
echo "Sunrise (local): $sunrise_time_local"
|
|
|
|
# ── Calculate recording window centred on sunrise ─────────────────────────────
|
|
time_to_seconds() { IFS=':' read -r h m s <<< "$1"; echo $((10#$h*3600 + 10#$m*60 + 10#$s)); }
|
|
|
|
sunrise_sec=$(time_to_seconds "$sunrise_time_local")
|
|
half_pre=$(( SUNRISE_TARGET_SECS / 2 )) # floor — pre-sunrise portion
|
|
half_post=$(( SUNRISE_TARGET_SECS - half_pre )) # ceil — post-sunrise gets odd second
|
|
record_start_sec=$(( sunrise_sec - half_pre ))
|
|
[ "$record_start_sec" -lt 0 ] && record_start_sec=0
|
|
record_dur_sec=$SUNRISE_TARGET_SECS
|
|
|
|
echo "Audio window: ${half_pre}s before → ${half_post}s after sunrise (${record_dur_sec}s total)"
|
|
|
|
midnight=$(date -d "today 00:00:00" +%s)
|
|
now_day_sec=$(( $(date +%s) - midnight ))
|
|
wait_sec=$(( record_start_sec - now_day_sec ))
|
|
|
|
if [ "$wait_sec" -gt 0 ]; then
|
|
echo "Waiting ${wait_sec}s until audio window ($(date -d "@$(( midnight + record_start_sec ))" '+%H:%M:%S'))..."
|
|
sleep "$wait_sec"
|
|
fi
|
|
|
|
today=$(date +%Y-%m-%d)
|
|
dir="${AUDIO_DIR:-$BASE_DIR/audio}/sunrise/$CAM/$today"
|
|
mkdir -p "$dir"
|
|
output="$dir/sunrise-audio.m4a"
|
|
|
|
echo "Recording ${record_dur_sec}s of audio → $output"
|
|
|
|
if ! ffmpeg -loglevel warning \
|
|
-rtsp_transport tcp \
|
|
-i "$RTSP_URL" \
|
|
-t "$record_dur_sec" \
|
|
-vn \
|
|
-acodec aac -b:a "${CAPTURE_AUDIO_BITRATE:-96k}" \
|
|
-y "$output"; then
|
|
"$SCRIPT_DIR/notify.sh" "FAILED: audio capture $today" \
|
|
"ffmpeg audio recording failed — sunrise video will have no audio" || true
|
|
exit 1
|
|
fi
|
|
|
|
size=$(du -h "$output" | cut -f1)
|
|
echo "Audio capture complete: $output (${record_dur_sec}s, $size)"
|
|
|
|
# Rolling retention for sunrise audio clips
|
|
retain="${SUNRISE_AUDIO_RETENTION_DAYS:-7}"
|
|
if [ "$retain" -gt 0 ]; then
|
|
audio_root="${AUDIO_DIR:-$BASE_DIR/audio}/sunrise/$CAM"
|
|
deleted=$(find "$audio_root" -name "sunrise-audio.m4a" -mtime +"$retain" -print -delete 2>/dev/null | wc -l)
|
|
[ "$deleted" -gt 0 ] && echo "Retention: deleted $deleted sunrise audio clip(s) older than ${retain}d" || true
|
|
fi
|
|
|
|
exit 0
|