UNPKG

brave-real-playwright-core

Version:

Brave-optimized Playwright Core (v1.55.0) with comprehensive stealth patches and error stack sanitization

114 lines (113 loc) 4.59 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var videoRecorder_exports = {}; __export(videoRecorder_exports, { VideoRecorder: () => VideoRecorder }); module.exports = __toCommonJS(videoRecorder_exports); var import_utils = require("../../utils"); var import_page = require("../page"); var import_processLauncher = require("../utils/processLauncher"); const fps = 25; class VideoRecorder { constructor(page, ffmpegPath) { this._process = null; this._gracefullyClose = null; this._lastWritePromise = Promise.resolve(); this._lastFrameTimestamp = 0; this._lastFrameBuffer = null; this._lastWriteTimestamp = 0; this._frameQueue = []; this._isStopped = false; this._ffmpegPath = ffmpegPath; page.on(import_page.Page.Events.ScreencastFrame, (frame) => this.writeFrame(frame.buffer, frame.frameSwapWallTime / 1e3)); } static async launch(page, ffmpegPath, options) { if (!options.outputFile.endsWith(".webm")) throw new Error("File must have .webm extension"); const recorder = new VideoRecorder(page, ffmpegPath); await recorder._launch(options); return recorder; } async _launch(options) { const w = options.width; const h = options.height; const args = `-loglevel error -f image2pipe -avioflags direct -fpsprobesize 0 -probesize 32 -analyzeduration 0 -c:v mjpeg -i pipe:0 -y -an -r ${fps} -c:v vp8 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M -threads 1 -vf pad=${w}:${h}:0:0:gray,crop=${w}:${h}:0:0`.split(" "); args.push(options.outputFile); const { launchedProcess, gracefullyClose } = await (0, import_processLauncher.launchProcess)({ command: this._ffmpegPath, args, stdio: "stdin", log: (message) => import_utils.debugLogger.log("browser", message), tempDirectories: [], attemptToGracefullyClose: async () => { import_utils.debugLogger.log("browser", "Closing stdin..."); launchedProcess.stdin.end(); }, onExit: (exitCode, signal) => { import_utils.debugLogger.log("browser", `ffmpeg onkill exitCode=${exitCode} signal=${signal}`); } }); launchedProcess.stdin.on("finish", () => { import_utils.debugLogger.log("browser", "ffmpeg finished input."); }); launchedProcess.stdin.on("error", () => { import_utils.debugLogger.log("browser", "ffmpeg error."); }); this._process = launchedProcess; this._gracefullyClose = gracefullyClose; } writeFrame(frame, timestamp) { (0, import_utils.assert)(this._process); if (this._isStopped) return; if (this._lastFrameBuffer) { const durationSec = timestamp - this._lastFrameTimestamp; const repeatCount = Math.max(1, Math.round(fps * durationSec)); for (let i = 0; i < repeatCount; ++i) this._frameQueue.push(this._lastFrameBuffer); this._lastWritePromise = this._lastWritePromise.then(() => this._sendFrames()); } this._lastFrameBuffer = frame; this._lastFrameTimestamp = timestamp; this._lastWriteTimestamp = (0, import_utils.monotonicTime)(); } async _sendFrames() { while (this._frameQueue.length) await this._sendFrame(this._frameQueue.shift()); } async _sendFrame(frame) { return new Promise((f) => this._process.stdin.write(frame, f)).then((error) => { if (error) import_utils.debugLogger.log("browser", `ffmpeg failed to write: ${String(error)}`); }); } async stop() { if (this._isStopped) return; this.writeFrame(Buffer.from([]), this._lastFrameTimestamp + ((0, import_utils.monotonicTime)() - this._lastWriteTimestamp) / 1e3); this._isStopped = true; await this._lastWritePromise; await this._gracefullyClose(); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { VideoRecorder });