Skip to content

Export audio landed at t=0; preview strobed black on Windows - #23

Open
dvgmdvgm wants to merge 2 commits into
HelpFreedom:mainfrom
dvgmdvgm:fix/export-audio-delay-and-preview-flicker
Open

dvgmdvgm wants to merge 2 commits into
HelpFreedom:mainfrom
dvgmdvgm:fix/export-audio-delay-and-preview-flicker

Conversation

@dvgmdvgm

Copy link
Copy Markdown

Two bugs found on one real Windows edit — a 22-clip CS2 montage, 1080p60,
OBS sources. Independent of each other, one commit each.

1. The export piles every audio segment onto t=0

The picture was correct; the sound was all of the timeline stacked on the
first seconds, then silence from 13.8 s on — the length of the longest
clip.

adelay is what puts each segment at its timeline position. On the
ffmpeg this machine has (gyan.dev git 2025-01-08) it stamps the silence
it inserts with NOPTS whenever the input is an A/V file opened with
-ss — which is every segment of a normal edit. The atrim right after
it then drops those frames as out of range, and the delay goes with them.
An audio-only input does not reproduce it; a video stream next to the
audio does.

asetpts=N/SR/TB after the delay recounts the timestamps from the sample
position. Version-neutral, free, and it repairs the transcription and
loudness-envelope mixdowns that run through the same graph.

Verified on the reported project: with the fix, the finished mix nulls
against the source of the clip at 90.2 s at −91 dB, i.e. sample-exact.
scripts/check-mixdown.mjs is the small standing check — it fails on the
old chain.

2. The preview strobes black during playback on Windows

The preview context asked for desynchronized. On Windows that is
front-buffer rendering, so the screen can catch a frame between the clear
at the top of begin() and the layers drawn over it.

What the compositor produced was never wrong — the black exists only on
screen, which is why nothing that reads pixels back (snapshots, exports,
the e2e suites) ever saw it. Measured by screencasting the composited
page across 12 s of playback of the same range: 131 black frames out of
916
with the flag, 0 out of 645 without it. The flag buys at most
one frame of latency in return.

Checks

npm run typecheck, check-envelope, check-proxy, check-ttstext,
check-voicemap, and the new check-mixdown all pass. The e2e suites
were not run — they need Linux and a display.

🤖 Generated with Claude Code

dvgmdvgm and others added 2 commits September 18, 2026 13:54
On a Windows build of ffmpeg (gyan.dev git 2025-01-08) an export of a
22-clip timeline came out with all of its audio piled onto the first
seconds and silence from 13.8 s — the length of the longest clip — on.
The picture was right; only the sound was wrong.

`adelay` is what moves each segment to its timeline position, and on that
build it stamps the silence it inserts with NOPTS whenever the input is an
A/V file opened with `-ss` — which is every segment of a normal edit. The
`atrim` that follows then drops those frames as out of range, the delay
with them, and every segment starts at 0.

Recount the timestamps from the sample position right after the delay.
Version-neutral, free, and it also fixes the mixdowns that transcription
and the loudness envelope run through the same graph.

`scripts/check-mixdown.mjs` builds a tiny A/V file (an audio-only source
does not reproduce it), mixes two one-second segments two seconds apart
and asserts the gap and the second tone. It fails without the fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The preview canvas asked for a `desynchronized` context. On Windows that
means front-buffer rendering: the screen can show the canvas between the
clear at the top of a frame and the layers drawn over it, so playback
strobes black. What the compositor produced was always correct — the
black never existed in the canvas, only on screen, which is why nothing
that reads pixels back (snapshots, exports, the e2e suites) ever saw it.

Measured on a real edit by screencasting the composited page across 12 s
of playback: 131 black frames out of 916 with the flag, 0 out of 645
without it. The flag buys at most one frame of latency in return.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant