UNPKG

@remotion/renderer

Version:

Render Remotion videos using Node.js or Bun

213 lines (212 loc) 9.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setPropsAndEnv = void 0; const version_1 = require("remotion/version"); const TimeoutSettings_1 = require("./browser/TimeoutSettings"); const goto_page_or_throw_1 = require("./goto-page-or-throw"); const logger_1 = require("./logger"); const normalize_serve_url_1 = require("./normalize-serve-url"); const puppeteer_evaluate_1 = require("./puppeteer-evaluate"); const redirect_status_codes_1 = require("./redirect-status-codes"); const truthy_1 = require("./truthy"); const validate_puppeteer_timeout_1 = require("./validate-puppeteer-timeout"); const innerSetPropsAndEnv = async ({ serializedInputPropsWithCustomSchema, envVariables, page, serveUrl, initialFrame, timeoutInMilliseconds, proxyPort, retriesRemaining, audioEnabled, videoEnabled, indent, logLevel, onServeUrlVisited, }) => { (0, validate_puppeteer_timeout_1.validatePuppeteerTimeout)(timeoutInMilliseconds); const actualTimeout = timeoutInMilliseconds !== null && timeoutInMilliseconds !== void 0 ? timeoutInMilliseconds : TimeoutSettings_1.DEFAULT_TIMEOUT; page.setDefaultTimeout(actualTimeout); page.setDefaultNavigationTimeout(actualTimeout); const urlToVisit = (0, normalize_serve_url_1.normalizeServeUrl)(serveUrl); await page.evaluateOnNewDocument((timeout) => { window.remotion_puppeteerTimeout = timeout; // To make getRemotionEnvironment() work if (window.process === undefined) { // @ts-expect-error window.process = {}; } if (window.process.env === undefined) { window.process.env = {}; } window.process.env.NODE_ENV = 'production'; }, actualTimeout); if (envVariables) { await page.evaluateOnNewDocument((input) => { window.remotion_envVariables = input; }, JSON.stringify(envVariables)); } await page.evaluateOnNewDocument((input, key, port, audEnabled, vidEnabled, level) => { window.remotion_inputProps = input; window.remotion_initialFrame = key; window.remotion_attempt = 1; window.remotion_proxyPort = port; window.remotion_audioEnabled = audEnabled; window.remotion_videoEnabled = vidEnabled; window.remotion_logLevel = level; window.alert = (message) => { if (message) { window.window.remotion_cancelledError = new Error(`alert("${message}") was called. It cannot be called in a headless browser.`).stack; } else { window.window.remotion_cancelledError = new Error('alert() was called. It cannot be called in a headless browser.').stack; } }; window.confirm = (message) => { if (message) { window.remotion_cancelledError = new Error(`confirm("${message}") was called. It cannot be called in a headless browser.`).stack; } else { window.remotion_cancelledError = new Error('confirm() was called. It cannot be called in a headless browser.').stack; } return false; }; }, serializedInputPropsWithCustomSchema, initialFrame, proxyPort, audioEnabled, videoEnabled, logLevel); const retry = async () => { await new Promise((resolve) => { setTimeout(() => { resolve(); }, 2000); }); return innerSetPropsAndEnv({ envVariables, initialFrame, serializedInputPropsWithCustomSchema, page, proxyPort, retriesRemaining: retriesRemaining - 1, serveUrl, timeoutInMilliseconds, audioEnabled, videoEnabled, indent, logLevel, onServeUrlVisited, }); }; const [pageRes, error] = await (0, goto_page_or_throw_1.gotoPageOrThrow)(page, urlToVisit, actualTimeout); if (error !== null) { if (error.message.includes('ECONNRESET') || error.message.includes('ERR_CONNECTION_TIMED_OUT')) { return retry(); } throw error; } const status = pageRes.status(); // S3 in rare occasions returns a 500 or 503 error code for GET operations. // Usually it is fixed by retrying. if (status >= 500 && status <= 504 && retriesRemaining > 0) { return retry(); } if (!redirect_status_codes_1.redirectStatusCodes.every((code) => code !== status)) { throw new Error(`Error while getting compositions: Tried to go to ${urlToVisit} but the status code was ${status} instead of 200. Does the site you specified exist?`); } onServeUrlVisited(); const { value: isRemotionFn } = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({ pageFunction: () => { return window.getStaticCompositions; }, args: [], frame: null, page, timeoutInMilliseconds: actualTimeout, }); if (typeof isRemotionFn === 'undefined') { const { value: body } = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({ pageFunction: () => { return document.body.innerHTML; }, args: [], frame: null, page, timeoutInMilliseconds: actualTimeout, }); // AWS shakyness if (body.includes('We encountered an internal error.')) { return retry(); } const errorMessage = [ `Error while getting compositions: Tried to go to ${urlToVisit} and verify that it is a Remotion project by checking if window.getStaticCompositions is defined.`, 'However, the function was undefined, which indicates that this is not a valid Remotion project. Please check the URL you passed.', 'The page loaded contained the following markup:', body.substring(0, 500) + (body.length > 500 ? '...' : ''), 'Does this look like a foreign page? If so, try to stop this server.', ].join('\n'); throw new Error(errorMessage); } const { value: siteVersion } = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({ pageFunction: () => { return window.siteVersion; }, args: [], frame: null, page, timeoutInMilliseconds: actualTimeout, }); const { value: remotionVersion } = await (0, puppeteer_evaluate_1.puppeteerEvaluateWithCatch)({ pageFunction: () => { return window.remotion_version; }, args: [], frame: null, page, timeoutInMilliseconds: actualTimeout, }); const requiredVersion = '11'; if (siteVersion !== requiredVersion) { throw new Error([ `Incompatible site: When visiting ${urlToVisit}, a bundle was found, but one that is not compatible with this version of Remotion. Found version: ${siteVersion} - Required version: ${requiredVersion}. To resolve this error:`, 'When using server-side rendering:', ` ▸ Use 'bundle()' with '@remotion/bundler' of version ${version_1.VERSION} to create a compatible bundle.`, 'When using the Remotion Lambda:', ' ▸ Use `npx remotion lambda sites create` to redeploy the site with the latest version.', ' ℹ Use --site-name with the same name as before to overwrite your site.', ' ▸ Use `deploySite()` if you are using the Node.JS APIs.', ].join('\n')); } if (remotionVersion !== version_1.VERSION && process.env.NODE_ENV !== 'test') { if (remotionVersion) { logger_1.Log.warn({ indent, logLevel, }, [ `The site was bundled with version ${remotionVersion} of @remotion/bundler, while @remotion/renderer is on version ${version_1.VERSION}. You may not have the newest bugfixes and features.`, `To resolve this warning:`, '▸ Use `npx remotion lambda sites create` to redeploy the site with the latest version.', ' ℹ Use --site-name with the same name as before to overwrite your site.', '▸ Use `deploySite()` if you are using the Node.JS APIs.', ].join('\n')); } else { logger_1.Log.warn({ indent, logLevel, }, `The site was bundled with an old version of Remotion, while @remotion/renderer is on version ${version_1.VERSION}. You may not have the newest bugfixes and features. Re-bundle the site to fix this issue.`); } } }; const setPropsAndEnv = async (params) => { let timeout = null; try { const result = await Promise.race([ innerSetPropsAndEnv(params), new Promise((_, reject) => { timeout = setTimeout(() => { reject(new Error([ `Timed out after ${params.timeoutInMilliseconds}ms while setting up the headless browser.`, 'This could be because the you specified takes a long time to load (or network resources that it includes like fonts) or because the browser is not responding.', process.platform === 'linux' ? 'Make sure you have installed the Linux depdendencies: https://www.remotion.dev/docs/miscellaneous/linux-dependencies' : null, ] .filter(truthy_1.truthy) .join('\n'))); }, params.timeoutInMilliseconds); }), ]); return result; } finally { if (timeout !== null) { clearTimeout(timeout); } } }; exports.setPropsAndEnv = setPropsAndEnv;