fix(producer): scale high-quality encode timeout (#3649)

This commit is contained in:
Miguel Ángel
2026-09-04 23:15:37 +00:00
committed by GitHub
parent 2ca493094e
commit 50af764b7d
2 changed files with 64 additions and 3 deletions
@@ -259,6 +259,65 @@ describe("runEncodeStage config plumbing", () => {
});
});
it("gives the reported long high-quality encode a 24x source-duration budget", async () => {
const { runEncodeStage } = await import("./encodeStage.js");
const input = makeInput();
await runEncodeStage(
makeInput({
job: {
...input.job,
config: { ...input.job.config, quality: "high" },
duration: 331.273,
},
engineConfig: { ffmpegEncodeTimeout: 600_000 },
}),
);
expect(encodeFramesFromDirMock.mock.calls[0]?.[5]).toEqual({
ffmpegEncodeTimeout: 7_950_552,
});
});
it("keeps the 4x budget for a standard encode", async () => {
const { runEncodeStage } = await import("./encodeStage.js");
const input = makeInput();
await runEncodeStage(
makeInput({
job: {
...input.job,
config: { ...input.job.config, quality: "standard" },
duration: 331.273,
},
engineConfig: { ffmpegEncodeTimeout: 600_000 },
}),
);
expect(encodeFramesFromDirMock.mock.calls[0]?.[5]).toEqual({
ffmpegEncodeTimeout: 1_325_092,
});
});
it("preserves a larger operator timeout for high-quality encoding", async () => {
const { runEncodeStage } = await import("./encodeStage.js");
const input = makeInput();
const operatorConfig = { ffmpegEncodeTimeout: 9_000_000 };
await runEncodeStage(
makeInput({
job: {
...input.job,
config: { ...input.job.config, quality: "high" },
duration: 331.273,
},
engineConfig: operatorConfig,
}),
);
expect(encodeFramesFromDirMock.mock.calls[0]?.[5]).toBe(operatorConfig);
});
it("prefers engine config supplied by the orchestrator", async () => {
const { runEncodeStage } = await import("./encodeStage.js");
const orchestratorEngineConfig = { ffmpegEncodeTimeout: 54_321 };
@@ -289,9 +289,11 @@ export async function runEncodeStage(input: EncodeStageInput): Promise<EncodeSta
// ffmpegEncodeTimeout is a total wall-clock cap, not an inactivity timeout.
// A fixed ten-minute cap reliably kills long high-quality disk-frame encodes
// that are still making progress. Preserve larger operator overrides while
// guaranteeing four seconds of encode budget per second of source video.
const scaledEncodeTimeout = Math.ceil((job.duration ?? 0) * 4_000);
// that are still making progress. High-quality CPU presets are substantially
// slower, so reserve 24x source duration there while retaining the established
// 4x budget for draft/standard and preserving larger operator overrides.
const baseScaledEncodeTimeout = Math.ceil((job.duration ?? 0) * 4_000);
const scaledEncodeTimeout = baseScaledEncodeTimeout * (job.config.quality === "high" ? 6 : 1);
const videoEngineCfg =
scaledEncodeTimeout > engineCfg.ffmpegEncodeTimeout
? { ...engineCfg, ffmpegEncodeTimeout: scaledEncodeTimeout }