From 2ba34cd5fe9051e00bc92a97f8e41ec5b4763b69 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Apr 2026 12:22:00 +0000 Subject: [PATCH] 4-seasons: fix VFR pause/jump in daily MVT clips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- 4-seasons.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/4-seasons.sh b/4-seasons.sh index 7429505..9c56898 100755 --- a/4-seasons.sh +++ b/4-seasons.sh @@ -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