fix(render): scope M4A priming preservation to trims

This commit is contained in:
Miguel Ángel
2026-07-25 21:14:17 +00:00
parent 59c56d3257
commit 9289551e98
5 changed files with 36 additions and 5 deletions
@@ -418,7 +418,7 @@ describe("muxVideoWithAudio audio codec handling", () => {
});
});
it("preserves M4A priming edit lists instead of shifting copied video", async () => {
it("keeps negative-timestamp repair for an M4A without a known priming edit list", async () => {
const { spawn, calls } = createSpawnSpy();
vi.resetModules();
vi.doMock("child_process", () => ({ spawn }));
@@ -433,6 +433,30 @@ describe("muxVideoWithAudio audio codec handling", () => {
{ num: 30, den: 1 },
);
await flushMuxCodecResolution();
expect(calls).toHaveLength(1);
expect(calls[0]!.args).toContain("copy");
expect(calls[0]!.args).toContain("-avoid_negative_ts");
emitClose(calls[0]!.proc, 0);
await expect(muxPromise).resolves.toMatchObject({ success: true });
});
it("preserves a known M4A priming edit list instead of shifting copied video", async () => {
const { spawn, calls } = createSpawnSpy();
vi.resetModules();
vi.doMock("child_process", () => ({ spawn }));
const { muxVideoWithAudio } = await import("./chunkEncoder.js");
const muxPromise = muxVideoWithAudio(
"/tmp/video-only.mp4",
"/tmp/audio.duration-normalized.m4a",
"/tmp/output.mp4",
undefined,
{ audioCodec: "aac", preserveAudioPrimingEditList: true },
{ num: 30, den: 1 },
);
await flushMuxCodecResolution();
expect(calls).toHaveLength(1);
expect(calls[0]!.args).toContain("copy");
+3 -1
View File
@@ -77,6 +77,8 @@ export interface MuxVideoWithAudioOptions extends Partial<
* depend on the file extension alone.
*/
audioCodec?: "aac";
/** Preserve a priming edit list known to have been created by AAC re-encoding. */
preserveAudioPrimingEditList?: boolean;
}
async function shouldCopyAacSidecar(
@@ -691,7 +693,7 @@ export async function muxVideoWithAudio(
}
}
const copiesContainerizedAac =
!isWebm && shouldCopyAudio && extname(audioPath).toLowerCase() === ".m4a";
!isWebm && shouldCopyAudio && config?.preserveAudioPrimingEditList === true;
// PTS bases can diverge during mux and reintroduce negative DTS. See
// buildEncoderArgs for the full reasoning on why that breaks playback.
// A freshly encoded M4A is the exception: its edit list already hides the