Degrade gracefully on overlay/audio failure; notify on upload success
Sunrise: - Overlay failure no longer exits 1; the speed-only video is renamed to the expected final path so OnSuccess still fires and the upload still happens - sunrise2mm.py now notifies on every upload outcome (success, post failure, file-not-found) via notify.sh so the user always knows whether the video reached Mattermost Montage: - Music+overlay failure no longer exits 1; the sped video is promoted to the *-Montage.mp4 path so year-end-join can still include this movement (as a silent, no-overlay clip) and the user is notified of the degraded output - Year-end join trigger is now outside the success/failure branch so it fires in both cases https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
This commit is contained in:
+13
-12
@@ -140,22 +140,23 @@ DT="${DT}:x=w-tw-18:y=(h-th)/2"
|
|||||||
DT="${DT}:shadowcolor=black@0.55:shadowx=1:shadowy=1"
|
DT="${DT}:shadowcolor=black@0.55:shadowx=1:shadowy=1"
|
||||||
|
|
||||||
# ── Step 3: Overlay — sunrise time burned in ──────────────────────────────────
|
# ── Step 3: Overlay — sunrise time burned in ──────────────────────────────────
|
||||||
# If this fails, $sped_video survives at its permanent path for manual recovery.
|
# If overlay fails, the sped video is promoted to the upload target so
|
||||||
|
# OnSuccess still fires and the upload happens (without timestamp overlay).
|
||||||
final_video="$output_dir/$current_date-daily-sunrise.mp4"
|
final_video="$output_dir/$current_date-daily-sunrise.mp4"
|
||||||
echo "Step 3/3: overlay → $final_video"
|
echo "Step 3/3: overlay → $final_video"
|
||||||
if ! ffmpeg -loglevel warning \
|
if ffmpeg -loglevel warning \
|
||||||
-i "$sped_video" \
|
-i "$sped_video" \
|
||||||
-vf "${DT}" \
|
-vf "${DT}" \
|
||||||
-c:v libx264 -pix_fmt yuv420p -crf "$CRF_SUNRISE" -an \
|
-c:v libx264 -pix_fmt yuv420p -crf "$CRF_SUNRISE" -an \
|
||||||
-y "$final_video"; then
|
-y "$final_video"; then
|
||||||
"$SCRIPT_DIR/notify.sh" "FAILED: sunrise overlay $current_date" \
|
actual_dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$final_video")
|
||||||
"Overlay failed — speed-only video saved: $(basename "$sped_video")" || true
|
echo "Done: $final_video (${actual_dur}s, sunrise at ${SR_TIME})"
|
||||||
exit 1
|
rm -f "$sped_video"
|
||||||
|
"$SCRIPT_DIR/notify.sh" "Sunrise ready: $current_date" \
|
||||||
|
"$(basename "$final_video") — ${actual_dur}s, sunrise at ${SR_TIME}" || true
|
||||||
|
else
|
||||||
|
mv "$sped_video" "$final_video"
|
||||||
|
echo "Overlay failed — promoting speed-only video as upload target"
|
||||||
|
"$SCRIPT_DIR/notify.sh" "WARNING: sunrise overlay failed $current_date" \
|
||||||
|
"Overlay step failed — uploading speed-only video (no timestamp)" || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
actual_dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$final_video")
|
|
||||||
echo "Done: $final_video (${actual_dur}s, sunrise at ${SR_TIME})"
|
|
||||||
|
|
||||||
rm -f "$sped_video"
|
|
||||||
"$SCRIPT_DIR/notify.sh" "Sunrise ready: $current_date" \
|
|
||||||
"$(basename "$final_video") — ${actual_dur}s, sunrise at ${SR_TIME}" || true
|
|
||||||
|
|||||||
+15
-14
@@ -178,8 +178,9 @@ DT="${DT}:alpha='${ALPHA}':enable='${ENABLE}'"
|
|||||||
|
|
||||||
output_file="$output_dir/${MVT_START}_${SEASON}_Mvt${MVT_NUM}-Montage.mp4"
|
output_file="$output_dir/${MVT_START}_${SEASON}_Mvt${MVT_NUM}-Montage.mp4"
|
||||||
|
|
||||||
# If this fails, $sped_file survives for manual recovery (re-run step 3 only).
|
# If music/overlay fails, the sped video is promoted to the output path so
|
||||||
if ! ffmpeg -loglevel warning \
|
# year-end-join can still include this movement (as a silent, no-overlay clip).
|
||||||
|
if ffmpeg -loglevel warning \
|
||||||
-i "$sped_file" -i "$music_file" \
|
-i "$sped_file" -i "$music_file" \
|
||||||
-filter_complex \
|
-filter_complex \
|
||||||
"[0:v]fade=t=in:st=0:d=${FADE_DUR},fade=t=out:st=${fade_out_start}:d=${FADE_DUR},${DT}[vout];\
|
"[0:v]fade=t=in:st=0:d=${FADE_DUR},fade=t=out:st=${fade_out_start}:d=${FADE_DUR},${DT}[vout];\
|
||||||
@@ -187,20 +188,20 @@ if ! ffmpeg -loglevel warning \
|
|||||||
-map "[vout]" -map "[aout]" \
|
-map "[vout]" -map "[aout]" \
|
||||||
-c:v libx264 -pix_fmt yuv420p -c:a aac -b:a "$AUDIO_BITRATE" \
|
-c:v libx264 -pix_fmt yuv420p -c:a aac -b:a "$AUDIO_BITRATE" \
|
||||||
-t "$music_duration" -y "$output_file"; then
|
-t "$music_duration" -y "$output_file"; then
|
||||||
"$SCRIPT_DIR/notify.sh" "FAILED: montage step 3/3 (music+overlay) $SEASON Mvt$MVT_NUM ($ASTRO_YEAR)" \
|
rm -f "$sped_file"
|
||||||
"Music/overlay failed — sped video saved: $(basename "$sped_file")" || true
|
echo "Done: $output_file"
|
||||||
exit 1
|
"$SCRIPT_DIR/notify.sh" \
|
||||||
|
"Montage ready: $SEASON Mvt $MVT_NUM ($ASTRO_YEAR)" \
|
||||||
|
"$(basename "$output_file") — ${music_duration}s" \
|
||||||
|
|| true
|
||||||
|
else
|
||||||
|
mv "$sped_file" "$output_file"
|
||||||
|
echo "Music+overlay failed — silent video promoted to: $output_file"
|
||||||
|
"$SCRIPT_DIR/notify.sh" \
|
||||||
|
"WARNING: montage audio+overlay failed — $SEASON Mvt$MVT_NUM ($ASTRO_YEAR)" \
|
||||||
|
"Silent video saved as $(basename "$output_file") — re-run montage-mvt.sh to retry" || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f "$sped_file"
|
|
||||||
echo "Done: $output_file"
|
|
||||||
|
|
||||||
# ── Notify ────────────────────────────────────────────────────────────────────
|
|
||||||
"$SCRIPT_DIR/notify.sh" \
|
|
||||||
"Montage ready: $SEASON Mvt $MVT_NUM ($ASTRO_YEAR)" \
|
|
||||||
"$(basename "$output_file") — ${music_duration}s" \
|
|
||||||
|| true # notifications are best-effort
|
|
||||||
|
|
||||||
# ── Trigger year-end join on last Autumn movement ────────────────────────────
|
# ── Trigger year-end join on last Autumn movement ────────────────────────────
|
||||||
if [ "$SEASON" = "Autumn" ] && [ "$MVT_NUM" = "3" ]; then
|
if [ "$SEASON" = "Autumn" ] && [ "$MVT_NUM" = "3" ]; then
|
||||||
echo "Last movement of astronomical year $ASTRO_YEAR — triggering year-end join..."
|
echo "Last movement of astronomical year $ASTRO_YEAR — triggering year-end join..."
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import requests
|
import requests
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import pathlib
|
import pathlib
|
||||||
@@ -91,9 +92,33 @@ if os.path.isfile(final_video_file):
|
|||||||
|
|
||||||
if message_response.status_code == 201:
|
if message_response.status_code == 201:
|
||||||
print("Message posted successfully.")
|
print("Message posted successfully.")
|
||||||
|
subprocess.run(
|
||||||
|
[str(_here / 'notify.sh'),
|
||||||
|
f"Sunrise uploaded: {today_date_str}",
|
||||||
|
f"Video posted to Mattermost successfully"],
|
||||||
|
check=False
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(f"Failed to post message: {message_response.text}")
|
print(f"Failed to post message: {message_response.text}")
|
||||||
|
subprocess.run(
|
||||||
|
[str(_here / 'notify.sh'),
|
||||||
|
f"FAILED: sunrise Mattermost post {today_date_str}",
|
||||||
|
f"File uploaded but post failed: {message_response.status_code}"],
|
||||||
|
check=False
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(f"Failed to upload {final_video_file}: {response.text}")
|
print(f"Failed to upload {final_video_file}: {response.text}")
|
||||||
|
subprocess.run(
|
||||||
|
[str(_here / 'notify.sh'),
|
||||||
|
f"FAILED: sunrise upload {today_date_str}",
|
||||||
|
f"Mattermost file upload failed: {response.status_code}"],
|
||||||
|
check=False
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(f"No video file found at {final_video_file}.")
|
print(f"No video file found at {final_video_file}.")
|
||||||
|
subprocess.run(
|
||||||
|
[str(_here / 'notify.sh'),
|
||||||
|
f"FAILED: sunrise upload {today_date_str}",
|
||||||
|
f"Video file not found: {final_video_file}"],
|
||||||
|
check=False
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user