fix(engine): remove -shortest from muxVideoWithAudio (#1648) (#1650)

FFmpeg 6.0 (bundled by ffmpeg-static) has a regression where -shortest
combined with -c:v copy over-truncates the video stream while leaving
audio untouched. The flag is also redundant — the audio mixer already
pads/caps all tracks to totalDuration via apad=whole_dur and -t.

Closes #1648
This commit is contained in:
Miguel Ángel
2026-06-22 17:06:03 -04:00
committed by GitHub
parent 3a6742bd13
commit e9957ecaf4
2 changed files with 26 additions and 2 deletions
@@ -394,10 +394,10 @@ describe("muxVideoWithAudio audio codec handling", () => {
"make_zero",
"-r",
"30",
"-shortest",
"-y",
"/tmp/output.mp4",
]);
expect(calls[0]!.args).not.toContain("-shortest");
expect(calls[0]!.args).not.toContain("-use_editlist");
emitClose(calls[0]!.proc, 0);
@@ -545,6 +545,30 @@ describe("muxVideoWithAudio audio codec handling", () => {
await expect(muxPromise).resolves.toMatchObject({ success: true });
});
it("does not pass -shortest to ffmpeg (regression #1648)", async () => {
const { spawn, calls } = createSpawnSpy();
vi.resetModules();
vi.doMock("child_process", () => ({ spawn }));
const { muxVideoWithAudio } = await import("./chunkEncoder.js");
for (const ext of [".mp4", ".mov", ".webm"] as const) {
const muxPromise = muxVideoWithAudio(
`/tmp/video-only${ext}`,
"/tmp/audio.aac",
`/tmp/output${ext}`,
undefined,
undefined,
{ num: 30, den: 1 },
);
if (ext !== ".webm") await flushMuxCodecResolution();
const call = calls[calls.length - 1]!;
expect(call.args).not.toContain("-shortest");
emitClose(call.proc, 0);
await muxPromise;
}
});
it("keeps WebM audio on the Opus transcode path", async () => {
const { spawn, calls } = createSpawnSpy();
vi.resetModules();