From aa4b53533414e5669caf6a9910c499143bbe0465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Thu, 22 Oct 2026 22:35:17 +0000 Subject: [PATCH] fix(engine): publish video frames only after decoding (#6092) --- .../engine/src/services/screenshotService.ts | 6 +++- .../videoFrameTransport.browser.test.ts | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/engine/src/services/screenshotService.ts b/packages/engine/src/services/screenshotService.ts index d702f8bf17..8cc8487765 100644 --- a/packages/engine/src/services/screenshotService.ts +++ b/packages/engine/src/services/screenshotService.ts @@ -662,6 +662,7 @@ async function injectResolvedVideoFramesBatch( ) => { const injectedIds: string[] = []; const pendingDecodes: Array> = []; + const imagesToPublish: HTMLImageElement[] = []; const replacementLayoutProperties = new Set([ "width", "height", @@ -803,6 +804,8 @@ async function injectResolvedVideoFramesBatch( img.style.objectPosition = computedStyle.objectPosition; img.style.zIndex = computedStyle.zIndex; + // Publish after full decode so raster cannot race it with a reduced JPEG decode. + img.style.setProperty("visibility", "hidden", "important"); img.decoding = "sync"; if (img.getAttribute("src") !== item.dataUri) { if (item.crossOrigin) img.crossOrigin = item.crossOrigin; @@ -821,7 +824,7 @@ async function injectResolvedVideoFramesBatch( ); } img.style.opacity = String(computedOpacity); - img.style.visibility = "visible"; + imagesToPublish.push(img); // Hide the native