Summary
The encode stage calls encodeFramesFromDir with 5 arguments while the function takes 6 — the trailing config parameter is never passed. As a result the encode timeout always falls back to the hardcoded default (600000 ms), and the env-aware resolveConfig() is never consulted on this path. Any encode whose wall time exceeds 600s is deterministically killed (FFmpeg exited with code 255, ffmpeg logs Exiting normally, received signal 15), no matter what timeout envs are set.
Verified in 0.6.56 and still present in 0.6.91 (dist/cli.js):
// definition (6 params)
encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) { ... }
// call site (5 args — config is undefined)
encodeFramesFromDir(framesDir, framePattern, videoOnlyPath, encoderOpts, abortSignal)
Inside, the timeout resolves as config?.ffmpegEncodeTimeout ?? 600000 → always 600000.
Symptom
- vp9 alpha encode of a UI overlay at 30 fps encodes at ~10–15 fps on a CPU-bound machine, so any capture longer than ~210s pushes the encode past 600s → hard kill after exactly ~600s wall time.
FFMPEG_ENCODE_TIMEOUT_MS, FFMPEG_PROCESS_TIMEOUT_MS, FFMPEG_STREAMING_TIMEOUT_MS have no effect on this path. We verified via /proc/<pid>/environ that the env vars were present in the hyperframes node process — they simply never reach the encode call.
- The failure looks flaky from the outside: shorter/low-load runs slip under 600s, loaded runs of the same video die. It is deterministic timeout math, not flakiness.
- Diagnostic fingerprint: ffmpeg prints its
Lsize= trailer and then Exiting normally, received signal 15 — i.e. an external kill, not an ffmpeg crash.
Repro
- Produce a frames dir long enough that vp9 alpha encoding takes > 600s wall (e.g. ~210s+ of 30 fps frames on a CPU-only encoder).
- Set
FFMPEG_ENCODE_TIMEOUT_MS=2400000.
- Run the encode → killed at ~600s regardless.
Workaround
PRODUCER_ENABLE_CHUNKED_ENCODE=true — the chunked path applies the 600s default per chunk (~360 frames ≈ 36s of encode), which never trips. With chunking enabled the same renders on the same machine pass reliably (verified across 3 consecutive renders that previously failed 6 times in a row).
Suggested fix
Pass the resolved config through at the call site (6th argument), or resolve it inside encodeFramesFromDir when the parameter is absent — either restores the documented env override behavior.
Found while reading the minified dist/cli.js of 0.6.56/0.6.91; happy to provide full ffmpeg stderr tails or timing logs if useful.
Summary
The encode stage calls
encodeFramesFromDirwith 5 arguments while the function takes 6 — the trailingconfigparameter is never passed. As a result the encode timeout always falls back to the hardcoded default (600000 ms), and the env-awareresolveConfig()is never consulted on this path. Any encode whose wall time exceeds 600s is deterministically killed (FFmpeg exited with code 255, ffmpeg logsExiting normally, received signal 15), no matter what timeout envs are set.Verified in 0.6.56 and still present in 0.6.91 (
dist/cli.js):Inside, the timeout resolves as
config?.ffmpegEncodeTimeout ?? 600000→ always 600000.Symptom
FFMPEG_ENCODE_TIMEOUT_MS,FFMPEG_PROCESS_TIMEOUT_MS,FFMPEG_STREAMING_TIMEOUT_MShave no effect on this path. We verified via/proc/<pid>/environthat the env vars were present in the hyperframes node process — they simply never reach the encode call.Lsize=trailer and thenExiting normally, received signal 15— i.e. an external kill, not an ffmpeg crash.Repro
FFMPEG_ENCODE_TIMEOUT_MS=2400000.Workaround
PRODUCER_ENABLE_CHUNKED_ENCODE=true— the chunked path applies the 600s default per chunk (~360 frames ≈ 36s of encode), which never trips. With chunking enabled the same renders on the same machine pass reliably (verified across 3 consecutive renders that previously failed 6 times in a row).Suggested fix
Pass the resolved config through at the call site (6th argument), or resolve it inside
encodeFramesFromDirwhen the parameter is absent — either restores the documented env override behavior.Found while reading the minified
dist/cli.jsof 0.6.56/0.6.91; happy to provide full ffmpeg stderr tails or timing logs if useful.