Overlay: yellow text, lower-right position; test-sunrise uses captured frames

- fontcolor: white → yellow (both scripts)
- y position: (h-th)/2 → h-th-18 (vertically centered → lower-right corner)
- test-sunrise.sh: reverted to reading last 60 frames from capture directory
  (~10 minutes at 10s interval) instead of live RTSP capture

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
This commit is contained in:
Claude
2026-04-21 17:32:31 +00:00
parent f3839ce1cf
commit 4c02de5fd4
2 changed files with 44 additions and 55 deletions
+2 -2
View File
@@ -153,9 +153,9 @@ if [ "${SUNRISE_OVERLAY_ENABLED:-true}" = "true" ]; then
else
DT="drawtext=textfile='${temp_text}'"
fi
DT="${DT}:fontcolor=white@${SUNRISE_OVERLAY_OPACITY}"
DT="${DT}:fontcolor=yellow@${SUNRISE_OVERLAY_OPACITY}"
DT="${DT}:fontsize=h/22:line_spacing=4"
DT="${DT}:x=w-tw-18:y=(h-th)/2"
DT="${DT}:x=w-tw-18:y=h-th-18"
DT="${DT}:shadowcolor=black@0.55:shadowx=1:shadowy=1"
fi
+42 -53
View File
@@ -1,8 +1,8 @@
#!/bin/bash
# test-sunrise.sh — smoke-test the sunrise pipeline using freshly captured frames.
# test-sunrise.sh — smoke-test the sunrise pipeline using recent captured frames.
#
# Captures NUM_FRAMES × CAPTURE_INTERVAL seconds of RTSP frames from SUNRISE_CAM,
# then runs the same 4-step pipeline as daily_sunrise_video.sh:
# Uses the last ~10 minutes of JPEGs from SUNRISE_CAM then runs the same
# 4-step pipeline as daily_sunrise_video.sh:
# 1. raw video from captured JPEGs
# 2. speed-adjust to SUNRISE_TARGET_SECS
# 3. grab SUNRISE_TARGET_SECS of live RTSP audio
@@ -10,7 +10,7 @@
#
# Usage:
# ./test-sunrise.sh [output_path]
# ./test-sunrise.sh ~/drives/data2-main/test2.mp4
# ./test-sunrise.sh ~/drives/data2-main/test3.mp4
set -euo pipefail
@@ -25,48 +25,23 @@ SUNRISE_OVERLAY_OPACITY="${SUNRISE_OVERLAY_OPACITY:-0.45}"
OUTPUT="${1:-/tmp/sunrise-test.mp4}"
CAM="$SUNRISE_CAM"
NUM_FRAMES=12 # ~2 minutes at 10s interval
TODAY=$(date +%Y-%m-%d)
image_dir="$BASE_DIR/$CAM/$TODAY"
NUM_FRAMES=60 # ~10 minutes at 10s interval
# ── RTSP URL ──────────────────────────────────────────────────────────────────
rtsp_var="CAM_RTSP_${CAM}"
RTSP_URL="${!rtsp_var:-}"
if [ -z "$RTSP_URL" ]; then
echo "ERROR: CAM_RTSP_${CAM} not set in .env"
echo " Add it: CAM_RTSP_${CAM}='rtsp://user:pass@ip:554/stream'"
# ── Collect frames ────────────────────────────────────────────────────────────
if [ ! -d "$image_dir" ]; then
echo "ERROR: no frames today at $image_dir"
echo " Is capture.sh running? systemctl --user status sky-cam-capture-${CAM}.service"
exit 1
fi
# ── Temp files ────────────────────────────────────────────────────────────────
TMP_FRAME_DIR=$(mktemp -d --suffix=-sunrise-frames)
TMP_LIST=$(mktemp --suffix=.txt)
TMP_RAW=$(mktemp --suffix=.mp4)
TMP_SPED=$(mktemp --suffix=.mp4)
TMP_AUDIO=$(mktemp --suffix=.m4a)
TMP_TEXT=$(mktemp --suffix=.txt)
cleanup() {
rm -rf "$TMP_FRAME_DIR"
rm -f "$TMP_LIST" "$TMP_RAW" "$TMP_SPED" "$TMP_AUDIO" "$TMP_TEXT" 2>/dev/null || true
}
trap cleanup EXIT
# ── Capture fresh frames ─────────────────────────────────────────────────────
CAPTURE_SECS=$(( NUM_FRAMES * ${CAPTURE_INTERVAL:-10} ))
echo "Capturing ${NUM_FRAMES} frames over ${CAPTURE_SECS}s from $CAM..."
ffmpeg -loglevel warning \
-rtsp_transport tcp \
-i "$RTSP_URL" \
-t "$CAPTURE_SECS" \
-vf "fps=1/${CAPTURE_INTERVAL:-10}" \
-f image2 -strftime 1 \
-q:v 2 \
"${TMP_FRAME_DIR}/%H-%M-%S.jpg" || true
mapfile -t frames < <(find "$TMP_FRAME_DIR" -name "*.jpg" | sort)
mapfile -t frames < <(find "$image_dir" -name "*.jpg" | sort | tail -n "$NUM_FRAMES")
if [ "${#frames[@]}" -lt 1 ]; then
echo "ERROR: no frames captured from $CAM — check RTSP URL in .env"
echo "ERROR: no frames found in $image_dir"
exit 1
fi
echo "Captured: ${#frames[@]} frames"
echo "Frames: ${#frames[@]} most-recent from $image_dir"
# ── Mid-point frame → overlay time ───────────────────────────────────────────
mid_idx=$(( ${#frames[@]} / 2 ))
@@ -75,6 +50,15 @@ mid_hms=$(basename "$mid_frame" .jpg) # HH-MM-SS
MID_TIME=$(echo "$mid_hms" | cut -c1-5 | tr '-' ':') # HH:MM
echo "Mid-point frame: $mid_hms → overlay time: $MID_TIME"
# ── Temp files ────────────────────────────────────────────────────────────────
TMP_LIST=$(mktemp --suffix=.txt)
TMP_RAW=$(mktemp --suffix=.mp4)
TMP_SPED=$(mktemp --suffix=.mp4)
TMP_AUDIO=$(mktemp --suffix=.m4a)
TMP_TEXT=$(mktemp --suffix=.txt)
cleanup() { rm -f "$TMP_LIST" "$TMP_RAW" "$TMP_SPED" "$TMP_AUDIO" "$TMP_TEXT" 2>/dev/null || true; }
trap cleanup EXIT
# Write each character on its own line for drawtext's textfile option.
# Avoids \n escape ambiguity across ffmpeg filter-string escaping levels.
printf '%s\n%s\n%s\n%s\n%s' \
@@ -96,8 +80,7 @@ if [ -z "$FONT" ]; then
fi
# ── Write concat list ─────────────────────────────────────────────────────────
# Explicit duration per frame so raw video represents real elapsed time:
# 12 frames × CAPTURE_INTERVAL seconds = ~2 minutes.
# Explicit duration per frame so raw video represents real elapsed time.
# The final entry needs a duplicate without duration (ffmpeg concat requirement).
for f in "${frames[@]}"; do
printf "file '%s'\nduration %s\n" "$f" "${CAPTURE_INTERVAL:-10}"
@@ -125,20 +108,26 @@ ffmpeg -loglevel warning \
-t "$SUNRISE_TARGET_SECS" \
-y "$TMP_SPED"
# ── Step 3: grab audio centred on mid-point ────────────────────────────────────
# ── Step 3: grab audio ────────────────────────────────────────────────────────
echo "Step 3/4: recording ${SUNRISE_TARGET_SECS}s of live audio from camera..."
rtsp_var="CAM_RTSP_${CAM}"
RTSP_URL="${!rtsp_var:-}"
HAS_AUDIO=false
if ffmpeg -loglevel warning \
-rtsp_transport tcp \
-i "$RTSP_URL" \
-t "$SUNRISE_TARGET_SECS" \
-vn -c:a aac -b:a 64k \
-y "$TMP_AUDIO"; then
HAS_AUDIO=true
echo " Audio: captured OK"
if [ -n "$RTSP_URL" ]; then
if ffmpeg -loglevel warning \
-rtsp_transport tcp \
-i "$RTSP_URL" \
-t "$SUNRISE_TARGET_SECS" \
-vn -c:a aac -b:a 64k \
-y "$TMP_AUDIO"; then
HAS_AUDIO=true
echo " Audio: captured OK"
else
echo " Audio: capture failed — continuing without audio"
fi
else
echo " Audio: capture failed — continuing without audio"
echo " Audio: CAM_RTSP_${CAM} not set — skipping"
fi
# ── Step 4: mix audio + burn overlay ─────────────────────────────────────────
@@ -151,9 +140,9 @@ if [ -n "$FONT" ]; then
else
DT="drawtext=textfile='${TMP_TEXT}'"
fi
DT="${DT}:fontcolor=white@${SUNRISE_OVERLAY_OPACITY}"
DT="${DT}:fontcolor=yellow@${SUNRISE_OVERLAY_OPACITY}"
DT="${DT}:fontsize=h/22:line_spacing=4"
DT="${DT}:x=w-tw-18:y=(h-th)/2"
DT="${DT}:x=w-tw-18:y=h-th-18"
DT="${DT}:shadowcolor=black@0.55:shadowx=1:shadowy=1"
if $HAS_AUDIO; then