Repository navigation
fix(producer): render variable-bound media at the bound clip's length and loudness - #7529
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Approve at 364baab6. No blockers.
Fails without the fix — checked. I kept the new htmlCompiler.variableMedia.test.ts and put origin/main's htmlCompiler.ts, applyVariableBindings.ts and compiler/index.ts back. Result: 3 fail, 1 pass, with the expected length/src mismatches and the missing "unsafe URL protocol" warning. On the PR head all 4 pass. htmlCompiler.test.ts passes too (177/177).
Checked against the runtime:
- The
bindVariableMediaSourcesmerge (declared defaults from every[data-composition-variables], then render variables) matches the top-levelgetVariables(). The skip for[data-variable-values]hosts leaves the per-instance scopes to the browser, as the PR says. boundMediaSrcis a pure extraction.variableSrcForandunproxiedMediaSrcbehave as before, and the tag allow-list and URL gate still have one owner.- Bound relative paths are not rebased by
rebaseDirectEntryAssetPaths. The browser assigns the same unrebased value, so compile and runtime agree. - A film with no
data-var-srctakes the early return, so its HTML is untouched.
Nits (not blocking):
- The unsafe-URL test reuses
bound.html, which the first new test writes. Running that test alone (-t) will fail. It could write its own fixture. - An unsafe value now warns twice, once at compile time and once in the browser. Harmless.
- A bound
<source>inside a<video>still goes through the browser path only. That's worth one line in "Not covered".
Contributor
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Nov 11, 2026
Merged
3 of 4 tasks
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.
What
A render whose
data-var-srcvideo or audio is bound to a clip now takes that clip's length and sound. Before, the film kept the placeholder's length and the swapped clip's sound was mixed in beside the placeholder's.Why it happened
compileForRendermeasured the authoredsrcand wrote the placeholder'sdata-duration,data-endand its sound lane into the page before any variable was read. The browser probe later swapped the<video>to the bound clip, but the film length stayed derived from the baked value, and the extract stage then added a second sound lane for the bound file because itssrcwas not in the first lane's dedupe set.Fix
One pre-pass in
compileForRender, beforecompileHtmlFile:bindVariableMediaSourcessets thesrcof eachdata-var-src<video>/<audio>from the render variables over the declared defaults. It uses the runtime's own resolver (boundMediaSrc, split out ofvariableSrcForso core stays the one owner, tag allow-list and URL gate included). Every reader after it (length probe, sound lane, extraction) sees the bound clip.data-variable-valueshost is left to the browser, as today.data-var-srctakes the early return and is untouched.Verified
Real CLI render on a Linux box, 3 s placeholder with a tone, 5 s bound clip with a tone,
--variables '{"clip":"bound5.mp4"}':After the fix the swapped film sits 3 dB over its source, the same lift the unswapped film has over its own source (-21.8 to -18.8); before it was 9 dB over, i.e. two lanes. Frame hashes of the no-variable render are identical before and after.
Tests (
htmlCompiler.variableMedia.test.ts, 3 new): length and single sound lane from a bound<video>, declared default with no value passed on an<audio>, unsafe URL keeps the authored clip and warns.fails without the fix:
htmlCompiler.variableMedia.test.ts("reads the length and the one sound lane from the clip a variable binds", the declared-default audio case and the unsafe-URL warning case) fail againstorigin/main'shtmlCompiler.ts(3 fail, 1 pass); with the fix 4 pass.htmlCompiler.test.ts(177),naturalDuration(7),probeCount(1) and coreapplyVariableBindings(15) pass.Not covered
Bound media inside a sub-composition mount that carries its own
data-variable-valuesstill gets its length from the browser probe, as before (first case inhtmlCompiler.variableMedia.test.ts). Binding there needs the per-instance table that exists only after inlining.