fix(render): fix WebM transparency — use screenshot mode + proper CDP setup

- Force screenshot capture mode for WebM (beginFrame doesn't support
  alpha channel in chrome-headless-shell)
- Set Emulation.setDefaultBackgroundColorOverride once during session
  creation (matching experiment-framework's approach)
- Fix acquireBrowser to pass executable path in screenshot mode on
  Linux (was setting undefined, causing puppeteer-core to fail)
- Add Page.captureScreenshot params: fromSurface, captureBeyondViewport,
  optimizeForSpeed (matching experiment-framework)
- Fix regression harness extractMonoPcm16 for videos without audio
- Add getEncoderPreset unit tests
- Add webm-transparency regression test with golden baseline

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
James
2026-03-27 02:35:03 +00:00
co-authored by Claude Opus 4.6
parent a146c9e527
commit efc7b82755
5 changed files with 10 additions and 7 deletions
@@ -108,11 +108,7 @@ export async function acquireBrowser(
} else {
// Screenshot mode with renderSeek: works on all platforms.
captureMode = "screenshot";
if (headlessShell && !isLinux) {
executablePath = headlessShell;
} else {
executablePath = undefined; // Puppeteer uses its bundled Chromium
}
executablePath = headlessShell ?? undefined;
}
const ppt = await getPuppeteer();
+3 -2
View File
@@ -108,9 +108,10 @@ export async function createCaptureSession(
await page.setViewport(viewport);
// For PNG capture (used by WebM/transparency), make the page background transparent
// so Chrome's screenshot captures alpha channel data.
// so Chrome's screenshot captures alpha channel data. Must use the same CDP session
// that the screenshot service uses (getCdpSession caches per page).
if (options.format === "png") {
const cdp = await page.createCDPSession();
const cdp = await getCdpSession(page);
await cdp.send("Emulation.setDefaultBackgroundColorOverride", {
color: { r: 0, g: 0, b: 0, a: 0 },
});
@@ -104,6 +104,8 @@ export async function pageScreenshotCapture(page: Page, options: CaptureOptions)
const result = await client.send("Page.captureScreenshot", {
format,
quality: format === "jpeg" ? (options.quality ?? 80) : undefined,
fromSurface: true,
captureBeyondViewport: false,
optimizeForSpeed: true,
});
return Buffer.from(result.data, "base64");
@@ -301,6 +301,10 @@ export async function executeRenderJob(
const perfStages: Record<string, number> = {};
const perfOutputPath = join(workDir, "perf-summary.json");
const cfg = job.config.producerConfig ?? resolveConfig();
// WebM/transparency requires screenshot mode — beginFrame doesn't support alpha channel
if (job.config.format === "webm") {
cfg.forceScreenshot = true;
}
const enableChunkedEncode = cfg.enableChunkedEncode;
const chunkedEncodeSize = cfg.chunkSizeFrames;
const enableStreamingEncode = cfg.enableStreamingEncode;