"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.printFact = exports.makeRenderingAndStitchingProgress = exports.getRightLabelWidth = exports.makeBundlingAndCopyProgress = exports.createOverwriteableCliOutput = exports.LABEL_WIDTH = void 0; const renderer_1 = require("@remotion/renderer"); const pure_1 = require("@remotion/renderer/pure"); const studio_server_1 = require("@remotion/studio-server"); const studio_shared_1 = require("@remotion/studio-shared"); const chalk_1 = require("./chalk"); const download_progress_1 = require("./download-progress"); const eta_string_1 = require("./eta-string"); const make_link_1 = require("./hyperlinks/make-link"); const log_1 = require("./log"); const make_progress_bar_1 = require("./make-progress-bar"); const truthy_1 = require("./truthy"); exports.LABEL_WIDTH = 20; const createOverwriteableCliOutput = (options) => { var _a; if (options.quiet) { return { update: () => false, }; } if (options.updatesDontOverwrite) { return { update: (up) => { if (options.indent) { process.stdout.write(up .split('\n') .filter((a) => a.trim()) .map((l) => { return `${renderer_1.RenderInternals.INDENT_TOKEN} ${l}`; }) .join('\n') + '\n'); } else { process.stdout.write(up + '\n'); } return true; }, }; } const diff = new studio_server_1.StudioServerInternals.AnsiDiff(); (_a = options.cancelSignal) === null || _a === void 0 ? void 0 : _a.call(options, () => { process.stdout.write(diff.finish()); }); return { update: (up, newline) => { if (options.indent) { return process.stdout.write(diff.update(up .split('\n') .filter((a) => a.trim()) .map((l) => `${renderer_1.RenderInternals.INDENT_TOKEN} ${l}`) .join('\n') + (newline ? '\n' : ''))); } return process.stdout.write(diff.update(up + (newline ? '\n' : ''))); }, }; }; exports.createOverwriteableCliOutput = createOverwriteableCliOutput; const makeBundlingProgress = ({ bundlingState, }) => { const { doneIn, progress } = bundlingState; return [ `${doneIn ? 'Bundled' : 'Bundling'} code`.padEnd(exports.LABEL_WIDTH, ' '), (0, make_progress_bar_1.makeProgressBar)(progress, false), doneIn === null ? (progress * 100).toFixed(0) + '%' : chalk_1.chalk.gray(`${doneIn}ms`), ] .filter(truthy_1.truthy) .join(' '); }; const makeCopyingProgress = (options) => { // Don't show copy progress lower than 200MB if (options.bytes < 1000 * 1000 * 200) { return null; } return [ 'Copying public dir'.padEnd(exports.LABEL_WIDTH, ' '), options.doneIn ? (0, make_progress_bar_1.makeProgressBar)(1, false) : (0, download_progress_1.getFileSizeDownloadBar)(options.bytes), options.doneIn === null ? null : chalk_1.chalk.gray(`${options.doneIn}ms`), ] .filter(truthy_1.truthy) .join(' '); }; const makeSymlinkProgress = (options) => { if (options.symlinks.length === 0) { return null; } if (options.symlinks.length === 1) { return [ chalk_1.chalk.gray(` Found a symbolic link in the public folder:`), chalk_1.chalk.gray(' ' + options.symlinks[0]), chalk_1.chalk.gray(' The symlink will be forwarded in to the bundle.'), ].join('\n'); } return [ chalk_1.chalk.gray(` Found ${options.symlinks.length} symbolic links in the public folder.`), chalk_1.chalk.gray(' The symlinks will be forwarded in to the bundle.'), ].join('\n'); }; const makeBundlingAndCopyProgress = ({ bundling, copying, symLinks, }) => { return [ makeBundlingProgress({ bundlingState: bundling, }), makeCopyingProgress(copying), makeSymlinkProgress(symLinks), ] .filter(truthy_1.truthy) .join('\n'); }; exports.makeBundlingAndCopyProgress = makeBundlingAndCopyProgress; const makeRenderingProgress = ({ frames, totalFrames, doneIn, timeRemainingInMilliseconds, }) => { const progress = frames / totalFrames; return [ [doneIn ? 'Rendered' : 'Rendering', totalFrames === 1 ? 'still' : 'frames'] .filter(truthy_1.truthy) .join(' ') .padEnd(exports.LABEL_WIDTH, ' '), (0, make_progress_bar_1.makeProgressBar)(progress, false), doneIn === null ? [ `${frames}/${totalFrames}`.padStart((0, exports.getRightLabelWidth)(totalFrames)), timeRemainingInMilliseconds ? chalk_1.chalk.gray(`${(0, eta_string_1.formatEtaString)(timeRemainingInMilliseconds)} remaining`) : null, ] .filter(truthy_1.truthy) .join(' ') : chalk_1.chalk.gray(`${doneIn}ms`), ] .filter(truthy_1.truthy) .join(' '); }; const ARTIFACTS_SHOWN = 5; const makeArtifactProgress = (artifactState) => { const { received } = artifactState; if (received.length === 0) { return null; } const artifacts = received .slice(0, ARTIFACTS_SHOWN) .map((artifact) => { return [ chalk_1.chalk.blue((artifact.alreadyExisted ? '○' : '+').padEnd(exports.LABEL_WIDTH)), chalk_1.chalk.blue((0, make_link_1.makeHyperlink)({ url: 'file://' + artifact.absoluteOutputDestination, fallback: artifact.relativeOutputDestination, text: artifact.relativeOutputDestination, })), chalk_1.chalk.gray(`${(0, studio_shared_1.formatBytes)(artifact.sizeInBytes)}`), ].join(' '); }) .filter(truthy_1.truthy) .join('\n'); const moreSizeCombined = received .slice(ARTIFACTS_SHOWN) .reduce((acc, artifact) => acc + artifact.sizeInBytes, 0); const more = received.length > ARTIFACTS_SHOWN ? chalk_1.chalk.gray(`${' '.repeat(exports.LABEL_WIDTH)} ${received.length - ARTIFACTS_SHOWN} more artifact${received.length - ARTIFACTS_SHOWN === 1 ? '' : 's'} ${(0, studio_shared_1.formatBytes)(moreSizeCombined)}`) : null; return [artifacts, more].filter(truthy_1.truthy).join('\n'); }; const getRightLabelWidth = (totalFrames) => { return `${totalFrames}/${totalFrames}`.length; }; exports.getRightLabelWidth = getRightLabelWidth; const makeLogsProgress = (logs) => { if (logs.length === 0) { return null; } return logs .map((log) => { var _a; return renderer_1.RenderInternals.Log.formatLogs(log.logLevel, { indent: false, // It the log makes it this far, it should be logged // Bypass log level filter logLevel: 'trace', tag: (_a = log.tag) !== null && _a !== void 0 ? _a : undefined, }, [log.previewString]).join(' '); }) .join('\n'); }; const makeStitchingProgress = ({ stitchingProgress, isUsingParallelEncoding, }) => { const { frames, totalFrames, doneIn, stage, codec } = stitchingProgress; const progress = frames / totalFrames; const mediaType = codec === 'gif' ? 'GIF' : pure_1.NoReactAPIs.isAudioCodec(codec) ? 'audio' : 'video'; return [ (stage === 'muxing' && isUsingParallelEncoding ? `${doneIn ? 'Muxed' : 'Muxing'} ${mediaType}` : `${doneIn ? 'Encoded' : 'Encoding'} ${mediaType}`).padEnd(exports.LABEL_WIDTH, ' '), (0, make_progress_bar_1.makeProgressBar)(progress, false), doneIn === null ? `${String(frames).padStart(String(totalFrames).length, ' ')}/${totalFrames}` : chalk_1.chalk.gray(`${doneIn}ms`), ] .filter(truthy_1.truthy) .join(' '); }; const makeRenderingAndStitchingProgress = ({ prog, isUsingParallelEncoding, }) => { var _a, _b; const { rendering, stitching, downloads, bundling, artifactState, logs } = prog; const output = [ rendering ? makeRenderingProgress(rendering) : null, makeLogsProgress(logs), (0, download_progress_1.makeMultiDownloadProgress)(downloads, (_a = rendering === null || rendering === void 0 ? void 0 : rendering.totalFrames) !== null && _a !== void 0 ? _a : 0), stitching === null ? null : makeStitchingProgress({ stitchingProgress: stitching, isUsingParallelEncoding, }), makeArtifactProgress(artifactState), ] .filter(truthy_1.truthy) .join('\n'); const renderProgress = rendering ? rendering.frames / rendering.totalFrames : 0; const stitchingProgress = stitching ? stitching.frames / stitching.totalFrames : 0; const progress = ((_b = bundling === null || bundling === void 0 ? void 0 : bundling.progress) !== null && _b !== void 0 ? _b : 0) * 0.3 + renderProgress * 0.6 + stitchingProgress * 0.1; return { output, progress, message: getGuiProgressSubtitle(prog) }; }; exports.makeRenderingAndStitchingProgress = makeRenderingAndStitchingProgress; const getGuiProgressSubtitle = (progress) => { var _a, _b; // Handle floating point inaccuracies const bundlingProgress = ((_a = progress.bundling) === null || _a === void 0 ? void 0 : _a.progress) || 0; if (bundlingProgress < 0.99999) { return `Bundling ${Math.round(bundlingProgress * 100)}%`; } if (bundlingProgress === 1 && ((_b = progress.bundling) === null || _b === void 0 ? void 0 : _b.doneIn) === null && progress.copyingState.bytes === 0) { return `Bundling ${Math.round(bundlingProgress * 100)}%`; } if (progress.copyingState.doneIn === null) { return `Copying public dir ${studio_server_1.StudioServerInternals.formatBytes(progress.copyingState.bytes)}`; } if (!progress.rendering) { return `Getting composition`; } // Get render estimated time value and extract hours, minutes, and seconds const { timeRemainingInMilliseconds } = progress.rendering; // Create estimated time string by concatenating them with colons const estimatedTimeString = timeRemainingInMilliseconds === null ? null : (0, eta_string_1.formatEtaString)(timeRemainingInMilliseconds); const allRendered = progress.rendering.frames === progress.rendering.totalFrames; if (!allRendered || !progress.stitching || progress.stitching.frames === 0) { const etaString = timeRemainingInMilliseconds && timeRemainingInMilliseconds > 0 ? `, time remaining: ${estimatedTimeString}` : ''; return `Rendered ${progress.rendering.frames}/${progress.rendering.totalFrames}${etaString}`; } return `Encoded ${progress.stitching.frames}/${progress.stitching.totalFrames}`; }; const printFact = (printLevel) => ({ indent, logLevel, left, right, color, link, }) => { const fn = (str) => { if (color === 'gray') { return chalk_1.chalk.gray(str); } if (color === 'blue') { return chalk_1.chalk.blue(str); } if (color === 'blueBright') { return chalk_1.chalk.blueBright(str); } return str; }; if (renderer_1.RenderInternals.isEqualOrBelowLogLevel(logLevel, 'verbose')) { log_1.Log[printLevel]({ indent, logLevel }, fn(`${left} = ${right}`)); return; } let leftPadded = left.padEnd(exports.LABEL_WIDTH, ' '); if (link) { const endPadding = exports.LABEL_WIDTH - left.length; leftPadded = (0, make_link_1.makeHyperlink)({ text: left, fallback: left, url: link, }) + ' '.repeat(endPadding); } log_1.Log[printLevel]({ indent, logLevel }, fn(`${leftPadded} ${right}`)); }; exports.printFact = printFact;