Repository navigation
fix(capture): end screencast videos at the stop time - #54
Merged
Merged
Conversation
The screencast backend builds an ffconcat list and repeats the last frame so ffmpeg honors that frame's duration. ffmpeg times the repeated entry like the entry before it, so the repeat added the whole final still stretch a second time. A take that ended on a still screen, or never changed at all, encoded at about double its wall-clock length and failed the duration check. Cut the concat input at the stop time with -t. The repeat still carries the last frame, and the video now ends where the take ended. Fixes #46
…top time An input-side -t becomes a trim before the fps filter. It drops the repeated last frame only when the per-frame durations, each rounded to 4 decimals, add up to at least the cut. When they come out one tick short, the repeat survives and ffmpeg 7+ doubles the still tail again (0.4999 + 3.0 with input -t 3.5 encodes to 6.5s). Trimming the encoded output holds the length at the cut for every list.
chhoumann
marked this pull request as ready for review
October 24, 2026 15:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #46.
Problem
capture record --backend screencastrejected any take that ended on a still screen. A real take with 1s of changes followed by 3s of stillness failed withEncoded duration 7.7s does not match wall-clock 4.51s.Root cause
The screencast backend builds an ffconcat list in which every frame gets its real on-screen duration. It then repeats the last frame so ffmpeg honors that frame's duration. On ffmpeg 7 and later, the frame after the last entry is timed like the gap before it, so the repeat adds the final still stretch a second time. ffmpeg 4.4 and 6.1 held the repeat for one 40 ms tick instead. Measured with ffmpeg 8.0.1:
-t 3.5-t 3.5Takes that kept changing until the end only went over by one short frame gap, which the check tolerates. A take whose screen never changed was also affected, because its single fallback screenshot was doubled the same way.
Fix
Trim the encoded output to
max(stop - start, 1/fps)with an output-side-t. The repeat still makes ffmpeg hold the last frame, and the trim ends the video where the take ended. An input-side-tis not enough. It becomes a trim before thefpsfilter and is defeated when the per-frame durations, each rounded to 4 decimals, add up to one tick less than the cut (the 0.4999 row above). The duration check is unchanged.CapturedSource.inputArgsis renamedsourceArgsbecause it now carries that output option.CI and the release job now install ffmpeg. The runner images ship none, and the new test runs a real encode.
Verification
Real screencast takes against a live Obsidian 1.13.7 window (
capture launchpluscapture record), using the packed tarball with the final fix:The new test drives
startRecordingandstopwith real JPEG frames and a still ending, then runs the real ffmpeg encode and duration check. Before the fix it fails withEncoded duration 3.8s does not match wall-clock 2.10s.