Repository navigation
@remotion/media: Bound unshifted audio decoding to the sequence end - #12683
Closed
alec-watts wants to merge 3 commits into
Closed
alec-watts wants to merge 3 commits into
alec-watts wants to merge 3 commits into
Conversation
Contributor
Contributor
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Bounded non-looping audio decode —
startAudioIteratornow capsmaximumTimestampatMath.min(getMediaEndTimestamp(), getSequenceEndTimestamp())when neither looping nor pitch-shifting, so short clips stop decoding source audio past the sequence end.onAudioChunkalready caps scheduled duration at the samegetSequenceEndTimestamp(), so this cannot truncate audible audio; it only avoids decoding chunks that would never be scheduled. - Pitch/loop exception —
loop || currentToneFrequency !== 1retains the old media-end bound. This matches exactly the condition under whichpitchShiftAudioIteratorengages (it passes through whentoneFrequency === 1), so the streaming shifter's future-sample lookahead keeps its full input. The tradeoff is documented in the PR body and covered by the existing pitch regression. - Duration-change invalidation —
setSequenceDurationInFramesnow callsdestroyIterator()before the discontinuity seek, matching the sibling setters (setPlaybackRate,setLoop,setTrimRange, …). This is the necessary half of the fix: after a duration change the retained iterator is exhausted at the old end, and the seek path would otherwise short-circuit viaisAlreadyQueuedand leave live extensions silent. - Tests —
makeAudioPlayergains pass-through options (durationInFrames,playbackRate,trimBefore,trimAfter,loop) and two real-codec cases assert the decode bound and the extension → shrink → re-extension reopening for bothAudioandVideo.
The cap is in the same units as getMediaEndTimestamp() (media seconds), uses the same endpoint the scheduler already enforces, and is recomputed only at iterator start — with the duration-change invalidation closing the growth window. No behavioral surface beyond the intended bound.
deepseek-v4.1-flash | 𝕏
…-audio-to-sequence-end
Member
|
Thanks @alec-watts! Since this fork doesn't allow maintainer edits, we moved your change to a new PR with you credited as co-author. It's rebased on main, the fixture changes that already landed in #12685 are dropped, and a few comments are removed. Closing this one in favor of the new PR. |
DeryFerd
pushed a commit
to DeryFerd/remotion
that referenced
this pull request
Oct 29, 2026
Short non-looping Audio and Video clips no longer decode source audio past their sequence end. Extending a clip's duration recreates the audio iterator so the newly added span is decoded. Supersedes remotion-dev#12683. Co-authored-by: Alec Watts <alecwatts1@gmail.com>
This branch was successfully deployed
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.

Short non-looping
@remotion/mediaAudio and Video clips can decode source audio beyond their sequence end even though those chunks will never play.Cap the existing iterator at the earlier of the media end and sequence end when no pitch shifting is active. Invalidate the audio iterator before the existing duration-change seek so extending a clip can decode its newly added span instead of retaining the exhausted iterator.
Loops retain their existing source bounds. Pitch-shifted audio also retains its existing bounds: the unconditional cap reproducibly fails the existing preview pitch regression (estimated 654 Hz versus expected 660 Hz), while unchanged upstream passes. The streaming pitch shifter consumes future samples, so safely bounding that path needs separate tail handling. No pitch assertion or tolerance is changed.
This applies to both Audio and Video's shared audio manager. Video-frame decoding is unchanged.
Validation
Based on upstream main
4725fadc9d4bab2779af5846554b18adff1613c6.git diff --checkpass (existing lint warnings only).The tests exercise actual decoding and queued audio, not physical-speaker output or an editor Undo UI. This PR makes no playback-FPS, retained-memory or universal performance claim.
Related downstream investigation: kino-ai/kino#4930. This upstream version adds the pitch exception discovered during broader validation. The separate paused-audio scheduling proposal #12609 is not required by this fix.
Why each file changes
packages/media/src/audio-iterator-manager.tspackages/media/src/media-player.tspackages/media/src/test/media-player.test.tspackages/example-videos/src/cached-example-media.ts.gitignoreturbo.jsonDiff cleanup found no unrelated formatting, new production mechanism, unused exports or extra media fixtures.
Prepared with OpenAI Codex.
Fixture dependency and CI
Includes the separately reviewable fixture repair #12685 at
8b61316. Initial macOS CI failed because upstream main's asset migration left/bigbuckbunny.mp4returning 404; the same existing test failed on unchanged main. The dependency repairs the existing downloader/public-directory setup and Turbo cached outputs. Maintainers can merge #12685 first; those changes will then drop out of this PR's diff.The combined branch passes all 193 media Chromium tests. #12685 separately passes all 186 baseline media tests, and a full Turbo cache hit restores its eight public fixtures byte-for-byte. Fresh upstream CI is running on merge head
1aa96be.