| ; | |
| 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 get_crf_for_codec_1 = require("./get-crf-for-codec"); | |
| 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 { audioBitrateOption, x264Option, offthreadVideoCacheSizeInBytesOption, scaleOption, crfOption, gopSizeOption, jpegQualityOption, videoBitrateOption, enforceAudioOption, mutedOption, videoCodecOption, colorSpaceOption, disallowParallelEncodingOption, disableSharedMemoryCaptureOption, enableMultiprocessOnLinuxOption, glOption, numberOfGifLoopsOption, encodingMaxRateOption, encodingBufferSizeOption, delayRenderTimeoutInMillisecondsOption, headlessOption, overwriteOption, binariesDirectoryOption, forSeamlessAacConcatenationOption, publicPathOption, publicDirOption, metadataOption, hardwareAccelerationOption, chromeModeOption, offthreadVideoThreadsOption, mediaCacheSizeInBytesOption, preferredEffectBackendOption, darkModeOption, askAIOption, keyboardShortcutsOption, rspackOption, pixelFormatOption, browserExecutableOption, everyNthFrameOption, proResProfileOption, videoImageFormatOption, userAgentOption, disableWebSecurityOption, ignoreCertificateErrorsOption, concurrencyOption, overrideHeightOption, overrideWidthOption, overrideFpsOption, overrideDurationOption, bundleCacheOption, runsOption, sampleRateOption, } = client_1.BrowserSafeApis.options; | |
| const { benchmarkConcurrenciesOption } = client_1.BrowserSafeApis.options; | |
| const getValidConcurrency = (cliConcurrency) => { | |
| const concurrencies = benchmarkConcurrenciesOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| 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; | |
| const runs = runsOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value; | |
| 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, frameRange: defaultFrameRange, selectedFrames, ffmpegOverride, } = (0, get_cli_options_1.getCliOptions)({ | |
| isStill: false, | |
| logLevel, | |
| indent: false, | |
| }); | |
| if (selectedFrames !== null) { | |
| throw new Error('Comma-separated frame selections are only supported by the `render` command.'); | |
| } | |
| const unparsedConcurrency = concurrencyOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const height = overrideHeightOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const width = overrideWidthOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const fps = overrideFpsOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value; | |
| const durationInFrames = overrideDurationOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const browserExecutable = browserExecutableOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const everyNthFrame = everyNthFrameOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const userAgent = userAgentOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value; | |
| const disableWebSecurity = disableWebSecurityOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const ignoreCertificateErrors = ignoreCertificateErrorsOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| 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 askAIEnabled = askAIOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value; | |
| const keyboardShortcutsEnabled = keyboardShortcutsOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| const rspack = rspackOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value; | |
| const shouldCache = bundleCacheOption.getValue({ | |
| commandLine: parsed_cli_1.parsedCli, | |
| }).value; | |
| 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, | |
| askAIEnabled, | |
| keyboardShortcutsEnabled, | |
| rspack, | |
| shouldCache, | |
| bundlerOverride: null, | |
| rspackOverride: null, | |
| webpackOverride: null, | |
| }); | |
| (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, | |
| preferredEffectBackend: preferredEffectBackendOption.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 crfSetting = crfOption.getValue({ commandLine: parsed_cli_1.parsedCli }); | |
| const gopSize = gopSizeOption.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 disableSharedMemoryCapture = disableSharedMemoryCaptureOption.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; | |
| const sampleRate = sampleRateOption.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: (_a = config_1.ConfigInternals.getOutputCodecOrUndefined()) !== null && _a !== void 0 ? _a : null, | |
| uiCodec: null, | |
| compositionCodec: (_b = composition.defaultCodec) !== null && _b !== void 0 ? _b : null, | |
| }); | |
| const crf = (0, get_crf_for_codec_1.getCrfForCodec)({ | |
| crf: crfSetting.value, | |
| crfIsFromConfigFile: crfSetting.source === 'config', | |
| codec: videoCodec, | |
| indent: false, | |
| logLevel, | |
| }); | |
| 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, | |
| logLevel, | |
| }); | |
| 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, | |
| fps: fps !== null && fps !== void 0 ? fps : composition.fps, | |
| durationInFrames: durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : composition.durationInFrames, | |
| }, | |
| crf, | |
| gopSize, | |
| envVariables, | |
| frameRange: defaultFrameRange, | |
| imageFormat: videoImageFormatOption.getValue({ commandLine: parsed_cli_1.parsedCli }, { | |
| codec: videoCodec, | |
| uiVideoImageFormat: null, | |
| compositionDefaultVideoImageFormat: composition.defaultVideoImageFormat, | |
| }).value, | |
| serializedInputPropsWithCustomSchema, | |
| overwrite, | |
| pixelFormat: pixelFormatOption.getValue({ commandLine: parsed_cli_1.parsedCli }, { | |
| uiPixelFormat: null, | |
| compositionDefaultPixelFormat: composition.defaultPixelFormat, | |
| }).value, | |
| proResProfile: proResProfileOption.getValue({ commandLine: parsed_cli_1.parsedCli }, { | |
| uiProResProfile: undefined, | |
| compositionDefaultProResProfile: composition.defaultProResProfile, | |
| }).value, | |
| x264Preset, | |
| jpegQuality, | |
| chromiumOptions, | |
| timeoutInMilliseconds: delayRenderInMilliseconds, | |
| scale, | |
| port: (0, preview_server_1.getRendererPortFromConfigFileAndCliFlag)(), | |
| numberOfGifLoops, | |
| everyNthFrame, | |
| logLevel, | |
| muted, | |
| sampleRate, | |
| enforceAudioTrack, | |
| browserExecutable, | |
| ffmpegOverride, | |
| serveUrl: bundleLocation, | |
| codec: videoCodec, | |
| audioBitrate, | |
| videoBitrate, | |
| encodingMaxRate, | |
| encodingBufferSize, | |
| puppeteerInstance, | |
| concurrency: con, | |
| audioCodec: null, | |
| cancelSignal: undefined, | |
| disallowParallelEncoding, | |
| disableSharedMemoryCapture, | |
| 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, | |
| preferredEffectBackend: preferredEffectBackendOption.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; | |
Xet Storage Details
- Size:
- 22.1 kB
- Xet hash:
- 302c1dcf0e0586b343c76fe726b4fb88c0939b898073a1914a2d21dd6c3866ef
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.