Skip to content

fix: keep scheduled audio when a clip ends during an export - #66

Open
moneymaker-ux wants to merge 1 commit into
diffusionstudio:mainfrom
moneymaker-ux:fix/export-audio-clip-tails
Open

fix: keep scheduled audio when a clip ends during an export#66
moneymaker-ux wants to merge 1 commit into
diffusionstudio:mainfrom
moneymaker-ux:fix/export-audio-clip-tails

Conversation

@moneymaker-ux

@moneymaker-ux moneymaker-ux commented Sep 13, 2026

Copy link
Copy Markdown

Fixes #65.

During an export, the OfflineAudioContext renders up to a second behind the frame loop. When a clip ends, forwardAudioDecoder calls AudioDecoder.reset(), which stops every scheduled AudioBufferSourceNode at the context's current time. That cuts whatever part of the clip the audio thread has not rendered yet:

  • 40–1000 ms per clip in audio-only exports;
  • 10–60 ms per clip in MP4 exports.

Change

  • New AudioDecoder.release(): drops the decoding state (iterator, first/last buffer) and leaves already scheduled nodes alone.
  • reset() = release() + stopping the nodes, so its behavior does not change.
  • In offline modes, forwardAudioDecoder calls release() when the clip is not playing. renderData already truncates every scheduled buffer at trimEnd, so the buffers end at the clip's out point, and onended removes them.
  • Realtime playback still calls reset(): seeking and pausing stop immediately, as before.

Verification

Each project was exported 3× as audio only (.ogg, opus) and 3× as MP4. Each export was compared with the expected audio in 10 ms windows.

Project Without this change With this change (4a652f5 + fix)
Repro from the issue: 10 × 1.5 s clips local build of 4a652f5: ogg 120–970 ms lost per clip, mp4 20–50 ms nothing lost
36 s project, 11 WAV dialogue clips 0.204.2 release and local build: ogg 40–1000 ms per clip, mp4 10–60 ms nothing lost
90 s project, 23 WAV dialogue clips + 12 video clips not measured nothing lost
Same 90 s project, one clip trimmed, later clips moved up 0.204.2 release: mp4 10–40 ms per clip nothing lost

On the 36 s project, each clip's level in the export matches the source within 0.04 dB with the change, so nothing plays past a clip's end either.

  • npm run lint: no new warnings.
  • npm run check: fails in packages/assets/src/browser.ts with TS2339 (showSaveFilePicker missing on Window). It fails the same way on main without this change.

During an export the OfflineAudioContext renders behind the frame loop, by
up to a second of samples. When a clip ended, forwardAudioDecoder called
AudioDecoder.reset(), which stops every scheduled AudioBufferSourceNode at
the context's current time. That cut the part of the clip the audio thread
had not rendered yet: 40-1000 ms per clip in audio-only exports, 10-60 ms
in MP4 exports.

In offline modes the decoder now only releases its decoding state when the
clip ends. The scheduled buffers already end at the clip's trimEnd, so they
stop at the clip's out point on their own. Realtime playback still stops
immediately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AybThRmRHP14dmvwixan1h
@vercel

vercel Bot commented Sep 13, 2026

Copy link
Copy Markdown

@moneymaker-ux is attempting to deploy a commit to the Diffusion Studio Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Export cuts the tail of every audio clip that ends before the scene

1 participant