Add .gitignore to exclude all node packages and lock files

This commit is contained in:
Adolfo Reyna
2026-02-23 21:56:04 -05:00
parent faae96c9ed
commit dcc5c6c044
9747 changed files with 1555105 additions and 2 deletions
@@ -0,0 +1,9 @@
import type { AggregateRenderProgress } from '@remotion/studio-shared';
import type { LogLevel } from 'remotion';
export declare const addLogToAggregateProgress: ({ logs, logLogLevel, logLevel, previewString, tag, }: {
logs: AggregateRenderProgress["logs"];
logLogLevel: LogLevel;
logLevel: LogLevel;
previewString: string;
tag: string | null;
}) => void;
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.addLogToAggregateProgress = void 0;
const renderer_1 = require("@remotion/renderer");
const addLogToAggregateProgress = ({ logs, logLogLevel, logLevel, previewString, tag, }) => {
if (renderer_1.RenderInternals.isEqualOrBelowLogLevel(logLevel, logLogLevel)) {
logs.push({ logLevel: logLogLevel, previewString, tag });
if (logs.length > 3) {
logs.shift();
}
}
};
exports.addLogToAggregateProgress = addLogToAggregateProgress;
@@ -0,0 +1,68 @@
import type { AudioCodec, Browser, BrowserExecutable, CancelSignal, ChromeMode, ChromiumOptions, Codec, ColorSpace, Crf, FfmpegOverrideFn, FrameRange, LogLevel, NumberOfGifLoops, PixelFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
import type { HardwareAccelerationOption } from '@remotion/renderer/client';
import type { JobProgressCallback } from '@remotion/studio-server';
import type { _InternalTypes } from 'remotion';
export declare const renderVideoFlow: ({ remotionRoot, fullEntryPoint, indent, logLevel, browserExecutable, browser, chromiumOptions, scale, shouldOutputImageSequence, publicDir, envVariables, puppeteerTimeout, port, height, width, remainingArgs, compositionIdFromUi, entryPointReason, overwrite, quiet, concurrency, frameRange, everyNthFrame, outputLocationFromUI, jpegQuality, onProgress, addCleanupCallback, cancelSignal, crf, uiCodec, uiImageFormat, ffmpegOverride, audioBitrate, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, videoBitrate, encodingMaxRate, encodingBufferSize, numberOfGifLoops, audioCodec, serializedInputPropsWithCustomSchema, disallowParallelEncoding, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, colorSpace, repro, binariesDirectory, forSeamlessAacConcatenation, separateAudioTo, publicPath, metadata, hardwareAcceleration, chromeMode, audioLatencyHint, imageSequencePattern, mediaCacheSizeInBytes, askAIEnabled, experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, }: {
remotionRoot: string;
fullEntryPoint: string;
entryPointReason: string;
browserExecutable: BrowserExecutable;
chromiumOptions: ChromiumOptions;
logLevel: LogLevel;
browser: Browser;
scale: number;
indent: boolean;
shouldOutputImageSequence: boolean;
publicDir: string | null;
serializedInputPropsWithCustomSchema: string;
envVariables: Record<string, string>;
puppeteerTimeout: number;
port: number | null;
height: number | null;
width: number | null;
remainingArgs: (string | number)[];
compositionIdFromUi: string | null;
outputLocationFromUI: string | null;
overwrite: boolean;
quiet: boolean;
concurrency: number | string | null;
frameRange: FrameRange | null;
everyNthFrame: number;
jpegQuality: number | undefined;
onProgress: JobProgressCallback;
addCleanupCallback: (label: string, cb: () => void) => void;
crf: Crf | null;
cancelSignal: CancelSignal | null;
uiCodec: Codec | null;
uiImageFormat: VideoImageFormat | null;
ffmpegOverride: FfmpegOverrideFn;
audioBitrate: string | null;
videoBitrate: string | null;
encodingMaxRate: string | null;
encodingBufferSize: string | null;
muted: boolean;
enforceAudioTrack: boolean;
proResProfile: _InternalTypes["ProResProfile"] | undefined;
x264Preset: X264Preset | null;
pixelFormat: PixelFormat;
numberOfGifLoops: NumberOfGifLoops;
audioCodec: AudioCodec | null;
disallowParallelEncoding: boolean;
offthreadVideoCacheSizeInBytes: number | null;
offthreadVideoThreads: number | null;
colorSpace: ColorSpace | null;
repro: boolean;
binariesDirectory: string | null;
forSeamlessAacConcatenation: boolean;
separateAudioTo: string | null;
publicPath: string | null;
metadata: Record<string, string> | null;
hardwareAcceleration: HardwareAccelerationOption;
chromeMode: ChromeMode;
audioLatencyHint: AudioContextLatencyCategory | null;
imageSequencePattern: string | null;
mediaCacheSizeInBytes: number | null;
askAIEnabled: boolean;
experimentalClientSideRenderingEnabled: boolean;
keyboardShortcutsEnabled: boolean;
}) => Promise<void>;
@@ -0,0 +1,524 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderVideoFlow = void 0;
const renderer_1 = require("@remotion/renderer");
const client_1 = require("@remotion/renderer/client");
const studio_shared_1 = require("@remotion/studio-shared");
const node_fs_1 = __importStar(require("node:fs"));
const node_os_1 = __importDefault(require("node:os"));
const node_path_1 = __importDefault(require("node:path"));
const no_react_1 = require("remotion/no-react");
const browser_download_bar_1 = require("../browser-download-bar");
const chalk_1 = require("../chalk");
const config_1 = require("../config");
const get_cli_options_1 = require("../get-cli-options");
const get_composition_with_dimension_override_1 = require("../get-composition-with-dimension-override");
const get_filename_1 = require("../get-filename");
const make_link_1 = require("../hyperlinks/make-link");
const image_formats_1 = require("../image-formats");
const log_1 = require("../log");
const make_on_download_1 = require("../make-on-download");
const on_artifact_1 = require("../on-artifact");
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 truthy_1 = require("../truthy");
const user_passed_output_location_1 = require("../user-passed-output-location");
const add_log_to_aggregate_progress_1 = require("./add-log-to-aggregate-progress");
const renderVideoFlow = async ({ remotionRoot, fullEntryPoint, indent, logLevel, browserExecutable, browser, chromiumOptions, scale, shouldOutputImageSequence, publicDir, envVariables, puppeteerTimeout, port, height, width, remainingArgs, compositionIdFromUi, entryPointReason, overwrite, quiet, concurrency, frameRange, everyNthFrame, outputLocationFromUI, jpegQuality, onProgress, addCleanupCallback, cancelSignal, crf, uiCodec, uiImageFormat, ffmpegOverride, audioBitrate, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, videoBitrate, encodingMaxRate, encodingBufferSize, numberOfGifLoops, audioCodec, serializedInputPropsWithCustomSchema, disallowParallelEncoding, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, colorSpace, repro, binariesDirectory, forSeamlessAacConcatenation, separateAudioTo, publicPath, metadata, hardwareAcceleration, chromeMode, audioLatencyHint, imageSequencePattern, mediaCacheSizeInBytes, askAIEnabled, experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, }) => {
var _a;
let bundlingProgress = null;
let renderingProgress = null;
let stitchingProgress = null;
let browserState = {
progress: 0,
doneIn: 0,
alreadyAvailable: true,
};
let copyingState = {
bytes: 0,
doneIn: null,
};
const logsProgress = [];
let artifactState = { received: [] };
const isVerbose = renderer_1.RenderInternals.isEqualOrBelowLogLevel(logLevel, 'verbose');
(0, progress_bar_1.printFact)('verbose')({
indent,
logLevel,
left: 'Entry point',
right: [fullEntryPoint, isVerbose ? `(${entryPointReason})` : null]
.filter(truthy_1.truthy)
.join(' '),
color: 'gray',
});
const downloads = [];
const onBrowserDownload = (0, browser_download_bar_1.defaultBrowserDownloadProgress)({
indent,
onProgress: updateBrowserProgress,
logLevel,
quiet: (0, parsed_cli_1.quietFlagProvided)(),
});
await renderer_1.RenderInternals.internalEnsureBrowser({
browserExecutable,
indent,
logLevel,
onBrowserDownload,
chromeMode,
});
const browserInstance = renderer_1.RenderInternals.internalOpenBrowser({
browser,
browserExecutable,
chromiumOptions,
forceDeviceScaleFactor: scale,
indent,
viewport: null,
logLevel,
onBrowserDownload,
chromeMode,
});
let isUsingParallelEncoding = false;
const updatesDontOverwrite = (0, should_use_non_overlaying_logger_1.shouldUseNonOverlayingLogger)({ logLevel });
const renderProgress = (0, progress_bar_1.createOverwriteableCliOutput)({
quiet,
cancelSignal,
updatesDontOverwrite,
indent,
});
function updateBrowserProgress(progress) {
browserState = progress;
const aggregateRenderProgress = {
browser: browserState,
rendering: renderingProgress,
stitching: shouldOutputImageSequence ? null : stitchingProgress,
downloads,
bundling: bundlingProgress,
copyingState,
artifactState,
logs: logsProgress,
};
onProgress({
message: `Downloading ${chromeMode === 'chrome-for-testing' ? 'Chrome for Testing' : 'Headless Shell'} ${Math.round(progress.progress * 100)}%`,
value: 0,
...aggregateRenderProgress,
});
}
const updateRenderProgress = ({ newline, printToConsole, }) => {
const aggregateRenderProgress = {
rendering: renderingProgress,
stitching: shouldOutputImageSequence ? null : stitchingProgress,
downloads,
browser: browserState,
bundling: bundlingProgress,
copyingState,
artifactState,
logs: logsProgress,
};
const { output, message, progress } = (0, progress_bar_1.makeRenderingAndStitchingProgress)({
prog: aggregateRenderProgress,
isUsingParallelEncoding,
});
onProgress({ message, value: progress, ...aggregateRenderProgress });
if (printToConsole) {
renderProgress.update(updatesDontOverwrite ? message : output, newline);
}
};
const { urlOrBundle, cleanup: cleanupBundle } = await (0, setup_cache_1.bundleOnCliOrTakeServeUrl)({
fullPath: fullEntryPoint,
remotionRoot,
publicDir,
onProgress: ({ bundling, copying }) => {
bundlingProgress = bundling;
copyingState = copying;
updateRenderProgress({ newline: false, printToConsole: true });
},
indentOutput: indent,
logLevel,
onDirectoryCreated: (dir) => {
addCleanupCallback(`Delete ${dir}`, () => renderer_1.RenderInternals.deleteDirectory(dir));
},
quietProgress: updatesDontOverwrite,
quietFlag: (0, parsed_cli_1.quietFlagProvided)(),
outDir: null,
// Not needed for render
gitSource: null,
bufferStateDelayInMilliseconds: null,
maxTimelineTracks: null,
publicPath,
audioLatencyHint,
experimentalClientSideRenderingEnabled,
askAIEnabled,
keyboardShortcutsEnabled,
});
addCleanupCallback(`Cleanup bundle`, () => cleanupBundle());
const onDownload = (0, make_on_download_1.makeOnDownload)({
downloads,
indent,
logLevel,
updateRenderProgress,
updatesDontOverwrite,
isUsingParallelEncoding,
});
const puppeteerInstance = await browserInstance;
addCleanupCallback(`Closing browser instance`, () => puppeteerInstance.close({ silent: false }));
const resolvedConcurrency = renderer_1.RenderInternals.resolveConcurrency(concurrency);
const server = await renderer_1.RenderInternals.prepareServer({
offthreadVideoThreads: offthreadVideoThreads !== null && offthreadVideoThreads !== void 0 ? offthreadVideoThreads : renderer_1.RenderInternals.DEFAULT_RENDER_FRAMES_OFFTHREAD_VIDEO_THREADS,
indent,
port,
remotionRoot,
logLevel,
webpackConfigOrServeUrl: urlOrBundle,
offthreadVideoCacheSizeInBytes,
binariesDirectory,
forceIPv4: false,
});
addCleanupCallback(`Close server`, () => server.closeServer(false));
const { compositionId, config, reason, argsAfterComposition } = await (0, get_composition_with_dimension_override_1.getCompositionWithDimensionOverride)({
height,
width,
args: remainingArgs,
compositionIdFromUi,
browserExecutable,
chromiumOptions,
envVariables,
indent,
serializedInputPropsWithCustomSchema,
port,
puppeteerInstance,
serveUrlOrWebpackUrl: urlOrBundle,
timeoutInMilliseconds: puppeteerTimeout,
logLevel,
server,
offthreadVideoCacheSizeInBytes,
offthreadVideoThreads,
binariesDirectory,
onBrowserDownload,
chromeMode,
mediaCacheSizeInBytes,
});
const { onArtifact } = (0, on_artifact_1.handleOnArtifact)({
artifactState,
onProgress: (progress) => {
artifactState = progress;
updateRenderProgress({
newline: false,
printToConsole: !updatesDontOverwrite,
});
},
compositionId,
});
const { value: codec, source: codecReason } = client_1.BrowserSafeApis.options.videoCodecOption.getValue({
commandLine: parsed_cli_1.parsedCli,
}, {
configFile: (_a = config_1.ConfigInternals.getOutputCodecOrUndefined()) !== null && _a !== void 0 ? _a : null,
downloadName: null,
outName: (0, user_passed_output_location_1.getUserPassedOutputLocation)(argsAfterComposition, outputLocationFromUI),
uiCodec,
compositionCodec: config.defaultCodec,
});
renderer_1.RenderInternals.validateEvenDimensionsWithCodec({
width: config.width,
height: config.height,
codec,
scale,
wantsImageSequence: shouldOutputImageSequence,
indent,
logLevel,
});
const relativeOutputLocation = (0, get_filename_1.getOutputFilename)({
imageSequence: shouldOutputImageSequence,
compositionName: compositionId,
compositionDefaultOutName: config.defaultOutName,
defaultExtension: renderer_1.RenderInternals.getFileExtensionFromCodec(codec, audioCodec),
args: argsAfterComposition,
indent,
fromUi: outputLocationFromUI,
logLevel,
});
(0, progress_bar_1.printFact)('info')({
indent,
logLevel,
left: 'Composition',
right: [compositionId, isVerbose ? `(${reason})` : null]
.filter(truthy_1.truthy)
.join(' '),
color: 'gray',
link: 'https://www.remotion.dev/docs/terminology/composition',
});
(0, progress_bar_1.printFact)('info')({
indent,
logLevel,
left: 'Codec',
link: 'https://www.remotion.dev/docs/encoding',
right: [codec, isVerbose ? `(${codecReason})` : null]
.filter(truthy_1.truthy)
.join(' '),
color: 'gray',
});
(0, progress_bar_1.printFact)('info')({
indent,
logLevel,
left: 'Output',
right: relativeOutputLocation,
color: 'gray',
});
(0, progress_bar_1.printFact)('info')({
indent,
logLevel,
left: 'Concurrency',
link: 'https://www.remotion.dev/docs/terminology/concurrency',
right: `${resolvedConcurrency}x`,
color: 'gray',
});
const absoluteOutputFile = (0, get_cli_options_1.getAndValidateAbsoluteOutputFile)(relativeOutputLocation, overwrite, logLevel);
const absoluteSeparateAudioTo = separateAudioTo === null ? null : node_path_1.default.resolve(separateAudioTo);
const exists = (0, node_fs_1.existsSync)(absoluteOutputFile);
const audioExists = absoluteSeparateAudioTo
? (0, node_fs_1.existsSync)(absoluteSeparateAudioTo)
: false;
const realFrameRange = renderer_1.RenderInternals.getRealFrameRange(config.durationInFrames, frameRange);
const totalFrames = renderer_1.RenderInternals.getFramesToRender(realFrameRange, everyNthFrame);
renderingProgress = {
frames: 0,
totalFrames: totalFrames.length,
doneIn: null,
timeRemainingInMilliseconds: null,
};
const imageFormat = (0, image_formats_1.getVideoImageFormat)({
codec: shouldOutputImageSequence ? undefined : codec,
uiImageFormat,
});
const onLog = ({ logLevel: logLogLevel, previewString, tag }) => {
(0, add_log_to_aggregate_progress_1.addLogToAggregateProgress)({
logs: logsProgress,
logLogLevel,
previewString,
tag,
logLevel,
});
if (!updatesDontOverwrite) {
updateRenderProgress({
newline: false,
printToConsole: !updatesDontOverwrite,
});
}
else {
log_1.Log[logLogLevel]({
indent,
logLevel,
tag,
}, previewString);
}
};
if (shouldOutputImageSequence) {
node_fs_1.default.mkdirSync(absoluteOutputFile, {
recursive: true,
});
if (imageFormat === 'none') {
throw new Error(`Cannot render an image sequence with a codec that renders no images. codec = ${codec}, imageFormat = ${imageFormat}`);
}
const outputDir = shouldOutputImageSequence
? absoluteOutputFile
: await node_fs_1.default.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), 'react-motion-render'));
log_1.Log.verbose({ indent, logLevel }, 'Output dir', outputDir);
await renderer_1.RenderInternals.internalRenderFrames({
imageFormat,
serializedInputPropsWithCustomSchema,
onFrameUpdate: (rendered) => {
renderingProgress.frames = rendered;
updateRenderProgress({ newline: false, printToConsole: true });
},
onStart: ({ parallelEncoding }) => {
isUsingParallelEncoding = parallelEncoding;
},
onDownload,
cancelSignal: cancelSignal !== null && cancelSignal !== void 0 ? cancelSignal : undefined,
outputDir,
webpackBundleOrServeUrl: urlOrBundle,
everyNthFrame,
envVariables,
frameRange,
concurrency: resolvedConcurrency,
puppeteerInstance,
jpegQuality: jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
timeoutInMilliseconds: puppeteerTimeout,
chromiumOptions,
scale,
browserExecutable,
port,
composition: config,
server,
indent,
muted,
onBrowserLog: null,
onFrameBuffer: null,
logLevel,
serializedResolvedPropsWithCustomSchema: no_react_1.NoReactInternals.serializeJSONWithSpecialTypes({
indent: undefined,
staticBase: null,
data: config.props,
}).serializedString,
offthreadVideoCacheSizeInBytes,
offthreadVideoThreads,
parallelEncodingEnabled: isUsingParallelEncoding,
binariesDirectory,
compositionStart: 0,
forSeamlessAacConcatenation,
onBrowserDownload,
onArtifact,
chromeMode,
imageSequencePattern,
mediaCacheSizeInBytes,
onLog,
});
if (!updatesDontOverwrite) {
updateRenderProgress({ newline: true, printToConsole: true });
}
log_1.Log.info({ indent, logLevel }, chalk_1.chalk.blue(`${(exists ? '○' : '+').padEnd(progress_bar_1.LABEL_WIDTH)} ${(0, make_link_1.makeHyperlink)({ url: `file://${absoluteOutputFile}`, text: relativeOutputLocation, fallback: relativeOutputLocation })}`));
return;
}
stitchingProgress = {
doneIn: null,
frames: 0,
stage: 'encoding',
totalFrames: totalFrames.length,
codec,
};
const { slowestFrames } = await renderer_1.RenderInternals.internalRenderMedia({
outputLocation: absoluteOutputFile,
composition: {
...config,
width: width !== null && width !== void 0 ? width : config.width,
height: height !== null && height !== void 0 ? height : config.height,
},
crf: crf !== null && crf !== void 0 ? crf : null,
envVariables,
frameRange,
serializedInputPropsWithCustomSchema,
overwrite,
pixelFormat,
proResProfile,
x264Preset: x264Preset !== null && x264Preset !== void 0 ? x264Preset : null,
jpegQuality: jpegQuality !== null && jpegQuality !== void 0 ? jpegQuality : renderer_1.RenderInternals.DEFAULT_JPEG_QUALITY,
chromiumOptions,
timeoutInMilliseconds: puppeteerTimeout,
scale,
port,
numberOfGifLoops,
everyNthFrame,
logLevel,
muted,
enforceAudioTrack,
browserExecutable,
ffmpegOverride,
concurrency,
serveUrl: urlOrBundle,
codec,
audioBitrate,
videoBitrate,
encodingMaxRate,
encodingBufferSize,
onProgress: (update) => {
stitchingProgress.doneIn =
update.encodedDoneIn;
stitchingProgress.frames =
update.encodedFrames;
stitchingProgress.stage = update.stitchStage;
renderingProgress.doneIn =
update.renderedDoneIn;
renderingProgress.frames =
update.renderedFrames;
renderingProgress.timeRemainingInMilliseconds = update.renderEstimatedTime;
updateRenderProgress({ newline: false, printToConsole: true });
},
puppeteerInstance,
onDownload,
onCtrlCExit: addCleanupCallback,
indent,
server,
cancelSignal: cancelSignal !== null && cancelSignal !== void 0 ? cancelSignal : undefined,
audioCodec,
preferLossless: false,
imageFormat,
disallowParallelEncoding,
onBrowserLog: null,
onStart: () => undefined,
serializedResolvedPropsWithCustomSchema: no_react_1.NoReactInternals.serializeJSONWithSpecialTypes({
data: config.props,
indent: undefined,
staticBase: null,
}).serializedString,
offthreadVideoCacheSizeInBytes,
offthreadVideoThreads,
colorSpace,
repro: repro !== null && repro !== void 0 ? repro : false,
binariesDirectory,
separateAudioTo: absoluteSeparateAudioTo,
forSeamlessAacConcatenation,
compositionStart: 0,
onBrowserDownload,
onArtifact,
metadata: metadata !== null && metadata !== void 0 ? metadata : null,
hardwareAcceleration,
chromeMode,
mediaCacheSizeInBytes,
onLog,
licenseKey: null,
isProduction: null,
});
if (!updatesDontOverwrite) {
updateRenderProgress({ newline: true, printToConsole: true });
}
if (absoluteSeparateAudioTo) {
const relativeAudio = node_path_1.default.relative(process.cwd(), absoluteSeparateAudioTo);
const audioSize = node_fs_1.default.statSync(absoluteSeparateAudioTo).size;
log_1.Log.info({ indent, logLevel }, chalk_1.chalk.blue(`${(audioExists ? '○' : '+').padEnd(progress_bar_1.LABEL_WIDTH, ' ')} ${(0, make_link_1.makeHyperlink)({ url: `file://${absoluteSeparateAudioTo}`, text: relativeAudio, fallback: absoluteSeparateAudioTo })}`), chalk_1.chalk.gray(`${(0, studio_shared_1.formatBytes)(audioSize)}`));
}
const { size } = node_fs_1.default.statSync(absoluteOutputFile);
log_1.Log.info({ indent, logLevel }, chalk_1.chalk.blue(`${(exists ? '○' : '+').padEnd(progress_bar_1.LABEL_WIDTH)} ${(0, make_link_1.makeHyperlink)({ url: `file://${absoluteOutputFile}`, text: relativeOutputLocation, fallback: relativeOutputLocation })}`), chalk_1.chalk.gray(`${(0, studio_shared_1.formatBytes)(size)}`));
log_1.Log.verbose({ indent, logLevel }, `Slowest frames:`);
slowestFrames.forEach(({ frame, time }) => {
log_1.Log.verbose({ indent, logLevel }, ` Frame ${frame} (${time.toFixed(3)}ms)`);
});
for (const line of renderer_1.RenderInternals.perf.getPerf()) {
log_1.Log.verbose({ indent, logLevel }, line);
}
};
exports.renderVideoFlow = renderVideoFlow;
@@ -0,0 +1,40 @@
import type { Browser, BrowserExecutable, CancelSignal, ChromeMode, ChromiumOptions, LogLevel, StillImageFormat } from '@remotion/renderer';
import type { JobProgressCallback } from '@remotion/studio-server';
export declare const renderStillFlow: ({ remotionRoot, fullEntryPoint, entryPointReason, remainingArgs, browser, browserExecutable, chromiumOptions, envVariables, height, serializedInputPropsWithCustomSchema, overwrite, port, publicDir, puppeteerTimeout, jpegQuality, scale, stillFrame, width, compositionIdFromUi, imageFormatFromUi, logLevel, onProgress, indent, addCleanupCallback, cancelSignal, outputLocationFromUi, offthreadVideoCacheSizeInBytes, binariesDirectory, publicPath, chromeMode, offthreadVideoThreads, audioLatencyHint, mediaCacheSizeInBytes, askAIEnabled, experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, }: {
remotionRoot: string;
fullEntryPoint: string;
entryPointReason: string;
remainingArgs: (string | number)[];
serializedInputPropsWithCustomSchema: string;
envVariables: Record<string, string>;
jpegQuality: number;
browser: Browser;
stillFrame: number;
browserExecutable: BrowserExecutable;
chromiumOptions: ChromiumOptions;
scale: number;
overwrite: boolean;
puppeteerTimeout: number;
port: number | null;
publicDir: string | null;
height: number | null;
width: number | null;
compositionIdFromUi: string | null;
imageFormatFromUi: StillImageFormat | null;
logLevel: LogLevel;
onProgress: JobProgressCallback;
indent: boolean;
addCleanupCallback: (label: string, cb: () => void) => void;
cancelSignal: CancelSignal | null;
outputLocationFromUi: string | null;
offthreadVideoCacheSizeInBytes: number | null;
offthreadVideoThreads: number | null;
binariesDirectory: string | null;
publicPath: string | null;
chromeMode: ChromeMode;
audioLatencyHint: AudioContextLatencyCategory | null;
mediaCacheSizeInBytes: number | null;
askAIEnabled: boolean;
experimentalClientSideRenderingEnabled: boolean;
keyboardShortcutsEnabled: boolean;
}) => Promise<void>;
@@ -0,0 +1,294 @@
"use strict";
// Prints to CLI and also reports back to browser
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderStillFlow = void 0;
const renderer_1 = require("@remotion/renderer");
const node_fs_1 = require("node:fs");
const node_path_1 = __importDefault(require("node:path"));
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 determine_image_format_1 = require("../determine-image-format");
const get_cli_options_1 = require("../get-cli-options");
const get_composition_with_dimension_override_1 = require("../get-composition-with-dimension-override");
const make_link_1 = require("../hyperlinks/make-link");
const log_1 = require("../log");
const make_on_download_1 = require("../make-on-download");
const on_artifact_1 = require("../on-artifact");
const parsed_cli_1 = require("../parsed-cli");
const progress_bar_1 = require("../progress-bar");
const progress_types_1 = require("../progress-types");
const setup_cache_1 = require("../setup-cache");
const should_use_non_overlaying_logger_1 = require("../should-use-non-overlaying-logger");
const truthy_1 = require("../truthy");
const user_passed_output_location_1 = require("../user-passed-output-location");
const add_log_to_aggregate_progress_1 = require("./add-log-to-aggregate-progress");
const renderStillFlow = async ({ remotionRoot, fullEntryPoint, entryPointReason, remainingArgs, browser, browserExecutable, chromiumOptions, envVariables, height, serializedInputPropsWithCustomSchema, overwrite, port, publicDir, puppeteerTimeout, jpegQuality, scale, stillFrame, width, compositionIdFromUi, imageFormatFromUi, logLevel, onProgress, indent, addCleanupCallback, cancelSignal, outputLocationFromUi, offthreadVideoCacheSizeInBytes, binariesDirectory, publicPath, chromeMode, offthreadVideoThreads, audioLatencyHint, mediaCacheSizeInBytes, askAIEnabled, experimentalClientSideRenderingEnabled, keyboardShortcutsEnabled, }) => {
var _a, _b;
const isVerbose = renderer_1.RenderInternals.isEqualOrBelowLogLevel(logLevel, 'verbose');
log_1.Log.verbose({ indent, logLevel }, chalk_1.chalk.gray(`Entry point = ${fullEntryPoint} (${entryPointReason})`));
const aggregate = (0, progress_types_1.initialAggregateRenderProgress)();
const updatesDontOverwrite = (0, should_use_non_overlaying_logger_1.shouldUseNonOverlayingLogger)({ logLevel });
const renderProgress = (0, progress_bar_1.createOverwriteableCliOutput)({
quiet: (0, parsed_cli_1.quietFlagProvided)(),
cancelSignal,
updatesDontOverwrite: (0, should_use_non_overlaying_logger_1.shouldUseNonOverlayingLogger)({ logLevel }),
indent,
});
const updateRenderProgress = ({ newline, printToConsole, }) => {
const { output, progress, message } = (0, progress_bar_1.makeRenderingAndStitchingProgress)({
prog: aggregate,
isUsingParallelEncoding: false,
});
if (printToConsole) {
renderProgress.update(updatesDontOverwrite ? message : output, newline);
}
onProgress({ message, value: progress, ...aggregate });
};
function updateBrowserProgress(progress) {
aggregate.browser = progress;
onProgress({
message: `Downloading ${chromeMode === 'chrome-for-testing' ? 'Chrome for Testing' : 'Headless Shell'} ${Math.round(progress.progress * 100)}%`,
value: 0,
...aggregate,
});
}
const onBrowserDownload = (0, browser_download_bar_1.defaultBrowserDownloadProgress)({
quiet: (0, parsed_cli_1.quietFlagProvided)(),
indent,
logLevel,
onProgress: updateBrowserProgress,
});
await renderer_1.RenderInternals.internalEnsureBrowser({
browserExecutable,
indent,
logLevel,
onBrowserDownload,
chromeMode,
});
const browserInstance = renderer_1.RenderInternals.internalOpenBrowser({
browser,
browserExecutable,
chromiumOptions,
forceDeviceScaleFactor: scale,
indent,
viewport: null,
logLevel,
onBrowserDownload,
chromeMode,
});
const { cleanup: cleanupBundle, urlOrBundle } = await (0, setup_cache_1.bundleOnCliOrTakeServeUrl)({
fullPath: fullEntryPoint,
remotionRoot,
publicDir,
onProgress: ({ copying, bundling }) => {
aggregate.bundling = bundling;
aggregate.copyingState = copying;
updateRenderProgress({
newline: false,
printToConsole: true,
});
},
indentOutput: indent,
logLevel,
onDirectoryCreated: (dir) => {
(0, cleanup_before_quit_1.registerCleanupJob)(`Delete ${dir}`, () => {
renderer_1.RenderInternals.deleteDirectory(dir);
});
},
quietProgress: updatesDontOverwrite,
quietFlag: (0, parsed_cli_1.quietFlagProvided)(),
outDir: null,
// Not needed for still
gitSource: null,
bufferStateDelayInMilliseconds: null,
maxTimelineTracks: null,
publicPath,
audioLatencyHint,
experimentalClientSideRenderingEnabled,
askAIEnabled,
keyboardShortcutsEnabled,
});
const server = await renderer_1.RenderInternals.prepareServer({
offthreadVideoThreads: offthreadVideoThreads !== null && offthreadVideoThreads !== void 0 ? offthreadVideoThreads : renderer_1.RenderInternals.DEFAULT_RENDER_FRAMES_OFFTHREAD_VIDEO_THREADS,
indent,
port,
remotionRoot,
logLevel,
webpackConfigOrServeUrl: urlOrBundle,
offthreadVideoCacheSizeInBytes,
binariesDirectory,
forceIPv4: false,
});
addCleanupCallback(`Close server`, () => server.closeServer(false));
addCleanupCallback(`Cleanup bundle`, () => cleanupBundle());
const puppeteerInstance = await browserInstance;
addCleanupCallback(`Close browser`, () => puppeteerInstance.close({ silent: false }));
const { compositionId, config, reason, argsAfterComposition } = await (0, get_composition_with_dimension_override_1.getCompositionWithDimensionOverride)({
height,
width,
args: remainingArgs,
compositionIdFromUi,
browserExecutable,
chromiumOptions,
envVariables,
indent,
serializedInputPropsWithCustomSchema,
port,
puppeteerInstance,
serveUrlOrWebpackUrl: urlOrBundle,
timeoutInMilliseconds: puppeteerTimeout,
logLevel,
server,
offthreadVideoCacheSizeInBytes,
offthreadVideoThreads,
binariesDirectory,
onBrowserDownload,
chromeMode,
mediaCacheSizeInBytes,
});
const { format: imageFormat, source } = (0, determine_image_format_1.determineFinalStillImageFormat)({
cliFlag: (_a = parsed_cli_1.parsedCli['image-format']) !== null && _a !== void 0 ? _a : null,
configImageFormat: (_b = config_1.ConfigInternals.getUserPreferredStillImageFormat()) !== null && _b !== void 0 ? _b : null,
downloadName: null,
outName: (0, user_passed_output_location_1.getUserPassedOutputLocation)(argsAfterComposition, outputLocationFromUi),
isLambda: false,
fromUi: imageFormatFromUi,
});
const relativeOutputLocation = (0, user_passed_output_location_1.getOutputLocation)({
compositionId,
defaultExtension: imageFormat,
args: argsAfterComposition,
type: 'asset',
outputLocationFromUi,
compositionDefaultOutName: config.defaultOutName,
});
const absoluteOutputLocation = (0, get_cli_options_1.getAndValidateAbsoluteOutputFile)(relativeOutputLocation, overwrite, logLevel);
const exists = (0, node_fs_1.existsSync)(absoluteOutputLocation);
(0, node_fs_1.mkdirSync)(node_path_1.default.join(absoluteOutputLocation, '..'), {
recursive: true,
});
(0, progress_bar_1.printFact)('info')({
indent,
left: 'Composition',
link: 'https://remotion.dev/docs/terminology/composition',
logLevel,
right: [compositionId, isVerbose ? `(${reason})` : null]
.filter(truthy_1.truthy)
.join(' '),
color: 'gray',
});
(0, progress_bar_1.printFact)('info')({
indent,
left: 'Format',
logLevel,
right: [imageFormat, isVerbose ? `(${source})` : null]
.filter(truthy_1.truthy)
.join(' '),
color: 'gray',
});
(0, progress_bar_1.printFact)('info')({
indent,
left: 'Output',
logLevel,
right: relativeOutputLocation,
color: 'gray',
});
const renderStart = Date.now();
aggregate.rendering = {
frames: 0,
doneIn: null,
totalFrames: 1,
timeRemainingInMilliseconds: null,
};
updateRenderProgress({
newline: false,
printToConsole: true,
});
const onDownload = (0, make_on_download_1.makeOnDownload)({
downloads: aggregate.downloads,
indent,
logLevel,
updateRenderProgress,
updatesDontOverwrite,
isUsingParallelEncoding: false,
});
const { onArtifact } = (0, on_artifact_1.handleOnArtifact)({
artifactState: aggregate.artifactState,
compositionId,
onProgress: (progress) => {
aggregate.artifactState = progress;
updateRenderProgress({
newline: false,
printToConsole: true,
});
},
});
await renderer_1.RenderInternals.internalRenderStill({
composition: config,
frame: stillFrame,
output: absoluteOutputLocation,
serveUrl: urlOrBundle,
jpegQuality,
envVariables,
imageFormat,
serializedInputPropsWithCustomSchema,
chromiumOptions,
timeoutInMilliseconds: puppeteerTimeout,
scale,
browserExecutable,
overwrite,
onDownload,
port,
puppeteerInstance,
server,
cancelSignal,
indent,
onBrowserLog: null,
logLevel,
serializedResolvedPropsWithCustomSchema: no_react_1.NoReactInternals.serializeJSONWithSpecialTypes({
indent: undefined,
staticBase: null,
data: config.props,
}).serializedString,
offthreadVideoCacheSizeInBytes,
binariesDirectory,
onBrowserDownload,
onArtifact,
chromeMode,
offthreadVideoThreads,
mediaCacheSizeInBytes,
onLog: ({ logLevel: logLogLevel, previewString, tag }) => {
(0, add_log_to_aggregate_progress_1.addLogToAggregateProgress)({
logs: aggregate.logs,
logLogLevel,
previewString,
tag,
logLevel,
});
updateRenderProgress({
newline: false,
printToConsole: true,
});
},
licenseKey: null,
isProduction: null,
});
aggregate.rendering = {
frames: 1,
doneIn: Date.now() - renderStart,
totalFrames: 1,
timeRemainingInMilliseconds: null,
};
updateRenderProgress({
newline: true,
printToConsole: true,
});
log_1.Log.info({ indent, logLevel }, chalk_1.chalk.blue(`${(exists ? '○' : '+').padEnd(progress_bar_1.LABEL_WIDTH)} ${(0, make_link_1.makeHyperlink)({ url: 'file://' + absoluteOutputLocation, text: relativeOutputLocation, fallback: relativeOutputLocation })}`));
};
exports.renderStillFlow = renderStillFlow;