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 = { const streamingEnabledConfig = {
enableStreamingEncode: true, enableStreamingEncode: true,
streamingEncodeMaxDurationSeconds: 240, streamingEncodeMaxDurationSeconds: 240,
lowMemoryMode: false,
}; };
it("enables streaming for default single-worker video renders", () => { it("enables streaming for default single-worker video renders", () => {
@@ -473,6 +474,12 @@ describe("shouldUseStreamingEncode", () => {
), ),
).toBe(false); ).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", () => { describe("createCompiledFrameSrcResolver", () => {
@@ -1023,7 +1023,8 @@ function replaceBodyWithRenderClone(body: HTMLElement, renderClone: Element): vo
} }
export function shouldUseStreamingEncode( export function shouldUseStreamingEncode(
cfg: Pick<EngineConfig, "enableStreamingEncode" | "streamingEncodeMaxDurationSeconds">, cfg: Pick<EngineConfig, "enableStreamingEncode" | "streamingEncodeMaxDurationSeconds"> &
Partial<Pick<EngineConfig, "lowMemoryMode">>,
outputFormat: NonNullable<RenderConfig["format"]>, outputFormat: NonNullable<RenderConfig["format"]>,
workerCount: number, workerCount: number,
// Composition timeline duration in seconds. // Composition timeline duration in seconds.
@@ -1037,7 +1038,11 @@ export function shouldUseStreamingEncode(
if (outputFormat === "png-sequence") return false; if (outputFormat === "png-sequence") return false;
if (outputFormat === "gif") return false; if (outputFormat === "gif") return false;
if (!Number.isFinite(durationSeconds) || durationSeconds <= 0) 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): // HF_DE_PARALLEL_STREAM (manual opt-in) / forceParallelStream (router):
// allow multi-worker streaming for the interleaved drawElement produce // allow multi-worker streaming for the interleaved drawElement produce
// path. Contiguous-chunk parallel streaming stalls (worker k+1's first // path. Contiguous-chunk parallel streaming stalls (worker k+1's first