@remotion/renderer
Version:
Render Remotion videos using Node.js or Bun
201 lines (200 loc) • 10.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.openBrowser = exports.internalOpenBrowser = void 0;
const node_fs_1 = __importDefault(require("node:fs"));
const node_os_1 = __importDefault(require("node:os"));
const node_path_1 = __importDefault(require("node:path"));
const browser_download_progress_bar_1 = require("./browser/browser-download-progress-bar");
const Launcher_1 = require("./browser/Launcher");
const ensure_browser_1 = require("./ensure-browser");
const get_local_browser_executable_1 = require("./get-local-browser-executable");
const get_video_threads_flag_1 = require("./get-video-threads-flag");
const logger_1 = require("./logger");
const gl_1 = require("./options/gl");
const featuresToEnable = (option) => {
const renderer = option !== null && option !== void 0 ? option : gl_1.DEFAULT_OPENGL_RENDERER;
const enableAlways = ['NetworkService', 'NetworkServiceInProcess'];
if (renderer === 'vulkan') {
return [...enableAlways, 'Vulkan', 'UseSkiaRenderer'];
}
if (renderer === 'angle-egl') {
return [...enableAlways, 'VaapiVideoDecoder'];
}
return enableAlways;
};
const getOpenGlRenderer = (option) => {
const renderer = option !== null && option !== void 0 ? option : gl_1.DEFAULT_OPENGL_RENDERER;
(0, gl_1.validateOpenGlRenderer)(renderer);
if (renderer === 'swangle') {
return ['--use-gl=angle', '--use-angle=swiftshader'];
}
if (renderer === 'angle-egl') {
return ['--use-gl=angle', '--use-angle=gl-egl'];
}
if (renderer === 'vulkan') {
return [
'--use-angle=vulkan',
'--use-vulkan=native',
'--disable-vulkan-fallback-to-gl-for-testing',
'--disable-vulkan-surface',
'--ignore-gpu-blocklist',
'--enable-gpu',
];
}
if (renderer === null) {
return [];
}
return [`--use-gl=${renderer}`];
};
const internalOpenBrowser = async ({ browser, browserExecutable, chromiumOptions, forceDeviceScaleFactor, indent, viewport, logLevel, onBrowserDownload, chromeMode, }) => {
var _a, _b, _c, _d;
// @ts-expect-error Firefox
if (browser === 'firefox') {
throw new TypeError('Firefox supported is not yet turned on. Stay tuned for the future.');
}
logger_1.Log.verbose({ indent, logLevel }, 'Ensuring browser executable');
await (0, ensure_browser_1.internalEnsureBrowser)({
browserExecutable,
logLevel,
indent,
onBrowserDownload,
chromeMode,
});
logger_1.Log.verbose({ indent, logLevel }, 'Ensured browser is available.');
const executablePath = (0, get_local_browser_executable_1.getLocalBrowserExecutable)({
preferredBrowserExecutable: browserExecutable,
logLevel,
indent,
chromeMode,
});
const customGlRenderer = getOpenGlRenderer((_a = chromiumOptions.gl) !== null && _a !== void 0 ? _a : null);
const enableMultiProcessOnLinux = (_b = chromiumOptions.enableMultiProcessOnLinux) !== null && _b !== void 0 ? _b : true;
logger_1.Log.verbose({ indent, logLevel, tag: 'openBrowser()' }, `Opening browser: gl = ${chromiumOptions.gl}, executable = ${executablePath}, enableMultiProcessOnLinux = ${enableMultiProcessOnLinux}`);
if (chromiumOptions.userAgent) {
logger_1.Log.verbose({ indent, logLevel, tag: 'openBrowser()' }, `Using custom user agent: ${chromiumOptions.userAgent}`);
}
const userDataDir = await node_fs_1.default.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), 'puppeteer_dev_chrome_profile-'));
const browserInstance = await (0, Launcher_1.launchChrome)({
executablePath,
logLevel,
indent,
userDataDir,
timeout: 25000,
args: [
'about:blank',
'--allow-pre-commit-input',
'--disable-background-networking',
`--enable-features=${featuresToEnable(chromiumOptions.gl).join(',')}`,
'--disable-background-timer-throttling',
'--disable-backgrounding-occluded-windows',
'--disable-breakpad',
'--disable-client-side-phishing-detection',
'--disable-component-extensions-with-background-pages',
'--disable-default-apps',
'--disable-dev-shm-usage',
'--no-proxy-server',
"--proxy-server='direct://'",
'--proxy-bypass-list=*',
'--force-gpu-mem-available-mb=4096',
'--disable-hang-monitor',
'--disable-extensions',
'--allow-chrome-scheme-url',
'--disable-ipc-flooding-protection',
'--disable-popup-blocking',
'--disable-prompt-on-repost',
'--disable-renderer-backgrounding',
'--disable-sync',
'--force-color-profile=srgb',
'--metrics-recording-only',
'--mute-audio',
'--no-first-run',
`--video-threads=${(0, get_video_threads_flag_1.getIdealVideoThreadsFlag)(logLevel)}`,
'--enable-automation',
'--password-store=basic',
'--use-mock-keychain',
'--enable-blink-features=IdleDetection',
'--export-tagged-pdf',
'--intensive-wake-up-throttling-policy=0',
((_c = chromiumOptions.headless) !== null && _c !== void 0 ? _c : true)
? chromeMode === 'chrome-for-testing'
? '--headless=new'
: '--headless=old'
: null,
'--no-sandbox',
'--disable-setuid-sandbox',
...customGlRenderer,
'--disable-background-media-suspend',
process.platform === 'linux' &&
chromiumOptions.gl !== 'vulkan' &&
!enableMultiProcessOnLinux
? '--single-process'
: null,
'--allow-running-insecure-content', // https://source.chromium.org/search?q=lang:cpp+symbol:kAllowRunningInsecureContent&ss=chromium
'--disable-component-update', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableComponentUpdate&ss=chromium
'--disable-domain-reliability', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableDomainReliability&ss=chromium
'--disable-features=AudioServiceOutOfProcess,IsolateOrigins,site-per-process,Translate,BackForwardCache,AvoidUnnecessaryBeforeUnloadCheckSync,IntensiveWakeUpThrottling', // https://source.chromium.org/search?q=file:content_features.cc&ss=chromium
'--disable-print-preview', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisablePrintPreview&ss=chromium
'--disable-site-isolation-trials', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableSiteIsolation&ss=chromium
'--disk-cache-size=268435456', // https://source.chromium.org/search?q=lang:cpp+symbol:kDiskCacheSize&ss=chromium
'--hide-scrollbars', // https://source.chromium.org/search?q=lang:cpp+symbol:kHideScrollbars&ss=chromium
'--no-default-browser-check', // https://source.chromium.org/search?q=lang:cpp+symbol:kNoDefaultBrowserCheck&ss=chromium
'--no-pings', // https://source.chromium.org/search?q=lang:cpp+symbol:kNoPings&ss=chromium
'--font-render-hinting=none',
'--no-zygote', // https://source.chromium.org/search?q=lang:cpp+symbol:kNoZygote&ss=chromium,
'--ignore-gpu-blocklist',
'--enable-unsafe-webgpu',
typeof forceDeviceScaleFactor === 'undefined'
? null
: `--force-device-scale-factor=${forceDeviceScaleFactor}`,
chromiumOptions.ignoreCertificateErrors
? '--ignore-certificate-errors'
: null,
...((chromiumOptions === null || chromiumOptions === void 0 ? void 0 : chromiumOptions.disableWebSecurity)
? ['--disable-web-security']
: []),
(chromiumOptions === null || chromiumOptions === void 0 ? void 0 : chromiumOptions.userAgent)
? `--user-agent="${chromiumOptions.userAgent}"`
: null,
'--remote-debugging-port=0',
`--user-data-dir=${userDataDir}`,
].filter(Boolean),
defaultViewport: viewport !== null && viewport !== void 0 ? viewport : {
height: 720,
width: 1280,
deviceScaleFactor: 1,
},
});
const pages = await browserInstance.pages();
await ((_d = pages[0]) === null || _d === void 0 ? void 0 : _d.close());
return browserInstance;
};
exports.internalOpenBrowser = internalOpenBrowser;
/*
* @description Opens a Chrome or Chromium browser instance. By reusing an instance across various rendering and compositional API calls, significant time can be saved by avoiding the repeated opening and closing of browsers.
* @see [Documentation](https://www.remotion.dev/docs/renderer/open-browser)
*/
const openBrowser = (browser, options) => {
var _a, _b;
const { browserExecutable, chromiumOptions, forceDeviceScaleFactor } = options !== null && options !== void 0 ? options : {};
const indent = false;
const logLevel = (_a = options === null || options === void 0 ? void 0 : options.logLevel) !== null && _a !== void 0 ? _a : ((options === null || options === void 0 ? void 0 : options.shouldDumpIo) ? 'verbose' : 'info');
return (0, exports.internalOpenBrowser)({
browser,
browserExecutable: browserExecutable !== null && browserExecutable !== void 0 ? browserExecutable : null,
chromiumOptions: chromiumOptions !== null && chromiumOptions !== void 0 ? chromiumOptions : {},
forceDeviceScaleFactor,
indent,
viewport: null,
logLevel,
onBrowserDownload: (0, browser_download_progress_bar_1.defaultBrowserDownloadProgress)({
indent,
logLevel,
api: 'openBrowser()',
}),
chromeMode: (_b = options === null || options === void 0 ? void 0 : options.chromeMode) !== null && _b !== void 0 ? _b : 'headless-shell',
});
};
exports.openBrowser = openBrowser;