4-seasons: fix VFR pause/jump in daily MVT clips

Without explicit duration in the concat file, ffmpeg assigns timestamps
from EXIF metadata or defaults — producing a variable frame-rate raw
video with uneven frame spacing.  Applying setpts without fps= then
preserved that unevenness into the final clip, causing the observed
pause-then-jump-minutes/hours behaviour.

Fix 1: write `duration 0.04` (1/25 s) for every JPEG in the concat
list, making the raw video a true 25 fps CFR stream.  The duplicate
final-entry is appended as required by the ffmpeg concat demuxer so the
last content frame keeps its full display duration.

Fix 2: add `fps=25` to the setpts filter in step 2, resampling to
standard 25 fps CFR regardless of the speed factor, which guarantees
smooth, uniform playback in the final clip.

https://claude.ai/code/session_01U29A8NpgJ41tboiggZNmk8
This commit is contained in:
Claude
2026-04-23 12:22:00 +00:00
parent bd2ade49fc
commit 2ba34cd5fe
+4 -2
View File
@@ -135,8 +135,10 @@ if [ "${#images[@]}" -eq 0 ]; then
fi
for img in "${images[@]}"; do
printf "file '%s'\n" "$img"
printf "file '%s'\nduration 0.04\n" "$img"
done > "$temp_file"
# ffmpeg concat demuxer requires a final entry with no duration for image files
printf "file '%s'\n" "${images[-1]}" >> "$temp_file"
# ── Step 1: Build raw video ───────────────────────────────────────────────────
echo "Step 1/2: encoding raw video from ${#images[@]} frames..."
@@ -155,7 +157,7 @@ echo "Step 2/2: speed factor $speed_factor..."
final_file="$output_dir/${CAM_NAME}-${yesterday}_Mvt${MVT_NUM}-Day${DAY_OF_MVT}of${DAYS_IN_MVT}-final.mp4"
if ! ffmpeg -loglevel warning \
-i "$temp_video" \
-vf "setpts=PTS/$speed_factor" \
-vf "setpts=PTS/$speed_factor,fps=25" \
-c:v libx264 -pix_fmt yuv420p -preset "$ENCODE_PRESET" -crf "$CRF_SEASONS_FINAL" \
-t "$target_per_clip" -an \
-y "$final_file"; then