@remotion/renderer
Version:
Render Remotion videos using Node.js or Bun
213 lines (212 loc) • 9.89 kB
JavaScript
;
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;