UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

202 lines (201 loc) 10.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeReadOnlyStudioRenderCommand = exports.normalizeServeUrlForRenderCommand = exports.getNpmRemotionCommandPrefix = void 0; const client_1 = require("@remotion/renderer/client"); const shellQuote = (value) => { return `'${value.replace(/'/g, "'\\''")}'`; }; const addFlagWithValue = (flags, flag, value) => { if (value === null || value === undefined) { return; } flags.push(`--${flag}=${shellQuote(String(value))}`); }; const addBooleanFlag = (flags, flag, value) => { if (value) { flags.push(`--${flag}`); } }; const valueFlag = (flag, value, defaultValue) => { return { flag, value, defaultValue }; }; const booleanFlag = (flag, value, defaultValue) => { return { flag, value, defaultValue }; }; const addValueFlagsIfChanged = (flags, mappings) => { for (const mapping of mappings) { if (mapping.value !== mapping.defaultValue) { addFlagWithValue(flags, mapping.flag, mapping.value); } } }; const addTrueBooleanFlagsIfChanged = (flags, mappings) => { for (const mapping of mappings) { if (mapping.value && mapping.value !== mapping.defaultValue) { addBooleanFlag(flags, mapping.flag, true); } } }; const getNpmRemotionCommandPrefix = (version) => { return version.trim() === '' ? 'bunx --yes --location=global -p @remotion/cli remotion' : `bunx --yes --location=global -p @remotion/cli@${version} remotion`; }; exports.getNpmRemotionCommandPrefix = getNpmRemotionCommandPrefix; const normalizeServeUrlForRenderCommand = ({ locationHref, compositionId, }) => { const parsed = new URL(locationHref); parsed.hash = ''; parsed.search = ''; const suffix = `/${compositionId}`; if (parsed.pathname === suffix) { parsed.pathname = '/'; } else if (parsed.pathname.endsWith(suffix)) { const basePath = parsed.pathname.slice(0, -suffix.length); parsed.pathname = basePath === '' ? '/' : basePath; } if (parsed.pathname !== '/' && parsed.pathname.endsWith('/')) { parsed.pathname = parsed.pathname.slice(0, -1); } return `${parsed.origin}${parsed.pathname === '/' ? '' : parsed.pathname}`; }; exports.normalizeServeUrlForRenderCommand = normalizeServeUrlForRenderCommand; const trimDefaultOutPrefix = (outName) => { if (outName.startsWith('out/')) { const trimmed = outName.slice('out/'.length); return trimmed.length === 0 ? outName : trimmed; } if (outName.startsWith('./out/')) { const trimmed = outName.slice('./out/'.length); return trimmed.length === 0 ? outName : trimmed; } return outName; }; const getRenderMediaFlag = (option) => { return client_1.BrowserSafeApis.optionsMap.renderMedia[option].cliFlag; }; const renderMediaValueFlag = (option, value, defaultValue) => { return valueFlag(getRenderMediaFlag(option), value, defaultValue); }; const renderMediaBooleanFlag = (option, value, defaultValue) => { return booleanFlag(getRenderMediaFlag(option), value, defaultValue); }; const makeReadOnlyStudioRenderCommand = ({ remotionVersion, locationHref, compositionId, outName, renderMode, renderDefaults, durationInFrames, concurrency, frame, startFrame, endFrame, stillImageFormat, sequenceImageFormat, videoImageFormat, jpegQuality, codec, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, crf, videoBitrate, audioBitrate, audioCodec, everyNthFrame, numberOfGifLoops, disallowParallelEncoding, encodingBufferSize, encodingMaxRate, forSeamlessAacConcatenation, separateAudioTo, colorSpace, scale, logLevel, delayRenderTimeout, hardwareAcceleration, chromeMode, headless, disableWebSecurity, ignoreCertificateErrors, gl, userAgent, multiProcessOnLinux, darkMode, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, mediaCacheSizeInBytes, beepOnFinish, repro, metadata, envVariables, inputProps, }) => { var _a; const serveUrl = (0, exports.normalizeServeUrlForRenderCommand)({ locationHref, compositionId, }); const isStillRender = renderMode === 'still'; const isSequenceRender = renderMode === 'sequence'; const hasCodecSpecificOptions = !isSequenceRender; const commandType = isStillRender ? 'still' : 'render'; const command = (0, exports.getNpmRemotionCommandPrefix)(remotionVersion); const { options } = client_1.BrowserSafeApis; const flags = []; addValueFlagsIfChanged(flags, [ valueFlag(options.scaleOption.cliFlag, scale, renderDefaults.scale), renderMediaValueFlag('logLevel', logLevel, renderDefaults.logLevel), renderMediaValueFlag('timeoutInMilliseconds', delayRenderTimeout, renderDefaults.delayRenderTimeout), renderMediaValueFlag('chromeMode', chromeMode, renderDefaults.chromeMode), valueFlag(options.glOption.cliFlag, gl, renderDefaults.openGlRenderer), valueFlag(options.userAgentOption.cliFlag, userAgent, renderDefaults.userAgent), renderMediaValueFlag('offthreadVideoCacheSizeInBytes', offthreadVideoCacheSizeInBytes, renderDefaults.offthreadVideoCacheSizeInBytes), renderMediaValueFlag('offthreadVideoThreads', offthreadVideoThreads, renderDefaults.offthreadVideoThreads), renderMediaValueFlag('mediaCacheSizeInBytes', mediaCacheSizeInBytes, renderDefaults.mediaCacheSizeInBytes), ]); if (headless !== renderDefaults.headless) { addFlagWithValue(flags, options.headlessOption.cliFlag, !headless); } addTrueBooleanFlagsIfChanged(flags, [ booleanFlag(options.disableWebSecurityOption.cliFlag, disableWebSecurity, renderDefaults.disableWebSecurity), booleanFlag(options.ignoreCertificateErrorsOption.cliFlag, ignoreCertificateErrors, renderDefaults.ignoreCertificateErrors), booleanFlag(options.enableMultiprocessOnLinuxOption.cliFlag, multiProcessOnLinux, renderDefaults.multiProcessOnLinux), booleanFlag(options.darkModeOption.cliFlag, darkMode, renderDefaults.darkMode), booleanFlag(options.beepOnFinishOption.cliFlag, beepOnFinish, renderDefaults.beepOnFinish), ]); if (isStillRender) { addValueFlagsIfChanged(flags, [ valueFlag(options.stillFrameOption.cliFlag, frame, 0), valueFlag(options.stillImageFormatOption.cliFlag, stillImageFormat, renderDefaults.stillImageFormat), valueFlag(options.jpegQualityOption.cliFlag, jpegQuality, renderDefaults.jpegQuality), ]); } else { addValueFlagsIfChanged(flags, [ valueFlag(options.concurrencyOption.cliFlag, concurrency, renderDefaults.concurrency), ]); if (isSequenceRender) { addBooleanFlag(flags, options.imageSequenceOption.cliFlag, true); if (sequenceImageFormat !== 'jpeg') { addFlagWithValue(flags, options.videoImageFormatOption.cliFlag, sequenceImageFormat); } } else { addValueFlagsIfChanged(flags, [ valueFlag(options.videoImageFormatOption.cliFlag, videoImageFormat, renderDefaults.videoImageFormat), renderMediaValueFlag('hardwareAcceleration', hardwareAcceleration, renderDefaults.hardwareAcceleration), ]); } if (hasCodecSpecificOptions && codec !== renderDefaults.codec) { addFlagWithValue(flags, getRenderMediaFlag('codec'), codec); } if (startFrame !== 0 || endFrame !== durationInFrames - 1) { addFlagWithValue(flags, options.framesOption.cliFlag, `${startFrame}-${endFrame}`); } if (hasCodecSpecificOptions) { addTrueBooleanFlagsIfChanged(flags, [ renderMediaBooleanFlag('muted', muted, renderDefaults.muted), booleanFlag(options.enforceAudioOption.cliFlag, enforceAudioTrack, renderDefaults.enforceAudioTrack), renderMediaBooleanFlag('forSeamlessAacConcatenation', forSeamlessAacConcatenation, renderDefaults.forSeamlessAacConcatenation), ]); addValueFlagsIfChanged(flags, [ valueFlag(options.pixelFormatOption.cliFlag, pixelFormat, renderDefaults.pixelFormat), renderMediaValueFlag('colorSpace', colorSpace, renderDefaults.colorSpace), valueFlag(options.proResProfileOption.cliFlag, proResProfile, renderDefaults.proResProfile), renderMediaValueFlag('x264Preset', x264Preset, renderDefaults.x264Preset), valueFlag(options.crfOption.cliFlag, crf, null), valueFlag(options.jpegQualityOption.cliFlag, jpegQuality, renderDefaults.jpegQuality), renderMediaValueFlag('videoBitrate', videoBitrate, renderDefaults.videoBitrate), renderMediaValueFlag('audioBitrate', audioBitrate, renderDefaults.audioBitrate), valueFlag(options.everyNthFrameOption.cliFlag, everyNthFrame, renderDefaults.everyNthFrame), renderMediaValueFlag('numberOfGifLoops', numberOfGifLoops, renderDefaults.numberOfGifLoops), renderMediaValueFlag('encodingBufferSize', encodingBufferSize, renderDefaults.encodingBufferSize), renderMediaValueFlag('encodingMaxRate', encodingMaxRate, renderDefaults.encodingMaxRate), renderMediaValueFlag('separateAudioTo', separateAudioTo, null), ]); const defaultAudioCodec = (_a = client_1.BrowserSafeApis.defaultAudioCodecs[codec]) === null || _a === void 0 ? void 0 : _a.compressed; if (audioCodec !== defaultAudioCodec) { addFlagWithValue(flags, getRenderMediaFlag('audioCodec'), audioCodec); } } addTrueBooleanFlagsIfChanged(flags, [ renderMediaBooleanFlag('disallowParallelEncoding', disallowParallelEncoding, false), renderMediaBooleanFlag('repro', repro, renderDefaults.repro), ]); } if (metadata) { for (const [key, value] of Object.entries(metadata)) { addFlagWithValue(flags, options.metadataOption.cliFlag, `${key}=${value}`); } } if (Object.keys(inputProps).length > 0) { addFlagWithValue(flags, options.propsOption.cliFlag, JSON.stringify(inputProps)); } const envArgs = Object.entries(envVariables) .sort(([a], [b]) => a.localeCompare(b)) .map(([key, value]) => shellQuote(`${key}=${value}`)); const renderCommand = [ command, commandType, shellQuote(serveUrl), shellQuote(compositionId), shellQuote(trimDefaultOutPrefix(outName)), ...flags, ].join(' '); if (envArgs.length === 0) { return renderCommand; } return ['env', ...envArgs, renderCommand].join(' '); }; exports.makeReadOnlyStudioRenderCommand = makeReadOnlyStudioRenderCommand;