diff --git a/packages/producer/src/services/renderOrchestrator.ts b/packages/producer/src/services/renderOrchestrator.ts index 511052b196..9a1cf2acb2 100644 --- a/packages/producer/src/services/renderOrchestrator.ts +++ b/packages/producer/src/services/renderOrchestrator.ts @@ -1956,8 +1956,6 @@ export async function executeRenderJob( sparseStates: numStates - videoStateCount, }); - // CDP capture — toggle video visibility at video/non-video boundaries - const cdpClient = await probeSession.page.createCDPSession(); const stateFramePaths: string[] = []; let videosHidden = false; @@ -1969,63 +1967,83 @@ export async function executeRenderJob( videosHidden = true; } - const pixelPerfectVideoInjector = - pixelPerfectMode && frameLookup ? createVideoFrameInjector(frameLookup) : null; + if (pixelPerfectMode) { + // ── Pixel-perfect: use engine's deterministic capture pipeline ── + // Create a FRESH capture session with beginFrame mode and video + // frame injection — identical to the standard CDP render pipeline. + // This guarantees the same deterministic GSAP evaluation. + const ppSession = await createCaptureSession( + fileServer!.url, + join(workDir, "pixel-perfect-capture"), + { width, height, fps: job.config.fps }, + createVideoFrameInjector(frameLookup), + cfg, + ); + await initializeSession(ppSession); - for (let si = 0; si < numStates; si++) { - const t = stateTimes[si]!; - const inVideo = isInVideoRange(t); + for (let si = 0; si < numStates; si++) { + const t = stateTimes[si]!; + const frameIndex = Math.round(t * job.config.fps); - if (videoOverlays.length > 0) { - const vids = videoOverlays.map((v) => JSON.stringify(v.id)).join(","); - if (inVideo && videosHidden) { - await probeSession.page.evaluate( - `[${vids}].forEach(id=>{const e=document.getElementById(id);if(e)e.style.removeProperty("visibility")})`, + if (si % 100 === 0) { + const pct = Math.round(25 + (si / numStates) * 50); + updateJobStatus( + job, + "rendering", + `Pixel-perfect capture: ${si}/${numStates}`, + pct, + onProgress, ); - videosHidden = false; - } else if (!inVideo && !videosHidden) { - await probeSession.page.evaluate( - `[${vids}].forEach(id=>{` + - `const e=document.getElementById(id);if(e)e.style.setProperty("visibility","hidden","important");` + - `const img=e?.nextElementSibling;if(img?.classList.contains("__render_frame__"))img.style.visibility="hidden"` + - `})`, - ); - videosHidden = true; } - } - await probeSession.page.evaluate(`void(window.__hf?.seek(${t}))`); - if (inVideo && pixelPerfectVideoInjector) { - // Headless Chrome can't seek