diff --git a/packages/engine/src/services/chunkEncoder.test.ts b/packages/engine/src/services/chunkEncoder.test.ts index f0ce7adab..cc6325333 100644 --- a/packages/engine/src/services/chunkEncoder.test.ts +++ b/packages/engine/src/services/chunkEncoder.test.ts @@ -389,6 +389,7 @@ describe("muxVideoWithAudio audio codec handling", () => { ); await flushMuxCodecResolution(); + expect(calls[0]!.args).toContain("-shortest"); expect(calls[0]!.args).toContain("-t"); expect(calls[0]!.args).toContain("16.066667"); emitClose(calls[0]!.proc, 0); diff --git a/packages/engine/src/services/chunkEncoder.ts b/packages/engine/src/services/chunkEncoder.ts index a2d301781..e373520a7 100644 --- a/packages/engine/src/services/chunkEncoder.ts +++ b/packages/engine/src/services/chunkEncoder.ts @@ -709,6 +709,13 @@ export async function muxVideoWithAudio( args.push("-r", fpsToFfmpegArg(fps)); } if (config?.durationSeconds !== undefined) { + // Stream-copying a normalized AAC sidecar can preserve a longer packet + // timeline than its container/edit-list duration. `-t` alone limits the + // output timestamp window but does not prevent the copied audio stream's + // tail from extending the MP4 timeline. When an explicit video-derived + // duration is supplied, also stop at the shortest stream so the final + // mux boundary is deterministic. + args.push("-shortest"); args.push("-t", String(config.durationSeconds)); } args.push("-y", outputPath);