fix(engine): write the audio mix filter graph to a file, not the command line#1890
Draft
miguel-heygen wants to merge 1 commit into
Draft
fix(engine): write the audio mix filter graph to a file, not the command line#1890miguel-heygen wants to merge 1 commit into
miguel-heygen wants to merge 1 commit into
Conversation
…and line mixAudioTracks built the ffmpeg -filter_complex argument as one inline string scaling linearly with track count. Reported in the wild at 146 timed audio clips: the resulting command line exceeded the OS length limit and spawn failed with ENAMETOOLONG, dropping audio entirely until the user manually consolidated clips to reduce the count. FFmpeg supports -filter_complex_script specifically for this - the same filter graph read from a file instead of inlined as an argument. The -i pairs for each track still scale with count but stay short and fixed-size each, so the one component that actually grew unbounded (the filter string) no longer sits on the command line at all. The temp file is cleaned up immediately after ffmpeg exits, matching the existing sibling temp-file convention in audioVolumeEnvelope.ts. Verified end-to-end against a real ffmpeg binary (not just mocked): a two-track mix produced correct output audio with no leftover temp files.
| const inputs: string[] = []; | ||
| tracks.forEach((track) => inputs.push("-i", track.srcPath)); | ||
| const scriptPath = join(outputDir, `.filter-complex-${randomBytes(6).toString("hex")}.txt`); | ||
| writeFileSync(scriptPath, buildFilterComplex(ignoreAutomation)); |
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.
Summary
mixAudioTracksbuilt the ffmpeg-filter_complexargument as one inline string that scales linearly with track count. Reported in the wild at 146 timed audio clips: the resulting command line exceeded the OS argument-length limit andspawnfailed withENAMETOOLONG, dropping audio entirely until the user manually consolidated clips to reduce the count.Fix
FFmpeg supports
-filter_complex_script <file>specifically for this — the same filter graph read from a file instead of inlined as a command-line argument.-i <path>pairs for each track still scale with count, but each is short and fixed-size; the one component that actually grew unbounded (the filter graph string) is off the command line entirely.The temp script file is written right before the
runFfmpegcall and cleaned up immediately after it resolves (success or failure, via.finally()), matching the existing sibling temp-file convention already used inaudioVolumeEnvelope.ts.Test plan
bunx vitest run packages/engine/src/services/audioMixer.test.ts— 7 tests pass (6 existing, updated to read the filter graph from the mock's captured file content instead of the now-removed inline-filter_complexstring, + 1 new regression test)-filter_complex_script(not-filter_complex), and the captured filter script's content still contains a correctamix=inputs=150and oneatrim=segment per trackbunx vitest run packages/engine/— full package, 841 tests pass, no regressionsprocessCompositionAudiounmocked, confirmed correct output audio (right duration, right codec viaffprobe) and no leftover temp files after completion