fix(render): stream long low-memory captures (#2245)

This commit is contained in:
Miguel Ángel
2026-07-12 22:17:44 -04:00
committed by GitHub
parent 995885484f
commit 9c0c1f99d4
2 changed files with 14 additions and 2 deletions
@@ -431,6 +431,7 @@ describe("shouldUseStreamingEncode", () => {
const streamingEnabledConfig = {
enableStreamingEncode: true,
streamingEncodeMaxDurationSeconds: 240,
lowMemoryMode: false,
};
it("enables streaming for default single-worker video renders", () => {
@@ -473,6 +474,12 @@ describe("shouldUseStreamingEncode", () => {
),
).toBe(false);
});
it("keeps long single-worker renders streaming in low-memory mode", () => {
expect(
shouldUseStreamingEncode({ ...streamingEnabledConfig, lowMemoryMode: true }, "mp4", 1, 411),
).toBe(true);
});
});
describe("createCompiledFrameSrcResolver", () => {
@@ -1023,7 +1023,8 @@ function replaceBodyWithRenderClone(body: HTMLElement, renderClone: Element): vo
}
export function shouldUseStreamingEncode(
cfg: Pick<EngineConfig, "enableStreamingEncode" | "streamingEncodeMaxDurationSeconds">,
cfg: Pick<EngineConfig, "enableStreamingEncode" | "streamingEncodeMaxDurationSeconds"> &
Partial<Pick<EngineConfig, "lowMemoryMode">>,
outputFormat: NonNullable<RenderConfig["format"]>,
workerCount: number,
// Composition timeline duration in seconds.
@@ -1037,7 +1038,11 @@ export function shouldUseStreamingEncode(
if (outputFormat === "png-sequence") return false;
if (outputFormat === "gif") return false;
if (!Number.isFinite(durationSeconds) || durationSeconds <= 0) return false;
if (durationSeconds > cfg.streamingEncodeMaxDurationSeconds) return false;
// Low-memory mode already pins capture to one worker. Keep those renders on
// the streaming path regardless of duration so captured frames are drained
// directly into FFmpeg instead of accumulating hundreds of gigabytes of
// data URIs / disk frames until Chrome OOMs.
if (!cfg.lowMemoryMode && durationSeconds > cfg.streamingEncodeMaxDurationSeconds) return false;
// HF_DE_PARALLEL_STREAM (manual opt-in) / forceParallelStream (router):
// allow multi-worker streaming for the interleaved drawElement produce
// path. Contiguous-chunk parallel streaming stalls (worker k+1's first