Files
clawbot/skills/remotion-prompt-video/node_modules/@remotion/cli/dist/benchmark.js

403 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.benchmarkCommand = void 0;
const renderer_1 = require("@remotion/renderer");
const client_1 = require("@remotion/renderer/client");
const no_react_1 = require("remotion/no-react");
const browser_download_bar_1 = require("./browser-download-bar");
const chalk_1 = require("./chalk");
const cleanup_before_quit_1 = require("./cleanup-before-quit");
const config_1 = require("./config");
const preview_server_1 = require("./config/preview-server");
const convert_entry_point_to_serve_url_1 = require("./convert-entry-point-to-serve-url");
const entry_point_1 = require("./entry-point");
const get_cli_options_1 = require("./get-cli-options");
const image_formats_1 = require("./image-formats");
const log_1 = require("./log");
const make_progress_bar_1 = require("./make-progress-bar");
const parsed_cli_1 = require("./parsed-cli");
const progress_bar_1 = require("./progress-bar");
const setup_cache_1 = require("./setup-cache");
const should_use_non_overlaying_logger_1 = require("./should-use-non-overlaying-logger");
const show_compositions_picker_1 = require("./show-compositions-picker");
const truthy_1 = require("./truthy");
const DEFAULT_RUNS = 3;
const { audioBitrateOption, x264Option, offthreadVideoCacheSizeInBytesOption, scaleOption, crfOption, jpegQualityOption, videoBitrateOption, enforceAudioOption, mutedOption, videoCodecOption, colorSpaceOption, disallowParallelEncodingOption, enableMultiprocessOnLinuxOption, glOption, numberOfGifLoopsOption, encodingMaxRateOption, encodingBufferSizeOption, delayRenderTimeoutInMillisecondsOption, headlessOption, overwriteOption, binariesDirectoryOption, forSeamlessAacConcatenationOption, publicPathOption, publicDirOption, metadataOption, hardwareAccelerationOption, chromeModeOption, offthreadVideoThreadsOption, mediaCacheSizeInBytesOption, darkModeOption, askAIOption, experimentalClientSideRenderingOption, keyboardShortcutsOption, } = client_1.BrowserSafeApis.options;
const getValidConcurrency = (cliConcurrency) => {
const { concurrencies } = parsed_cli_1.parsedCli;
if (!concurrencies) {
return [renderer_1.RenderInternals.resolveConcurrency(cliConcurrency)];
}
return String(concurrencies)
.split(',')
.map((c) => parseInt(c.trim(), 10));
};
const runBenchmark = async (runs, options, onProgress) => {
const timeTaken = [];
for (let run = 0; run < runs; ++run) {
const startTime = performance.now();
await renderer_1.RenderInternals.internalRenderMedia({
onProgress: ({ progress }) => onProgress === null || onProgress === void 0 ? void 0 : onProgress(run, progress),
...options,
});
const endTime = performance.now();
timeTaken.push(endTime - startTime);
}
return timeTaken;
};
const formatTime = (time) => {
let ret = '';
const hours = Math.floor(time / (60 * 60 * 1000));
if (hours) {
ret = `${hours}h`;
}
time %= 60 * 60 * 1000;
const minutes = Math.floor(time / (60 * 1000));
if (minutes) {
ret = `${ret}${minutes}m`;
}
time %= 60 * 1000;
const seconds = (time / 1000).toFixed(5);
if (seconds) {
ret = `${ret}${seconds}s`;
}
return ret;
};
const avg = (time) => time.reduce((prev, curr) => prev + curr) / time.length;
const stdDev = (time) => {
const mean = avg(time);
return Math.sqrt(time.map((x) => (x - mean) ** 2).reduce((a, b) => a + b) / time.length);
};
const getResults = (results, runs) => {
const mean = avg(results);
const dev = stdDev(results);
const max = Math.max(...results);
const min = Math.min(...results);
return ` Time (${chalk_1.chalk.green('mean')} ± ${chalk_1.chalk.green('σ')}): ${chalk_1.chalk.green(formatTime(mean))} ± ${chalk_1.chalk.green(formatTime(dev))}\n Range (${chalk_1.chalk.blue('min')} ... ${chalk_1.chalk.red('max')}): ${chalk_1.chalk.blue(formatTime(min))} ... ${chalk_1.chalk.red(formatTime(max))} \t ${chalk_1.chalk.gray(`${runs} runs`)}
`;
};
const makeBenchmarkProgressBar = ({ totalRuns, run, progress, doneIn, }) => {
const totalProgress = (run + progress) / totalRuns;
return [
`Rendering (${run + 1} out of ${totalRuns} runs)`,
(0, make_progress_bar_1.makeProgressBar)(totalProgress, false),
doneIn === null
? `${(totalProgress * 100).toFixed(2)}% `
: chalk_1.chalk.gray(doneIn),
].join(' ');
};
const benchmarkCommand = async (remotionRoot, args, logLevel) => {
var _a, _b, _c;
const runs = (_a = parsed_cli_1.parsedCli.runs) !== null && _a !== void 0 ? _a : DEFAULT_RUNS;
const { file, reason, remainingArgs } = (0, entry_point_1.findEntryPoint)({
args,
remotionRoot,
logLevel,
allowDirectory: true,
});
if (!file) {
log_1.Log.error({ indent: false, logLevel }, 'No entry file passed.');
log_1.Log.info({ indent: false, logLevel }, 'Pass an additional argument specifying the entry file');
log_1.Log.info({ indent: false, logLevel });
log_1.Log.info({ indent: false, logLevel }, `$ remotion benchmark <entry file>`);
process.exit(1);
}
const fullEntryPoint = (0, convert_entry_point_to_serve_url_1.convertEntryPointToServeUrl)(file);
const { inputProps, envVariables, browserExecutable, proResProfile, frameRange: defaultFrameRange, pixelFormat, everyNthFrame, ffmpegOverride, height, width, concurrency: unparsedConcurrency, disableWebSecurity, userAgent, ignoreCertificateErrors, } = (0, get_cli_options_1.getCliOptions)({
isStill: false,
logLevel,
indent: false,
});
log_1.Log.verbose({ indent: false, logLevel }, 'Entry point:', fullEntryPoint, 'reason:', reason);
const scale = scaleOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const enableMultiProcessOnLinux = enableMultiprocessOnLinuxOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const gl = glOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const headless = headlessOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const publicPath = publicPathOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const publicDir = publicDirOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const chromeMode = chromeModeOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const darkMode = darkModeOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const experimentalClientSideRenderingEnabled = experimentalClientSideRenderingOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const askAIEnabled = askAIOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const keyboardShortcutsEnabled = keyboardShortcutsOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
if (experimentalClientSideRenderingEnabled) {
log_1.Log.warn({ indent: false, logLevel }, 'Enabling WIP client-side rendering. Please see caveats on https://www.remotion.dev/docs/client-side-rendering/.');
}
const chromiumOptions = {
disableWebSecurity,
enableMultiProcessOnLinux,
gl,
headless,
ignoreCertificateErrors,
userAgent,
darkMode,
};
const onBrowserDownload = (0, browser_download_bar_1.defaultBrowserDownloadProgress)({
indent: false,
logLevel,
quiet: (0, parsed_cli_1.quietFlagProvided)(),
onProgress: () => undefined,
});
const indent = false;
await renderer_1.RenderInternals.internalEnsureBrowser({
browserExecutable,
indent,
logLevel,
onBrowserDownload,
chromeMode,
});
const browserInstance = renderer_1.RenderInternals.internalOpenBrowser({
browser: 'chrome',
browserExecutable,
chromiumOptions,
forceDeviceScaleFactor: scale,
indent,
viewport: null,
logLevel,
onBrowserDownload,
chromeMode,
});
const { urlOrBundle: bundleLocation, cleanup: cleanupBundle } = await (0, setup_cache_1.bundleOnCliOrTakeServeUrl)({
fullPath: fullEntryPoint,
publicDir,
remotionRoot,
onProgress: () => undefined,
indentOutput: false,
logLevel,
onDirectoryCreated: (dir) => {
(0, cleanup_before_quit_1.registerCleanupJob)(`Delete ${dir}`, () => renderer_1.RenderInternals.deleteDirectory(dir));
},
quietProgress: false,
quietFlag: (0, parsed_cli_1.quietFlagProvided)(),
outDir: null,
// Not needed for benchmark
gitSource: null,
bufferStateDelayInMilliseconds: null,
maxTimelineTracks: null,
publicPath,
audioLatencyHint: null,
experimentalClientSideRenderingEnabled,
askAIEnabled,
keyboardShortcutsEnabled,
});
(0, cleanup_before_quit_1.registerCleanupJob)(`Deleting bundle`, () => cleanupBundle());
const puppeteerInstance = await browserInstance;
const serializedInputPropsWithCustomSchema = no_react_1.NoReactInternals.serializeJSONWithSpecialTypes({
data: inputProps !== null && inputProps !== void 0 ? inputProps : {},
indent: undefined,
staticBase: null,
}).serializedString;
const comps = await renderer_1.RenderInternals.internalGetCompositions({
serveUrlOrWebpackUrl: bundleLocation,
serializedInputPropsWithCustomSchema,
envVariables,
chromiumOptions,
timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
port: (0, preview_server_1.getRendererPortFromConfigFileAndCliFlag)(),
puppeteerInstance,
browserExecutable,
indent: false,
onBrowserLog: null,
// Intentionally disabling server to not cache results
server: undefined,
logLevel,
offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
offthreadVideoThreads: offthreadVideoThreadsOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
binariesDirectory: binariesDirectoryOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
onBrowserDownload,
chromeMode,
mediaCacheSizeInBytes: mediaCacheSizeInBytesOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
onLog: renderer_1.RenderInternals.defaultOnLog,
});
const ids = (remainingArgs[0]
? String(remainingArgs[0])
.split(',')
.map((c) => c.trim())
.filter(truthy_1.truthy)
: await (0, show_compositions_picker_1.showMultiCompositionsPicker)(comps, logLevel));
const compositions = ids.map((compId) => {
const composition = comps.find((c) => c.id === compId);
if (!composition) {
throw new Error(`No composition with the ID "${compId}" found.`);
}
return composition;
});
if (compositions.length === 0) {
log_1.Log.error({ indent: false, logLevel }, 'No composition IDs passed. Add another argument to the command specifying at least 1 composition ID.');
}
const benchmark = {};
let count = 1;
const x264Preset = x264Option.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const audioBitrate = audioBitrateOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const configFileCrf = crfOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const jpegQuality = jpegQualityOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const videoBitrate = videoBitrateOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const enforceAudioTrack = enforceAudioOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const muted = mutedOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
const disallowParallelEncoding = disallowParallelEncodingOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const numberOfGifLoops = numberOfGifLoopsOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const encodingMaxRate = encodingMaxRateOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const encodingBufferSize = encodingBufferSizeOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const delayRenderInMilliseconds = delayRenderTimeoutInMillisecondsOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value;
const overwrite = overwriteOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}, true).value;
const metadata = metadataOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
for (const composition of compositions) {
const { value: videoCodec, source: codecReason } = videoCodecOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}, {
downloadName: null,
outName: null,
configFile: (_b = config_1.ConfigInternals.getOutputCodecOrUndefined()) !== null && _b !== void 0 ? _b : null,
uiCodec: null,
compositionCodec: (_c = composition.defaultCodec) !== null && _c !== void 0 ? _c : null,
});
const concurrency = getValidConcurrency(unparsedConcurrency);
benchmark[composition.id] = {};
for (const con of concurrency) {
const benchmarkProgress = (0, progress_bar_1.createOverwriteableCliOutput)({
quiet: (0, parsed_cli_1.quietFlagProvided)(),
cancelSignal: null,
updatesDontOverwrite: (0, should_use_non_overlaying_logger_1.shouldUseNonOverlayingLogger)({ logLevel }),
indent: false,
});
log_1.Log.info({ indent: false, logLevel });
log_1.Log.info({ indent: false, logLevel }, `${chalk_1.chalk.bold(`Benchmark #${count++}:`)} ${chalk_1.chalk.gray(`composition=${composition.id} concurrency=${con} codec=${videoCodec} (${codecReason})`)}`);
const timeTaken = await runBenchmark(runs, {
outputLocation: null,
composition: {
...composition,
width: width !== null && width !== void 0 ? width : composition.width,
height: height !== null && height !== void 0 ? height : composition.height,
},
crf: configFileCrf !== null && configFileCrf !== void 0 ? configFileCrf : null,
envVariables,
frameRange: defaultFrameRange,
imageFormat: (0, image_formats_1.getVideoImageFormat)({
codec: videoCodec,
uiImageFormat: null,
}),
serializedInputPropsWithCustomSchema,
overwrite,
pixelFormat,
proResProfile,
x264Preset,
jpegQuality,
chromiumOptions,
timeoutInMilliseconds: delayRenderInMilliseconds,
scale,
port: (0, preview_server_1.getRendererPortFromConfigFileAndCliFlag)(),
numberOfGifLoops,
everyNthFrame,
logLevel,
muted,
enforceAudioTrack,
browserExecutable,
ffmpegOverride,
serveUrl: bundleLocation,
codec: videoCodec,
audioBitrate,
videoBitrate,
encodingMaxRate,
encodingBufferSize,
puppeteerInstance,
concurrency: con,
audioCodec: null,
cancelSignal: undefined,
disallowParallelEncoding,
indent: false,
onBrowserLog: null,
onCtrlCExit: () => undefined,
onDownload: () => undefined,
onStart: () => undefined,
preferLossless: false,
server: undefined,
serializedResolvedPropsWithCustomSchema: no_react_1.NoReactInternals.serializeJSONWithSpecialTypes({
data: composition.props,
indent: undefined,
staticBase: null,
}).serializedString,
offthreadVideoThreads: offthreadVideoThreadsOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
colorSpace: colorSpaceOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
repro: false,
binariesDirectory: binariesDirectoryOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
separateAudioTo: null,
forSeamlessAacConcatenation: forSeamlessAacConcatenationOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
compositionStart: 0,
onBrowserDownload,
onArtifact: () => undefined,
metadata,
hardwareAcceleration: hardwareAccelerationOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
chromeMode,
mediaCacheSizeInBytes: mediaCacheSizeInBytesOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}).value,
onLog: renderer_1.RenderInternals.defaultOnLog,
licenseKey: null,
isProduction: null,
}, (run, progress) => {
benchmarkProgress.update(makeBenchmarkProgressBar({
totalRuns: runs,
run,
doneIn: null,
progress,
}), false);
});
benchmarkProgress.update('', false);
benchmarkProgress.update(getResults(timeTaken, runs), false);
benchmark[composition.id][`${con}`] =
timeTaken;
}
}
log_1.Log.info({ indent: false, logLevel });
};
exports.benchmarkCommand = benchmarkCommand;