diff --git a/packages/engine/src/services/chunkEncoder.test.ts b/packages/engine/src/services/chunkEncoder.test.ts index d97c3939e..4014afd38 100644 --- a/packages/engine/src/services/chunkEncoder.test.ts +++ b/packages/engine/src/services/chunkEncoder.test.ts @@ -154,6 +154,11 @@ describe("encodeFramesFromDir ffmpegEncodeTimeout", () => { expect(result.error).toContain("FFmpeg exited with code 143"); expect(result.error).toContain("terminated by timeout"); expect(result.error).toContain(encodeTimeoutMessage(1000)); + // Regression: the timeout message used to just state what happened, leaving + // the user to independently discover FFMPEG_ENCODE_TIMEOUT_MS and + // PRODUCER_ENABLE_CHUNKED_ENCODE (both already existed) on their own. + expect(result.error).toContain("FFMPEG_ENCODE_TIMEOUT_MS"); + expect(result.error).toContain("PRODUCER_ENABLE_CHUNKED_ENCODE"); }); it("keeps non-timeout ffmpeg failures unchanged", async () => { diff --git a/packages/engine/src/services/chunkEncoder.ts b/packages/engine/src/services/chunkEncoder.ts index 060e69aa7..44f3e68ab 100644 --- a/packages/engine/src/services/chunkEncoder.ts +++ b/packages/engine/src/services/chunkEncoder.ts @@ -44,7 +44,17 @@ export interface EncoderPreset { function appendEncodeTimeoutMessage(error: string, timedOut: boolean, timeoutMs: number): string { if (!timedOut) return error; - return `${error}\nFFmpeg killed after exceeding ffmpegEncodeTimeout (${timeoutMs} ms)`; + // Two independent reports of this exact timeout, both resolved by env vars + // that already exist but aren't named anywhere the user would see them at + // the point of failure — they had to go find FFMPEG_ENCODE_TIMEOUT_MS and + // PRODUCER_ENABLE_CHUNKED_ENCODE themselves. Name both here instead of + // just stating what happened. + return ( + `${error}\nFFmpeg killed after exceeding ffmpegEncodeTimeout (${timeoutMs} ms). ` + + "Long or high-frame-count renders may need more time: set FFMPEG_ENCODE_TIMEOUT_MS " + + "to a higher value (ms), or set PRODUCER_ENABLE_CHUNKED_ENCODE=true to encode in " + + "smaller chunks instead of one long-running ffmpeg process." + ); } function isAacSidecar(audioPath: string): boolean {