mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(engine): supersample screenshot capture to honor deviceScaleFactor
This commit is contained in:
@@ -114,8 +114,14 @@ export async function createCaptureSession(
|
|||||||
const headlessShell = resolveHeadlessShellPath(config);
|
const headlessShell = resolveHeadlessShellPath(config);
|
||||||
const isLinux = process.platform === "linux";
|
const isLinux = process.platform === "linux";
|
||||||
const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG.forceScreenshot;
|
const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG.forceScreenshot;
|
||||||
|
// BeginFrame's screenshot does not honor a viewport `deviceScaleFactor`
|
||||||
|
// (the captured surface is sized by the OS window in CSS pixels regardless
|
||||||
|
// of `Emulation.setDeviceMetricsOverride`'s DPR). When supersampling we
|
||||||
|
// need explicit clip+scale on `Page.captureScreenshot`, so fall back to
|
||||||
|
// the screenshot path for any DPR > 1.
|
||||||
|
const supersampling = (options.deviceScaleFactor ?? 1) > 1;
|
||||||
const preMode: CaptureMode =
|
const preMode: CaptureMode =
|
||||||
headlessShell && isLinux && !forceScreenshot ? "beginframe" : "screenshot";
|
headlessShell && isLinux && !forceScreenshot && !supersampling ? "beginframe" : "screenshot";
|
||||||
const requestedGpuMode = config?.browserGpuMode ?? DEFAULT_CONFIG.browserGpuMode;
|
const requestedGpuMode = config?.browserGpuMode ?? DEFAULT_CONFIG.browserGpuMode;
|
||||||
const resolvedGpuMode = await resolveBrowserGpuMode(requestedGpuMode, {
|
const resolvedGpuMode = await resolveBrowserGpuMode(requestedGpuMode, {
|
||||||
chromePath: headlessShell ?? undefined,
|
chromePath: headlessShell ?? undefined,
|
||||||
|
|||||||
@@ -129,12 +129,20 @@ export async function beginFrameCapture(
|
|||||||
export async function pageScreenshotCapture(page: Page, options: CaptureOptions): Promise<Buffer> {
|
export async function pageScreenshotCapture(page: Page, options: CaptureOptions): Promise<Buffer> {
|
||||||
const client = await getCdpSession(page);
|
const client = await getCdpSession(page);
|
||||||
const isPng = options.format === "png";
|
const isPng = options.format === "png";
|
||||||
|
const dpr = options.deviceScaleFactor ?? 1;
|
||||||
|
// When supersampling, pass an explicit clip with `scale` so Chrome emits a
|
||||||
|
// screenshot at device-pixel dimensions (`width × height × dpr`). Without
|
||||||
|
// this, `Page.captureScreenshot` returns at CSS dimensions regardless of
|
||||||
|
// the viewport's deviceScaleFactor.
|
||||||
|
const clip =
|
||||||
|
dpr > 1 ? { x: 0, y: 0, width: options.width, height: options.height, scale: dpr } : undefined;
|
||||||
const result = await client.send("Page.captureScreenshot", {
|
const result = await client.send("Page.captureScreenshot", {
|
||||||
format: isPng ? "png" : "jpeg",
|
format: isPng ? "png" : "jpeg",
|
||||||
quality: isPng ? undefined : (options.quality ?? 80),
|
quality: isPng ? undefined : (options.quality ?? 80),
|
||||||
fromSurface: true,
|
fromSurface: true,
|
||||||
captureBeyondViewport: false,
|
captureBeyondViewport: false,
|
||||||
optimizeForSpeed: !isPng,
|
optimizeForSpeed: !isPng,
|
||||||
|
...(clip ? { clip } : {}),
|
||||||
});
|
});
|
||||||
return Buffer.from(result.data, "base64");
|
return Buffer.from(result.data, "base64");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user