fix(producer): preserve normalized audio mux duration

This commit is contained in:
Miguel Ángel
2026-07-25 21:14:18 +00:00
parent 20188d637b
commit 532461599b
2 changed files with 16 additions and 10 deletions
@@ -289,8 +289,11 @@ export async function assemble(
}
// ── 3. Audio: pad-or-trim then mux ────────────────────────────────────
let audioForMux: string | null = null;
let preserveAudioPrimingEditList = false;
let normalizedAudio: {
path: string;
preserveAudioPrimingEditList: boolean;
durationSeconds: number;
} | null = null;
if (audioPath !== null && existsSync(audioPath)) {
const paddedAudioPath = join(workDir, "audio-padded.m4a");
const padTrimResult = await padOrTrimAudioToVideoFrameCount({
@@ -302,8 +305,11 @@ export async function assemble(
if (!padTrimResult.success) {
throw new Error(`[assemble] audio pad/trim failed: ${padTrimResult.error}`);
}
audioForMux = paddedAudioPath;
preserveAudioPrimingEditList = padTrimResult.operation === "trim";
normalizedAudio = {
path: paddedAudioPath,
preserveAudioPrimingEditList: padTrimResult.operation === "trim",
durationSeconds: padTrimResult.targetDurationSeconds,
};
log.info("[assemble] audio normalized for mux", {
operation: padTrimResult.operation,
targetDurationSeconds: padTrimResult.targetDurationSeconds,
@@ -316,17 +322,17 @@ export async function assemble(
// because it operates on a `RenderJob` and emits `updateJobStatus`
// payloads — the distributed activity has no job to thread through.
const muxOutputPath =
audioForMux !== null ? join(workDir, `mux.${plan.dimensions.format}`) : postConcatPath;
if (audioForMux !== null) {
normalizedAudio !== null ? join(workDir, `mux.${plan.dimensions.format}`) : postConcatPath;
if (normalizedAudio !== null) {
const muxResult = await muxVideoWithAudio(
postConcatPath,
audioForMux,
normalizedAudio.path,
muxOutputPath,
abortSignal,
{
audioCodec: "aac",
preserveAudioPrimingEditList,
durationSeconds: padTrimResult.targetDurationSeconds,
preserveAudioPrimingEditList: normalizedAudio.preserveAudioPrimingEditList,
durationSeconds: normalizedAudio.durationSeconds,
},
{ num: plan.dimensions.fpsNum, den: plan.dimensions.fpsDen },
);
@@ -69,7 +69,7 @@ describe("runAssembleStage audio duration parity", () => {
"/tmp/audio.duration-normalized.m4a",
"/tmp/output.mp4",
undefined,
{ audioCodec: "aac", preserveAudioPrimingEditList: true },
{ audioCodec: "aac", preserveAudioPrimingEditList: true, durationSeconds: 1 },
{ num: 30, den: 1 },
);
});