@remotion/renderer
Version:
Render Remotion videos using Node.js or Bun
350 lines (342 loc) • 13.4 kB
JavaScript
// src/chalk/is-color-supported.ts
import * as tty from "tty";
var isColorSupported = () => {
const env = process.env || {};
const isForceDisabled = "NO_COLOR" in env;
if (isForceDisabled) {
return false;
}
const isForced = "FORCE_COLOR" in env;
if (isForced) {
return true;
}
const isWindows = process.platform === "win32";
const isCompatibleTerminal = tty?.isatty?.(1) && env.TERM && env.TERM !== "dumb";
const isCI = "CI" in env && (("GITHUB_ACTIONS" in env) || ("GITLAB_CI" in env) || ("CIRCLECI" in env));
return isWindows || isCompatibleTerminal || isCI;
};
// src/chalk/index.ts
var chalk = (() => {
const colors = {
enabled: () => isColorSupported(),
visible: true,
styles: {},
keys: {}
};
const ansi = (st) => {
const open = `\x1B[${st.codes[0]}m`;
const close = `\x1B[${st.codes[1]}m`;
const regex = new RegExp(`\\u001b\\[${st.codes[1]}m`, "g");
st.wrap = (input, newline) => {
if (input.includes(close))
input = input.replace(regex, close + open);
const output = open + input + close;
return newline ? output.replace(/\r*\n/g, `${close}$&${open}`) : output;
};
return st;
};
const wrap = (sty, input, newline) => {
return sty.wrap?.(input, newline);
};
const style = (input, stack) => {
if (input === "" || input === null || input === undefined)
return "";
if (colors.enabled() === false)
return input;
if (colors.visible === false)
return "";
let str = String(input);
const nl = str.includes(`
`);
let n = stack.length;
while (n-- > 0)
str = wrap(colors.styles[stack[n]], str, nl);
return str;
};
const define = (name, codes, type) => {
colors.styles[name] = ansi({ name, codes });
const keys = colors.keys[type] || (colors.keys[type] = []);
keys.push(name);
Reflect.defineProperty(colors, name, {
configurable: true,
enumerable: true,
set(value) {
colors.alias?.(name, value);
},
get() {
const color = (input) => style(input, color.stack);
Reflect.setPrototypeOf(color, colors);
color.stack = this.stack ? this.stack.concat(name) : [name];
return color;
}
});
};
define("reset", [0, 0], "modifier");
define("bold", [1, 22], "modifier");
define("dim", [2, 22], "modifier");
define("italic", [3, 23], "modifier");
define("underline", [4, 24], "modifier");
define("inverse", [7, 27], "modifier");
define("hidden", [8, 28], "modifier");
define("strikethrough", [9, 29], "modifier");
define("black", [30, 39], "color");
define("red", [31, 39], "color");
define("green", [32, 39], "color");
define("yellow", [33, 39], "color");
define("blue", [34, 39], "color");
define("magenta", [35, 39], "color");
define("cyan", [36, 39], "color");
define("white", [37, 39], "color");
define("gray", [90, 39], "color");
define("grey", [90, 39], "color");
define("bgBlack", [40, 49], "bg");
define("bgRed", [41, 49], "bg");
define("bgGreen", [42, 49], "bg");
define("bgYellow", [43, 49], "bg");
define("bgBlue", [44, 49], "bg");
define("bgMagenta", [45, 49], "bg");
define("bgWhite", [47, 49], "bg");
define("blackBright", [90, 39], "bright");
define("redBright", [91, 39], "bright");
define("greenBright", [92, 39], "bright");
define("yellowBright", [93, 39], "bright");
define("blueBright", [94, 39], "bright");
define("magentaBright", [95, 39], "bright");
define("whiteBright", [97, 39], "bright");
define("bgBlackBright", [100, 49], "bgBright");
define("bgRedBright", [101, 49], "bgBright");
define("bgGreenBright", [102, 49], "bgBright");
define("bgYellowBright", [103, 49], "bgBright");
define("bgBlueBright", [104, 49], "bgBright");
define("bgMagentaBright", [105, 49], "bgBright");
define("bgWhiteBright", [107, 49], "bgBright");
colors.alias = (name, color) => {
const fn = colors[color];
if (typeof fn !== "function") {
throw new TypeError("Expected alias to be the name of an existing color (string) or a function");
}
if (!fn.stack) {
Reflect.defineProperty(fn, "name", { value: name });
colors.styles[name] = fn;
fn.stack = [name];
}
Reflect.defineProperty(colors, name, {
configurable: true,
enumerable: true,
set(value) {
colors.alias?.(name, value);
},
get() {
const col = (input) => style(input, col.stack);
Reflect.setPrototypeOf(col, colors);
col.stack = this.stack ? this.stack.concat(fn.stack) : fn.stack;
return col;
}
});
};
return colors;
})();
// src/log-level.ts
var logLevels = ["trace", "verbose", "info", "warn", "error"];
var getNumberForLogLevel = (level) => {
return logLevels.indexOf(level);
};
var isEqualOrBelowLogLevel = (currentLevel, level) => {
return getNumberForLogLevel(currentLevel) <= getNumberForLogLevel(level);
};
// src/repro.ts
import { VERSION } from "remotion/version";
var reproWriteInstance = null;
var getReproWriter = () => {
if (!reproWriteInstance) {
throw new Error("reproWriteInstance is not initialized");
}
return reproWriteInstance;
};
var writeInRepro = (level, ...args) => {
if (isReproEnabled()) {
getReproWriter().writeLine(level, ...args);
}
};
var shouldRepro = false;
var isReproEnabled = () => shouldRepro;
// src/truthy.ts
function truthy(value) {
return Boolean(value);
}
// src/logger.ts
var INDENT_TOKEN = chalk.gray("│");
var verboseTag = (str) => {
return isColorSupported() ? chalk.bgBlack(` ${str} `) : `[${str}]`;
};
var Log = {
trace: (options, ...args) => {
writeInRepro("trace", ...args);
if (isEqualOrBelowLogLevel(options.logLevel, "trace")) {
if (args.length === 0) {
return process.stdout.write(`
`);
}
return console.log(...[
options.indent ? INDENT_TOKEN : null,
options.tag ? verboseTag(options.tag) : null
].filter(truthy).concat(args.map((a) => chalk.gray(a))));
}
},
verbose: (options, ...args) => {
writeInRepro("verbose", ...args);
if (isEqualOrBelowLogLevel(options.logLevel, "verbose")) {
if (args.length === 0) {
return process.stdout.write(`
`);
}
return console.log(...[
options.indent ? INDENT_TOKEN : null,
options.tag ? verboseTag(options.tag) : null
].filter(truthy).concat(args.map((a) => chalk.gray(a))));
}
},
info: (options, ...args) => {
writeInRepro("info", ...args);
if (isEqualOrBelowLogLevel(options.logLevel, "info")) {
if (args.length === 0) {
return process.stdout.write(`
`);
}
return console.log(...[options.indent ? INDENT_TOKEN : null].filter(truthy).concat(args ?? []));
}
},
warn: (options, ...args) => {
writeInRepro("warn", ...args);
if (isEqualOrBelowLogLevel(options.logLevel, "warn")) {
if (args.length === 0) {
return process.stdout.write(`
`);
}
return console.warn(...[options.indent ? chalk.yellow(INDENT_TOKEN) : null].filter(truthy).concat(args.map((a) => chalk.yellow(a))));
}
},
error: (options, ...args) => {
writeInRepro("error", ...args);
if (isEqualOrBelowLogLevel(options.logLevel, "error")) {
if (args.length === 0) {
return process.stdout.write(`
`);
}
return console.error(...[
options.indent ? INDENT_TOKEN : null,
options.tag ? verboseTag(options.tag) : null
].filter(truthy).concat(args.map((a) => chalk.red(a))));
}
}
};
// src/print-useful-error-message.ts
var alreadyPrintedCache = [];
var printUsefulErrorMessage = (err, logLevel, indent) => {
const errorStack = err.stack;
if (errorStack && alreadyPrintedCache.includes(errorStack)) {
return;
}
if (errorStack) {
alreadyPrintedCache.push(errorStack);
alreadyPrintedCache = alreadyPrintedCache.slice(-10);
}
if (err.message.includes("Could not play video with")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Get help for this issue at https://remotion.dev/docs/media-playback-error");
}
if (err.message.includes("A delayRender()") && err.message.includes("was called but not cleared after")) {
Log.info({ indent, logLevel });
if (err.message.includes("/proxy")) {
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Get help for this issue at https://remotion.dev/docs/troubleshooting/delay-render-proxy");
}
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Get help for this issue at https://remotion.dev/docs/timeout");
}
if (err.message.includes("Target closed")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Get help for this issue at https://remotion.dev/docs/target-closed");
}
if (err.message.includes("Timed out evaluating")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Get help for this issue at https://remotion.dev/docs/troubleshooting/timed-out-page-function");
}
if (err.message.includes("ENAMETOOLONG")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Get help for this issue at https://remotion.dev/docs/enametoolong");
}
if (err.message.includes("Member must have value less than or equal to 3008")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 This error indicates that you have a AWS account on the free tier or have been limited by your organization. Often times this can be solved by adding a credit card. See also: https://repost.aws/questions/QUKruWYNDYTSmP17jCnIz6IQ/questions/QUKruWYNDYTSmP17jCnIz6IQ/unable-to-set-lambda-memory-over-3008mb");
}
if (err.stack?.includes("TooManyRequestsException: Rate Exceeded.")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 This error indicates that your Lambda concurrency limit is too low. See: https://www.remotion.dev/docs/lambda/troubleshooting/rate-limit");
}
if (err.message.includes("Error creating WebGL context")) {
Log.info({ indent, logLevel });
Log.warn({
indent,
logLevel
}, '\uD83D\uDCA1 You might need to set the OpenGL renderer to "angle-egl", "angle" (or "swangle" if rendering on lambda). Learn why at https://www.remotion.dev/docs/three');
Log.warn({
indent,
logLevel
}, "\uD83D\uDCA1 Check how it's done at https://www.remotion.dev/docs/chromium-flags#--gl");
}
if (err.message.includes("The bucket does not allow ACLs")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Fix for this issue: https://remotion.dev/docs/lambda/troubleshooting/bucket-disallows-acl");
}
if (err.message.includes("Minified React error #306")) {
const componentName = err.message.match(/<\w+>/)?.[0];
Log.info({ indent, logLevel }, [
"\uD83D\uDCA1 This error indicates that the component",
componentName ? `(${componentName})` : null,
"you are trying to render is not imported correctly."
].filter(truthy).join(" "));
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, " Check the root file and ensure that the component is not undefined.");
Log.info({ indent, logLevel }, " Oftentimes, this happens if the component is missing the `export` keyword");
Log.info({ indent, logLevel }, " or if the component was renamed and the import statement not properly adjusted.");
}
if (err.message.includes("GLIBC_")) {
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Remotion requires at least Libc 2.35.");
Log.info({ indent, logLevel }, "\uD83D\uDCA1 Get help for this issue: https://github.com/remotion-dev/remotion/issues/2439");
}
if (err.message.includes("EBADF")) {
Log.info({ indent, logLevel }, "\uD83D\uDCA1 This error might be fixed by changing your Node version:");
Log.info({ indent, logLevel }, " https://github.com/remotion-dev/remotion/issues/2452");
}
if (err.message.includes("routines::unsupported")) {
Log.info({ indent, logLevel }, "\uD83D\uDCA1 This error might happen if using Cloud Run with credentials that have a newline at the end or are otherwise badly encoded.");
Log.info({ indent, logLevel }, " https://github.com/remotion-dev/remotion/issues/3864");
}
if (err.message.includes("Failed to fetch")) {
Log.info({ indent, logLevel }, "\uD83D\uDCA1 On Lambda, one reason this could happen is that Chrome is rejecting an asset to be loaded when it is running low on disk space.");
Log.info({ indent, logLevel }, "Try increasing the disk size of your Lambda function.");
}
if (err.message.includes("Invalid value specified for cpu")) {
Log.info({ indent, logLevel });
Log.info({ indent, logLevel }, "\uD83D\uDCA1 This error indicates that your GCP account does have a limit. Try setting `--maxInstances=5` / `maxInstances: 5` when deploying this service.");
Log.info({
indent,
logLevel
});
}
};
// src/wrap-with-error-handling.ts
var wrapWithErrorHandling = (fn) => {
return async (...args) => {
try {
return await fn(...args);
} catch (err) {
const { indent } = args[0];
const { logLevel } = args[0];
printUsefulErrorMessage(err, logLevel, indent);
throw err;
}
};
};
export {
wrapWithErrorHandling
};