feat(streamer): chromium cdp screencast driver
This commit is contained in:
parent
e0d93b03ae
commit
baef915561
1 changed files with 60 additions and 0 deletions
60
streamer/src/chrome.ts
Normal file
60
streamer/src/chrome.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import { EventEmitter } from "node:events";
|
||||
import puppeteer, { Browser, CDPSession, Page } from "puppeteer-core";
|
||||
|
||||
export interface ChromeOpts {
|
||||
pageUrl: string;
|
||||
width: number;
|
||||
height: number;
|
||||
framerate: number;
|
||||
jpegQuality?: number; // 0..100, default 85
|
||||
executablePath?: string; // default /usr/bin/chromium
|
||||
}
|
||||
|
||||
export class ChromeRenderer extends EventEmitter {
|
||||
private browser: Browser | null = null;
|
||||
private page: Page | null = null;
|
||||
private cdp: CDPSession | null = null;
|
||||
|
||||
constructor(private opts: ChromeOpts) { super(); }
|
||||
|
||||
async start(): Promise<void> {
|
||||
this.browser = await puppeteer.launch({
|
||||
executablePath: this.opts.executablePath ?? "/usr/bin/chromium",
|
||||
headless: true,
|
||||
args: [
|
||||
"--no-sandbox",
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-gpu",
|
||||
"--hide-scrollbars",
|
||||
`--window-size=${this.opts.width},${this.opts.height}`,
|
||||
"--autoplay-policy=no-user-gesture-required",
|
||||
],
|
||||
defaultViewport: { width: this.opts.width, height: this.opts.height },
|
||||
});
|
||||
this.page = await this.browser.newPage();
|
||||
await this.page.goto(this.opts.pageUrl, { waitUntil: "networkidle2" });
|
||||
|
||||
this.cdp = await this.page.target().createCDPSession();
|
||||
await this.cdp.send("Page.startScreencast", {
|
||||
format: "jpeg",
|
||||
quality: this.opts.jpegQuality ?? 85,
|
||||
everyNthFrame: 1,
|
||||
});
|
||||
|
||||
this.cdp.on("Page.screencastFrame", async (frame) => {
|
||||
const buf = Buffer.from(frame.data, "base64");
|
||||
this.emit("frame", buf);
|
||||
await this.cdp!.send("Page.screencastFrameAck", { sessionId: frame.sessionId });
|
||||
});
|
||||
|
||||
this.browser.on("disconnected", () => this.emit("disconnected"));
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
try { await this.cdp?.send("Page.stopScreencast"); } catch { /* ignore */ }
|
||||
await this.browser?.close().catch(() => {});
|
||||
this.browser = null;
|
||||
this.page = null;
|
||||
this.cdp = null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue