Expose encoding quality and overlay durations in sky-cam.conf

Adds six CRF vars, AUDIO_BITRATE, and three MONTAGE_* overlay durations.
Values match previous hardcoded defaults so behavior is unchanged.

The same CRF appeared in several scripts but with intentionally different
values per purpose (28 for draft intermediates, 26 for polished output).
Each script's CRF is now its own variable in conf, so changing one never
silently changes another.

https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
This commit is contained in:
Claude
2026-04-19 16:08:14 +00:00
parent fffb19fd38
commit 6d68010691
5 changed files with 38 additions and 10 deletions
+2 -2
View File
@@ -79,7 +79,7 @@ done > "$temp_file"
echo "Step 1/2: encoding raw video..."
ffmpeg -loglevel warning \
-f concat -safe 0 -i "$temp_file" \
-c:v libx264 -pix_fmt yuv420p -crf 28 -vsync 2 -an \
-c:v libx264 -pix_fmt yuv420p -crf "$CRF_SEASONS_RAW" -vsync 2 -an \
-y "$temp_video"
raw_duration=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$temp_video")
@@ -93,7 +93,7 @@ final_file="$output_dir/${yesterday}_Mvt${MVT_NUM}-Day${DAY_OF_MVT}of${DAYS_IN_M
ffmpeg -loglevel warning \
-i "$temp_video" \
-vf "setpts=PTS/$speed_factor" \
-c:v libx264 -pix_fmt yuv420p -crf 26 \
-c:v libx264 -pix_fmt yuv420p -crf "$CRF_SEASONS_FINAL" \
-t "$target_per_clip" -an \
-y "$final_file"
+1 -1
View File
@@ -100,7 +100,7 @@ first_movie="$output_dir/$current_date-sunrise-day.mp4"
# Create the first movie at the default frame rate (no speed adjustments)
echo "Creating video at default frame rate..."
ffmpeg -f concat -safe 0 -i "$temp_file" -c:v libx264 -pix_fmt yuv420p -crf 28 -vsync 2 -y "$first_movie"
ffmpeg -f concat -safe 0 -i "$temp_file" -c:v libx264 -pix_fmt yuv420p -crf "$CRF_SUNRISE" -vsync 2 -y "$first_movie"
# Check the duration of the created video
video_duration=$(ffmpeg -i "$first_movie" 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed s/,//)
+1 -1
View File
@@ -63,7 +63,7 @@ echo "Creating: $output_file"
ffmpeg -loglevel warning \
-f concat -safe 0 -i "$temp_list" \
-c:v libx264 -pix_fmt yuv420p -crf 28 \
-c:v libx264 -pix_fmt yuv420p -crf "$CRF_FULLDAY" \
-an -y "$output_file"
actual_dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$output_file")
+8 -6
View File
@@ -31,9 +31,11 @@ base_dir="$BASE_DIR"
music_base_dir="$MUSIC_DIR"
[ ! -d "$music_base_dir" ] && music_base_dir="$SCRIPT_DIR/music"
FADE_DUR=2.0 # video + audio fade in/out (seconds)
ATTR_DUR=6 # attribution overlay duration (seconds from start)
ATTR_FADE=1 # attribution fade in / fade out duration
# Fade/overlay durations come from sky-cam.conf (MONTAGE_FADE_DUR,
# MONTAGE_ATTR_DUR, MONTAGE_ATTR_FADE). Alias for shorter local use.
FADE_DUR="$MONTAGE_FADE_DUR"
ATTR_DUR="$MONTAGE_ATTR_DUR"
ATTR_FADE="$MONTAGE_ATTR_FADE"
# ── Season / movement info ────────────────────────────────────────────────────
DATE_ARG="${1:-}"
@@ -100,7 +102,7 @@ ffmpeg -loglevel warning \
-f concat -safe 0 -i "$concat_list" \
-vf "scale=${VIDEO_W}:${VIDEO_H}:force_original_aspect_ratio=decrease,\
pad=${VIDEO_W}:${VIDEO_H}:(ow-iw)/2:(oh-ih)/2,setsar=1" \
-c:v libx264 -pix_fmt yuv420p -crf 26 -an \
-c:v libx264 -pix_fmt yuv420p -crf "$CRF_MONTAGE" -an \
-y "$temp_concat"
# ── Step 2: Speed-adjust to match music duration exactly ──────────────────────
@@ -112,7 +114,7 @@ temp_sped=$(mktemp --suffix=.mp4); TMPFILES+=("$temp_sped")
ffmpeg -loglevel warning \
-i "$temp_concat" \
-vf "setpts=PTS/$speed_factor" \
-c:v libx264 -pix_fmt yuv420p -crf 26 -an \
-c:v libx264 -pix_fmt yuv420p -crf "$CRF_MONTAGE" -an \
-t "$music_duration" -y "$temp_sped"
rm "$temp_concat"
@@ -156,7 +158,7 @@ ffmpeg -loglevel warning \
"[0:v]fade=t=in:st=0:d=${FADE_DUR},fade=t=out:st=${fade_out_start}:d=${FADE_DUR},${DT}[vout];\
[1:a]afade=t=in:st=0:d=${FADE_DUR},afade=t=out:st=${fade_out_start}:d=${FADE_DUR}[aout]" \
-map "[vout]" -map "[aout]" \
-c:v libx264 -pix_fmt yuv420p -c:a aac -b:a 192k \
-c:v libx264 -pix_fmt yuv420p -c:a aac -b:a "$AUDIO_BITRATE" \
-t "$music_duration" -y "$output_file"
rm "$temp_sped"
+26
View File
@@ -209,6 +209,32 @@ SUNRISE_TARGET_SECS=10
FULLDAY_FPS=5 # frame rate of the timelapse video
RETENTION_DAYS=10 # delete full-day videos older than this many days
# ── Video encoding quality ────────────────────────────────────────────────────
# FFmpeg CRF: lower = higher quality / larger files. Typical range 1830.
# 18 ≈ visually lossless 23 = ffmpeg default 28 = smaller/lower
# Different scripts use different defaults by design — intermediate/draft
# encodings use a higher CRF (smaller files, quality less critical), while
# final "polished" outputs use a lower CRF for better quality.
# Each is independent — changing one does NOT change the others.
#
CRF_SUNRISE=28 # daily_sunrise_video.sh — daily Mattermost upload
CRF_FULLDAY=28 # fullday-video.sh — full-day timelapse
CRF_SEASONS_RAW=28 # 4-seasons.sh — raw concat before speed-adjust
CRF_SEASONS_FINAL=26 # 4-seasons.sh — final daily clip (goes into montage)
CRF_MONTAGE=26 # montage-mvt.sh — concat and speed-adjust and final
AUDIO_BITRATE=192k # montage-mvt.sh — music track on movement montages
# ── Montage attribution overlay ───────────────────────────────────────────────
# A translucent bar across the top of each movement montage, naming the
# music source ("The Four Seasons — Antonio Vivaldi ...").
# Appears for MONTAGE_ATTR_DUR seconds from the start, with ATTR_FADE-second
# fade in and fade out. FADE_DUR controls the video/audio fade in/out at
# the very start and very end of the montage.
#
MONTAGE_FADE_DUR=2.0 # video + audio fade in/out (seconds)
MONTAGE_ATTR_DUR=6 # attribution overlay total duration (seconds)
MONTAGE_ATTR_FADE=1 # attribution fade-in and fade-out length (seconds)
# ── Mattermost — daily sunrise upload ─────────────────────────────────────────
mattermost_url=https://your-mattermost-server.example.com
access_token=your-access-token-here