@remotion/cli 4.0.26 → 4.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/benchmark.js +2 -1
  2. package/dist/config/color-space.d.ts +3 -0
  3. package/dist/config/color-space.js +12 -0
  4. package/dist/config/image-format.d.ts +1 -1
  5. package/dist/config/index.d.ts +7 -2
  6. package/dist/config/index.js +3 -0
  7. package/dist/editor/components/Modals.js +1 -1
  8. package/dist/editor/components/NewComposition/RemInput.d.ts +1 -1
  9. package/dist/editor/components/NewComposition/RemInputTypeColor.d.ts +1 -1
  10. package/dist/editor/components/NewComposition/RemTextarea.d.ts +1 -1
  11. package/dist/editor/components/RenderButton.js +2 -1
  12. package/dist/editor/components/RenderModal/OptionExplainer.js +1 -1
  13. package/dist/editor/components/RenderModal/RenderModal.d.ts +2 -1
  14. package/dist/editor/components/RenderModal/RenderModal.js +79 -3
  15. package/dist/editor/components/RenderModal/RenderModalAdvanced.d.ts +1 -1
  16. package/dist/editor/components/RenderModal/RenderModalBasic.js +1 -1
  17. package/dist/editor/components/RenderModal/RenderModalInput.d.ts +3 -1
  18. package/dist/editor/components/RenderModal/RenderModalInput.js +2 -2
  19. package/dist/editor/components/RenderModal/RenderModalPicture.d.ts +3 -1
  20. package/dist/editor/components/RenderModal/RenderModalPicture.js +22 -3
  21. package/dist/editor/components/RenderModal/human-readable-codec.d.ts +1 -1
  22. package/dist/editor/components/RenderModal/out-name-checker.js +6 -1
  23. package/dist/editor/components/RenderQueue/actions.d.ts +20 -2
  24. package/dist/editor/components/RenderQueue/actions.js +28 -2
  25. package/dist/editor/components/SegmentedControl.js +2 -1
  26. package/dist/editor/components/SidebarRenderButton.js +2 -1
  27. package/dist/editor/helpers/render-modal-sections.js +3 -0
  28. package/dist/editor/state/modals.d.ts +2 -1
  29. package/dist/get-cli-options.d.ts +2 -1
  30. package/dist/get-cli-options.js +6 -1
  31. package/dist/index.d.ts +7 -5
  32. package/dist/parse-command-line.d.ts +2 -0
  33. package/dist/parse-command-line.js +3 -0
  34. package/dist/preview-server/dev-middleware/range-parser.d.ts +1 -1
  35. package/dist/preview-server/render-queue/get-default-video-contexts.d.ts +2 -2
  36. package/dist/preview-server/render-queue/get-default-video-contexts.js +2 -2
  37. package/dist/preview-server/render-queue/job.d.ts +22 -1
  38. package/dist/preview-server/render-queue/make-retry-payload.js +52 -6
  39. package/dist/preview-server/render-queue/process-video.js +16 -15
  40. package/dist/preview-server/render-queue/queue.js +8 -1
  41. package/dist/preview-server/routes/add-render.js +30 -0
  42. package/dist/preview-server/routes.js +2 -0
  43. package/dist/render-flows/render.d.ts +3 -2
  44. package/dist/render-flows/render.js +2 -1
  45. package/dist/render.js +2 -1
  46. package/package.json +8 -8
package/dist/benchmark.js CHANGED
@@ -95,7 +95,7 @@ const benchmarkCommand = async (remotionRoot, args) => {
95
95
  process.exit(1);
96
96
  }
97
97
  const fullEntryPoint = (0, convert_entry_point_to_serve_url_1.convertEntryPointToServeUrl)(file);
98
- const { inputProps, envVariables, browserExecutable, chromiumOptions, port, puppeteerTimeout, browser, scale, publicDir, proResProfile, x264Preset, frameRange: defaultFrameRange, overwrite, jpegQuality, crf: configFileCrf, pixelFormat, scale: configFileScale, numberOfGifLoops, everyNthFrame, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, height, width, concurrency: unparsedConcurrency, logLevel, offthreadVideoCacheSizeInBytes, } = await (0, get_cli_options_1.getCliOptions)({
98
+ const { inputProps, envVariables, browserExecutable, chromiumOptions, port, puppeteerTimeout, browser, scale, publicDir, proResProfile, x264Preset, frameRange: defaultFrameRange, overwrite, jpegQuality, crf: configFileCrf, pixelFormat, scale: configFileScale, numberOfGifLoops, everyNthFrame, muted, enforceAudioTrack, ffmpegOverride, audioBitrate, videoBitrate, height, width, concurrency: unparsedConcurrency, logLevel, offthreadVideoCacheSizeInBytes, colorSpace, } = await (0, get_cli_options_1.getCliOptions)({
99
99
  isLambda: false,
100
100
  type: 'series',
101
101
  remotionRoot,
@@ -237,6 +237,7 @@ const benchmarkCommand = async (remotionRoot, args) => {
237
237
  staticBase: null,
238
238
  }).serializedString,
239
239
  offthreadVideoCacheSizeInBytes,
240
+ colorSpace,
240
241
  }, (run, progress) => {
241
242
  benchmarkProgress.update(makeBenchmarkProgressBar({
242
243
  totalRuns: runs,
@@ -0,0 +1,3 @@
1
+ import type { ColorSpace } from '@remotion/renderer';
2
+ export declare const getColorSpace: () => ColorSpace;
3
+ export declare const setColorSpace: (size: ColorSpace) => void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setColorSpace = exports.getColorSpace = void 0;
4
+ let colorSpace = 'default';
5
+ const getColorSpace = () => {
6
+ return colorSpace;
7
+ };
8
+ exports.getColorSpace = getColorSpace;
9
+ const setColorSpace = (size) => {
10
+ colorSpace = size;
11
+ };
12
+ exports.setColorSpace = setColorSpace;
@@ -2,4 +2,4 @@ import type { StillImageFormat, VideoImageFormat } from '@remotion/renderer';
2
2
  export declare const setStillImageFormat: (format: StillImageFormat) => void;
3
3
  export declare const setVideoImageFormat: (format: VideoImageFormat) => void;
4
4
  export declare const getUserPreferredStillImageFormat: () => "png" | "jpeg" | "pdf" | "webp" | undefined;
5
- export declare const getUserPreferredVideoImageFormat: () => "png" | "jpeg" | "none" | undefined;
5
+ export declare const getUserPreferredVideoImageFormat: () => "none" | "png" | "jpeg" | undefined;
@@ -1,6 +1,6 @@
1
1
  import * as Logging from './log';
2
2
  import type { WebpackConfiguration } from '@remotion/bundler';
3
- import type { BrowserExecutable, CodecOrUndefined, Crf, FrameRange, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
3
+ import type { BrowserExecutable, CodecOrUndefined, ColorSpace, Crf, FrameRange, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
4
4
  import type { Concurrency } from './concurrency';
5
5
  import type { Loop } from './number-of-gif-loops';
6
6
  import type { WebpackOverrideFn } from './override-webpack';
@@ -238,6 +238,10 @@ declare global {
238
238
  * Mutually exclusive with setCrf().
239
239
  */
240
240
  readonly setVideoBitrate: (bitrate: string | null) => void;
241
+ /**
242
+ * Opt into bt709 rendering.
243
+ */
244
+ readonly setColorSpace: (colorSpace: ColorSpace) => void;
241
245
  }
242
246
  }
243
247
  type FlatConfig = RemotionConfigObject & RemotionBundlingOptions & {
@@ -300,7 +304,7 @@ export declare const ConfigInternals: {
300
304
  getShouldOutputImageSequence: (frameRange: FrameRange | null) => boolean;
301
305
  getDotEnvLocation: () => string | null;
302
306
  getUserPreferredStillImageFormat: () => "png" | "jpeg" | "pdf" | "webp" | undefined;
303
- getUserPreferredVideoImageFormat: () => "png" | "jpeg" | "none" | undefined;
307
+ getUserPreferredVideoImageFormat: () => "none" | "png" | "jpeg" | undefined;
304
308
  getWebpackOverrideFn: () => WebpackOverrideFn;
305
309
  getWebpackCaching: () => boolean;
306
310
  getOutputLocation: () => string | null;
@@ -327,4 +331,5 @@ export declare const ConfigInternals: {
327
331
  getShouldOpenBrowser: () => boolean;
328
332
  getChromiumUserAgent: () => string | null;
329
333
  getOffthreadVideoCacheSizeInBytes: () => number | null;
334
+ getColorSpace: () => "default" | "bt709";
330
335
  };
@@ -52,6 +52,7 @@ const bitrate_1 = require("./bitrate");
52
52
  const browser_executable_2 = require("./browser-executable");
53
53
  const chromium_flags_2 = require("./chromium-flags");
54
54
  const codec_2 = require("./codec");
55
+ const color_space_1 = require("./color-space");
55
56
  const concurrency_2 = require("./concurrency");
56
57
  const crf_1 = require("./crf");
57
58
  const enforce_audio_track_1 = require("./enforce-audio-track");
@@ -155,6 +156,7 @@ exports.Config = {
155
156
  overrideFfmpegCommand: ffmpeg_override_1.setFfmpegOverrideFunction,
156
157
  setAudioCodec: audio_codec_1.setAudioCodec,
157
158
  setOffthreadVideoCacheSizeInBytes: offthread_video_cache_size_1.setOffthreadVideoCacheSizeInBytes,
159
+ setColorSpace: color_space_1.setColorSpace,
158
160
  };
159
161
  exports.ConfigInternals = {
160
162
  getRange: frame_range_1.getRange,
@@ -207,4 +209,5 @@ exports.ConfigInternals = {
207
209
  getShouldOpenBrowser: open_browser_1.getShouldOpenBrowser,
208
210
  getChromiumUserAgent: user_agent_1.getChromiumUserAgent,
209
211
  getOffthreadVideoCacheSizeInBytes: offthread_video_cache_size_1.getOffthreadVideoCacheSizeInBytes,
212
+ getColorSpace: color_space_1.getColorSpace,
210
213
  };
@@ -16,7 +16,7 @@ const UpdateModal_1 = require("./UpdateModal/UpdateModal");
16
16
  const Modals = () => {
17
17
  const { selectedModal: modalContextType } = (0, react_1.useContext)(modals_1.ModalsContext);
18
18
  const canRender = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).type === 'connected';
19
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'new-comp' && ((0, jsx_runtime_1.jsx)(NewComposition_1.default, { initialCompType: modalContextType.compType })), modalContextType && canRender && modalContextType.type === 'render' && ((0, jsx_runtime_1.jsx)(RenderModal_1.RenderModalWithLoader, { initialFrame: modalContextType.initialFrame, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialOutName: modalContextType.initialOutName, initialScale: modalContextType.initialScale, initialVerbose: modalContextType.initialVerbose, initialRenderType: modalContextType.initialRenderType, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, initialVideoCodecForAudioTab: modalContextType.initialVideoCodecForAudioTab, initialVideoCodecForVideoTab: modalContextType.initialVideoCodecForVideoTab, initialConcurrency: modalContextType.initialConcurrency, maxConcurrency: modalContextType.maxConcurrency, minConcurrency: modalContextType.minConcurrency, initialStillImageFormat: modalContextType.initialStillImageFormat, initialMuted: modalContextType.initialMuted, initialEnforceAudioTrack: modalContextType.initialEnforceAudioTrack, initialProResProfile: modalContextType.initialProResProfile, initialx264Preset: modalContextType.initialx264Preset, initialPixelFormat: modalContextType.initialPixelFormat, initialAudioBitrate: modalContextType.initialAudioBitrate, initialVideoBitrate: modalContextType.initialVideoBitrate, initialEveryNthFrame: modalContextType.initialEveryNthFrame, initialNumberOfGifLoops: modalContextType.initialNumberOfGifLoops, initialDelayRenderTimeout: modalContextType.initialDelayRenderTimeout, initialAudioCodec: modalContextType.initialAudioCodec, initialEnvVariables: modalContextType.initialEnvVariables, initialDisableWebSecurity: modalContextType.initialDisableWebSecurity, initialGl: modalContextType.initialOpenGlRenderer, initialHeadless: modalContextType.initialHeadless, initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark })), modalContextType &&
19
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'new-comp' && ((0, jsx_runtime_1.jsx)(NewComposition_1.default, { initialCompType: modalContextType.compType })), modalContextType && canRender && modalContextType.type === 'render' && ((0, jsx_runtime_1.jsx)(RenderModal_1.RenderModalWithLoader, { initialFrame: modalContextType.initialFrame, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialOutName: modalContextType.initialOutName, initialScale: modalContextType.initialScale, initialVerbose: modalContextType.initialVerbose, initialRenderType: modalContextType.initialRenderType, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, initialVideoCodecForAudioTab: modalContextType.initialVideoCodecForAudioTab, initialVideoCodecForVideoTab: modalContextType.initialVideoCodecForVideoTab, initialConcurrency: modalContextType.initialConcurrency, maxConcurrency: modalContextType.maxConcurrency, minConcurrency: modalContextType.minConcurrency, initialStillImageFormat: modalContextType.initialStillImageFormat, initialMuted: modalContextType.initialMuted, initialEnforceAudioTrack: modalContextType.initialEnforceAudioTrack, initialProResProfile: modalContextType.initialProResProfile, initialx264Preset: modalContextType.initialx264Preset, initialPixelFormat: modalContextType.initialPixelFormat, initialAudioBitrate: modalContextType.initialAudioBitrate, initialVideoBitrate: modalContextType.initialVideoBitrate, initialEveryNthFrame: modalContextType.initialEveryNthFrame, initialNumberOfGifLoops: modalContextType.initialNumberOfGifLoops, initialDelayRenderTimeout: modalContextType.initialDelayRenderTimeout, initialAudioCodec: modalContextType.initialAudioCodec, initialEnvVariables: modalContextType.initialEnvVariables, initialDisableWebSecurity: modalContextType.initialDisableWebSecurity, initialGl: modalContextType.initialOpenGlRenderer, initialHeadless: modalContextType.initialHeadless, initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark, initialColorSpace: modalContextType.initialColorSpace })), modalContextType &&
20
20
  canRender &&
21
21
  modalContextType.type === 'render-progress' && ((0, jsx_runtime_1.jsx)(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && ((0, jsx_runtime_1.jsx)(UpdateModal_1.UpdateModal, { info: modalContextType.info })), modalContextType && modalContextType.type === 'quick-switcher' && ((0, jsx_runtime_1.jsx)(QuickSwitcher_1.default, { invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode }))] }));
22
22
  };
@@ -13,5 +13,5 @@ export declare const getInputBorderColor: ({ status, isFocused, isHovered, }: {
13
13
  isFocused: boolean;
14
14
  isHovered: boolean;
15
15
  }) => "hsla(0, 0%, 100%, 0.15)" | "rgba(0, 0, 0, 0.6)" | "rgba(255, 255, 255, 0.05)" | "#ff3232" | "#f1c40f";
16
- export declare const RemotionInput: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | "rightAlign" | keyof React.InputHTMLAttributes<HTMLInputElement>> & React.RefAttributes<HTMLInputElement>>;
16
+ export declare const RemotionInput: React.ForwardRefExoticComponent<Pick<Props, "key" | keyof React.InputHTMLAttributes<HTMLInputElement> | "status" | "rightAlign"> & React.RefAttributes<HTMLInputElement>>;
17
17
  export {};
@@ -4,5 +4,5 @@ type Props = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>
4
4
  status: RemInputStatus;
5
5
  name: string;
6
6
  };
7
- export declare const RemInputTypeColor: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | keyof React.InputHTMLAttributes<HTMLInputElement>> & React.RefAttributes<HTMLInputElement>>;
7
+ export declare const RemInputTypeColor: React.ForwardRefExoticComponent<Pick<Props, "key" | keyof React.InputHTMLAttributes<HTMLInputElement> | "status"> & React.RefAttributes<HTMLInputElement>>;
8
8
  export {};
@@ -3,5 +3,5 @@ type Props = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLTextAreaEleme
3
3
  status: 'error' | 'warning' | 'ok';
4
4
  };
5
5
  export declare const inputBaseStyle: React.CSSProperties;
6
- export declare const RemTextarea: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | keyof React.InputHTMLAttributes<HTMLTextAreaElement>> & React.RefAttributes<HTMLTextAreaElement>>;
6
+ export declare const RemTextarea: React.ForwardRefExoticComponent<Pick<Props, "key" | "status" | keyof React.InputHTMLAttributes<HTMLTextAreaElement>> & React.RefAttributes<HTMLTextAreaElement>>;
7
7
  export {};
@@ -55,7 +55,7 @@ const RenderButton = () => {
55
55
  }
56
56
  const { initialAudioCodec, initialRenderType, initialVideoCodec } = (0, get_default_video_contexts_1.getDefaultCodecs)({
57
57
  defaultCodec: defaults.codec,
58
- isStill: !isVideo,
58
+ renderType: isVideo ? 'video' : 'still',
59
59
  });
60
60
  setSelectedModal({
61
61
  type: 'render',
@@ -99,6 +99,7 @@ const RenderButton = () => {
99
99
  defaultProps: (_c = props[video.id]) !== null && _c !== void 0 ? _c : video.defaultProps,
100
100
  inFrameMark: inFrame,
101
101
  outFrameMark: outFrame,
102
+ initialColorSpace: defaults.colorSpace,
102
103
  });
103
104
  }, [video, setSelectedModal, frame, props, inFrame, outFrame]);
104
105
  if (!video) {
@@ -51,6 +51,6 @@ const copyWrapper = {
51
51
  justifyContent: 'flex-end',
52
52
  };
53
53
  const OptionExplainer = ({ option }) => {
54
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "__remotion-info-button-container", children: [(0, jsx_runtime_1.jsxs)("div", { style: padding, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("strong", { style: title, children: option.name }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("a", { style: link, href: option.docLink, target: "_blank", children: "Docs" })] }), (0, jsx_runtime_1.jsx)("div", { style: description, children: option.description('ssr') })] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 0.5, block: true }), (0, jsx_runtime_1.jsx)(MenuDivider_1.MenuDivider, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 0.5, block: true }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: infoRow, children: [(0, jsx_runtime_1.jsx)("div", { style: infoRowLabel, children: "CLI flag" }), (0, jsx_runtime_1.jsx)("div", { style: flexSpacer }), (0, jsx_runtime_1.jsx)("code", { children: option.cliFlag }), (0, jsx_runtime_1.jsx)("div", { style: copyWrapper, children: (0, jsx_runtime_1.jsx)(CliCopyButton_1.CliCopyButton, { valueToCopy: option.cliFlag }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: infoRow, children: [(0, jsx_runtime_1.jsx)("div", { style: infoRowLabel, children: "Node.JS option" }), (0, jsx_runtime_1.jsx)("div", { style: flexSpacer }), (0, jsx_runtime_1.jsx)("code", { children: option.ssrName }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 3.75 })] }), (0, jsx_runtime_1.jsx)("div", { style: infoRow })] })] }));
54
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "__remotion-info-button-container", children: [(0, jsx_runtime_1.jsxs)("div", { style: padding, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("strong", { style: title, children: option.name }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("a", { style: link, href: option.docLink, target: "_blank", children: "Docs" })] }), (0, jsx_runtime_1.jsx)("div", { style: description, children: option.description('ssr') })] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 0.5, block: true }), (0, jsx_runtime_1.jsx)(MenuDivider_1.MenuDivider, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 0.5, block: true }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { style: infoRow, children: [(0, jsx_runtime_1.jsx)("div", { style: infoRowLabel, children: "CLI flag" }), (0, jsx_runtime_1.jsx)("div", { style: flexSpacer }), (0, jsx_runtime_1.jsxs)("code", { children: ["--", option.cliFlag] }), (0, jsx_runtime_1.jsx)("div", { style: copyWrapper, children: (0, jsx_runtime_1.jsx)(CliCopyButton_1.CliCopyButton, { valueToCopy: option.cliFlag }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: infoRow, children: [(0, jsx_runtime_1.jsx)("div", { style: infoRowLabel, children: "Node.JS option" }), (0, jsx_runtime_1.jsx)("div", { style: flexSpacer }), (0, jsx_runtime_1.jsx)("code", { children: option.ssrName }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 3.75 })] }), (0, jsx_runtime_1.jsx)("div", { style: infoRow })] })] }));
55
55
  };
56
56
  exports.OptionExplainer = OptionExplainer;
@@ -1,4 +1,4 @@
1
- import type { AudioCodec, Codec, OpenGlRenderer, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
1
+ import type { AudioCodec, Codec, ColorSpace, OpenGlRenderer, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
2
2
  import React from 'react';
3
3
  import type { RenderType } from './RenderModalAdvanced';
4
4
  type RenderModalProps = {
@@ -33,6 +33,7 @@ type RenderModalProps = {
33
33
  initialIgnoreCertificateErrors: boolean;
34
34
  initialOffthreadVideoCacheSizeInBytes: number | null;
35
35
  initialHeadless: boolean;
36
+ initialColorSpace: ColorSpace;
36
37
  defaultProps: Record<string, unknown>;
37
38
  inFrameMark: number | null;
38
39
  outFrameMark: number | null;
@@ -114,7 +114,7 @@ const outer = {
114
114
  display: 'flex',
115
115
  flexDirection: 'column',
116
116
  };
117
- const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageFormat, initialJpegQuality, initialScale, initialVerbose, initialOutName, initialRenderType, initialVideoCodecForAudioTab, initialVideoCodecForVideoTab, initialConcurrency, maxConcurrency, minConcurrency, initialMuted, initialEnforceAudioTrack, initialProResProfile, initialx264Preset, initialPixelFormat, initialVideoBitrate, initialAudioBitrate, initialEveryNthFrame, initialNumberOfGifLoops, initialDelayRenderTimeout, initialOffthreadVideoCacheSizeInBytes, initialAudioCodec, initialEnvVariables, initialDisableWebSecurity, initialGl, initialHeadless, initialIgnoreCertificateErrors, defaultProps, inFrameMark, outFrameMark, onClose, resolvedComposition, unresolvedComposition, }) => {
117
+ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageFormat, initialJpegQuality, initialScale, initialVerbose, initialOutName, initialRenderType, initialVideoCodecForAudioTab, initialVideoCodecForVideoTab, initialConcurrency, maxConcurrency, minConcurrency, initialMuted, initialEnforceAudioTrack, initialProResProfile, initialx264Preset, initialPixelFormat, initialVideoBitrate, initialAudioBitrate, initialEveryNthFrame, initialNumberOfGifLoops, initialDelayRenderTimeout, initialOffthreadVideoCacheSizeInBytes, initialAudioCodec, initialEnvVariables, initialDisableWebSecurity, initialGl, initialHeadless, initialIgnoreCertificateErrors, defaultProps, inFrameMark, outFrameMark, onClose, resolvedComposition, unresolvedComposition, initialColorSpace, }) => {
118
118
  const isMounted = (0, react_1.useRef)(true);
119
119
  const [state, dispatch] = (0, react_1.useReducer)(reducer, initialState);
120
120
  const [unclampedFrame, setFrame] = (0, react_1.useState)(() => initialFrame);
@@ -137,6 +137,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
137
137
  const [headless, setHeadless] = (0, react_1.useState)(() => initialHeadless);
138
138
  const [ignoreCertificateErrors, setIgnoreCertificateErrors] = (0, react_1.useState)(() => initialIgnoreCertificateErrors);
139
139
  const [openGlOption, setOpenGlOption] = (0, react_1.useState)(() => initialGl !== null && initialGl !== void 0 ? initialGl : 'default');
140
+ const [colorSpace, setColorSpace] = (0, react_1.useState)(() => initialColorSpace);
140
141
  const chromiumOptions = (0, react_1.useMemo)(() => {
141
142
  return {
142
143
  headless,
@@ -259,6 +260,9 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
259
260
  }, [resolvedComposition.durationInFrames, unclampedFrame]);
260
261
  const getStringBeforeSuffix = (0, react_1.useCallback)((fileName) => {
261
262
  const dotPos = fileName.lastIndexOf('.');
263
+ if (dotPos === -1) {
264
+ return fileName;
265
+ }
262
266
  const bitBeforeDot = fileName.substring(0, dotPos);
263
267
  return bitBeforeDot;
264
268
  }, []);
@@ -277,6 +281,12 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
277
281
  return newFileName;
278
282
  });
279
283
  }
284
+ else if (options.type === 'sequence') {
285
+ setOutName((prev) => {
286
+ const folderName = getStringBeforeSuffix(prev);
287
+ return folderName;
288
+ });
289
+ }
280
290
  else {
281
291
  setOutName((prev) => {
282
292
  const codecSuffix = client_1.BrowserSafeApis.getFileExtensionFromCodec(options.codec, deriveFinalAudioCodec(options.codec, options.audioCodec));
@@ -402,6 +412,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
402
412
  envVariables: (0, convert_env_variables_1.envVariablesArrayToObject)(envVariables),
403
413
  inputProps,
404
414
  offthreadVideoCacheSizeInBytes,
415
+ colorSpace,
405
416
  })
406
417
  .then(() => {
407
418
  dispatchIfMounted({ type: 'succeed' });
@@ -442,6 +453,57 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
442
453
  envVariables,
443
454
  inputProps,
444
455
  offthreadVideoCacheSizeInBytes,
456
+ colorSpace,
457
+ onClose,
458
+ ]);
459
+ const onClickSequence = (0, react_1.useCallback)(() => {
460
+ var _a;
461
+ setSidebarCollapsedState({ left: null, right: 'expanded' });
462
+ (0, OptionsPanel_1.persistSelectedOptionsSidebarPanel)('renders');
463
+ (_a = OptionsPanel_1.optionsSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectRendersPanel();
464
+ dispatchIfMounted({ type: 'start' });
465
+ (0, actions_1.addSequenceRenderJob)({
466
+ compositionId: resolvedComposition.id,
467
+ outName,
468
+ imageFormat: videoImageFormat,
469
+ scale,
470
+ verbose,
471
+ concurrency,
472
+ endFrame,
473
+ jpegQuality,
474
+ startFrame,
475
+ delayRenderTimeout,
476
+ chromiumOptions,
477
+ envVariables: (0, convert_env_variables_1.envVariablesArrayToObject)(envVariables),
478
+ inputProps,
479
+ offthreadVideoCacheSizeInBytes,
480
+ disallowParallelEncoding,
481
+ })
482
+ .then(() => {
483
+ dispatchIfMounted({ type: 'succeed' });
484
+ onClose();
485
+ })
486
+ .catch(() => {
487
+ dispatchIfMounted({ type: 'fail' });
488
+ });
489
+ }, [
490
+ setSidebarCollapsedState,
491
+ dispatchIfMounted,
492
+ resolvedComposition.id,
493
+ outName,
494
+ videoImageFormat,
495
+ scale,
496
+ verbose,
497
+ concurrency,
498
+ endFrame,
499
+ jpegQuality,
500
+ startFrame,
501
+ delayRenderTimeout,
502
+ chromiumOptions,
503
+ envVariables,
504
+ inputProps,
505
+ offthreadVideoCacheSizeInBytes,
506
+ disallowParallelEncoding,
445
507
  onClose,
446
508
  ]);
447
509
  (0, react_1.useEffect)(() => {
@@ -512,6 +574,9 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
512
574
  if (newRenderMode === 'still') {
513
575
  setDefaultOutName({ type: 'still', imageFormat: stillImageFormat });
514
576
  }
577
+ if (newRenderMode === 'sequence') {
578
+ setDefaultOutName({ type: 'sequence' });
579
+ }
515
580
  }, [
516
581
  videoCodecForAudioTab,
517
582
  userSelectedAudioCodec,
@@ -558,6 +623,14 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
558
623
  key: 'audio',
559
624
  selected: renderMode === 'audio',
560
625
  },
626
+ {
627
+ label: 'Image sequence',
628
+ onClick: () => {
629
+ setRenderMode('sequence');
630
+ },
631
+ key: 'sequence',
632
+ selected: renderMode === 'sequence',
633
+ },
561
634
  ];
562
635
  }, [resolvedComposition === null || resolvedComposition === void 0 ? void 0 : resolvedComposition.durationInFrames, renderMode, setRenderMode]);
563
636
  const outnameValidation = (0, out_name_checker_1.validateOutnameGui)({
@@ -577,10 +650,13 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
577
650
  if (renderMode === 'still') {
578
651
  onClickStill();
579
652
  }
653
+ else if (renderMode === 'sequence') {
654
+ onClickSequence();
655
+ }
580
656
  else {
581
657
  onClickVideo();
582
658
  }
583
- }, [onClickStill, onClickVideo, renderDisabled, renderMode]);
659
+ }, [onClickSequence, onClickStill, onClickVideo, renderDisabled, renderMode]);
584
660
  (0, react_1.useEffect)(() => {
585
661
  const enter = registerKeybinding({
586
662
  callback() {
@@ -599,7 +675,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
599
675
  return ((0, jsx_runtime_1.jsxs)("div", { style: outer, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.NewCompHeader, { title: `Render ${resolvedComposition.id}` }), (0, jsx_runtime_1.jsxs)("div", { style: container, children: [(0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }), (0, jsx_runtime_1.jsx)("div", { style: flexer }), (0, jsx_runtime_1.jsxs)(Button_1.Button, { autoFocus: true, onClick: trigger, disabled: renderDisabled, style: {
600
676
  ...buttonStyle,
601
677
  backgroundColor: outnameValidation.valid ? colors_1.BLUE : colors_1.BLUE_DISABLED,
602
- }, children: [state.type === 'idle' ? `Render ${renderMode}` : 'Rendering...', (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftSidebar, children: [shownTabs.includes('general') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'general', onClick: () => setTab('general'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: icon }) }), "General"] })) : null, shownTabs.includes('data') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: icon }) }), "Input Props"] })) : null, shownTabs.includes('picture') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'picture', onClick: () => setTab('picture'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(frame_1.PicIcon, { style: icon }) }), "Picture"] })) : null, shownTabs.includes('audio') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'audio', onClick: () => setTab('audio'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(audio_1.AudioIcon, { style: icon }) }), "Audio"] })) : null, shownTabs.includes('gif') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'gif', onClick: () => setTab('gif'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gif_1.GifIcon, { style: icon }) }), "GIF"] })) : null, shownTabs.includes('advanced') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gear_1.GearIcon, { style: icon }) }), "Other"] })) : null] }), (0, jsx_runtime_1.jsx)("div", { style: optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, jsx_runtime_1.jsx)(RenderModalBasic_1.RenderModalBasic, { codec: codec, resolvedComposition: resolvedComposition, frame: frame, imageFormatOptions: imageFormatOptions, outName: outName, proResProfile: proResProfile, renderMode: renderMode, setVideoCodec: setCodec, setFrame: setFrame, setOutName: setOutName, setProResProfile: setProResProfile, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? ((0, jsx_runtime_1.jsx)(RenderModalPicture_1.RenderModalPicture, { renderMode: renderMode, scale: scale, setScale: setScale, pixelFormat: pixelFormat, setPixelFormat: setPixelFormat, imageFormatOptions: imageFormatOptions, crf: crf, setCrf: setCrf, customTargetVideoBitrate: customTargetVideoBitrate, maxCrf: maxCrf, minCrf: minCrf, jpegQuality: jpegQuality, qualityControlType: qualityControlType, setJpegQuality: setJpegQuality, setCustomTargetVideoBitrateValue: setCustomTargetVideoBitrateValue, setQualityControl: setQualityControl, videoImageFormat: videoImageFormat, stillImageFormat: stillImageFormat, shouldDisplayQualityControlPicker: supportsBothQualityControls })) : tab === 'audio' ? ((0, jsx_runtime_1.jsx)(RenderModalAudio_1.RenderModalAudio, { muted: muted, renderMode: renderMode, setMuted: setMuted, codec: codec, audioCodec: audioCodec, setAudioCodec: setAudioCodec, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrackState: setEnforceAudioTrackState, customTargetAudioBitrate: customTargetAudioBitrate, setCustomTargetAudioBitrateValue: setCustomTargetAudioBitrateValue, setShouldHaveCustomTargetAudioBitrate: setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate: shouldHaveCustomTargetAudioBitrate })) : tab === 'gif' ? ((0, jsx_runtime_1.jsx)(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { inputProps: inputProps, setInputProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props", saving: saving, setSaving: setSaving })) : ((0, jsx_runtime_1.jsx)(RenderModalAdvanced_1.RenderModalAdvanced, { x264Preset: x264Preset, setx264Preset: setx264Preset, concurrency: concurrency, maxConcurrency: maxConcurrency, minConcurrency: minConcurrency, renderMode: renderMode, setConcurrency: setConcurrency, setVerboseLogging: setVerboseLogging, verbose: verbose, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, disallowParallelEncoding: disallowParallelEncoding, setDisallowParallelEncoding: setDisallowParallelEncoding, setDisableWebSecurity: setDisableWebSecurity, setIgnoreCertificateErrors: setIgnoreCertificateErrors, setHeadless: setHeadless, headless: headless, ignoreCertificateErrors: ignoreCertificateErrors, disableWebSecurity: disableWebSecurity, openGlOption: openGlOption, setOpenGlOption: setOpenGlOption, setEnvVariables: setEnvVariables, envVariables: envVariables, offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytes, setOffthreadVideoCacheSizeInBytes: setOffthreadVideoCacheSizeInBytes, codec: codec })) })] })] }));
678
+ }, children: [state.type === 'idle' ? `Render ${renderMode}` : 'Rendering...', (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftSidebar, children: [shownTabs.includes('general') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'general', onClick: () => setTab('general'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: icon }) }), "General"] })) : null, shownTabs.includes('data') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: icon }) }), "Input Props"] })) : null, shownTabs.includes('picture') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'picture', onClick: () => setTab('picture'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(frame_1.PicIcon, { style: icon }) }), "Picture"] })) : null, shownTabs.includes('audio') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'audio', onClick: () => setTab('audio'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(audio_1.AudioIcon, { style: icon }) }), "Audio"] })) : null, shownTabs.includes('gif') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'gif', onClick: () => setTab('gif'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gif_1.GifIcon, { style: icon }) }), "GIF"] })) : null, shownTabs.includes('advanced') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gear_1.GearIcon, { style: icon }) }), "Other"] })) : null] }), (0, jsx_runtime_1.jsx)("div", { style: optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, jsx_runtime_1.jsx)(RenderModalBasic_1.RenderModalBasic, { codec: codec, resolvedComposition: resolvedComposition, frame: frame, imageFormatOptions: imageFormatOptions, outName: outName, proResProfile: proResProfile, renderMode: renderMode, setVideoCodec: setCodec, setFrame: setFrame, setOutName: setOutName, setProResProfile: setProResProfile, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? ((0, jsx_runtime_1.jsx)(RenderModalPicture_1.RenderModalPicture, { renderMode: renderMode, scale: scale, setScale: setScale, pixelFormat: pixelFormat, setPixelFormat: setPixelFormat, imageFormatOptions: imageFormatOptions, crf: crf, setCrf: setCrf, customTargetVideoBitrate: customTargetVideoBitrate, maxCrf: maxCrf, minCrf: minCrf, jpegQuality: jpegQuality, qualityControlType: qualityControlType, setJpegQuality: setJpegQuality, setColorSpace: setColorSpace, colorSpace: colorSpace, setCustomTargetVideoBitrateValue: setCustomTargetVideoBitrateValue, setQualityControl: setQualityControl, videoImageFormat: videoImageFormat, stillImageFormat: stillImageFormat, shouldDisplayQualityControlPicker: supportsBothQualityControls })) : tab === 'audio' ? ((0, jsx_runtime_1.jsx)(RenderModalAudio_1.RenderModalAudio, { muted: muted, renderMode: renderMode, setMuted: setMuted, codec: codec, audioCodec: audioCodec, setAudioCodec: setAudioCodec, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrackState: setEnforceAudioTrackState, customTargetAudioBitrate: customTargetAudioBitrate, setCustomTargetAudioBitrateValue: setCustomTargetAudioBitrateValue, setShouldHaveCustomTargetAudioBitrate: setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate: shouldHaveCustomTargetAudioBitrate })) : tab === 'gif' ? ((0, jsx_runtime_1.jsx)(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { inputProps: inputProps, setInputProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props", saving: saving, setSaving: setSaving })) : ((0, jsx_runtime_1.jsx)(RenderModalAdvanced_1.RenderModalAdvanced, { x264Preset: x264Preset, setx264Preset: setx264Preset, concurrency: concurrency, maxConcurrency: maxConcurrency, minConcurrency: minConcurrency, renderMode: renderMode, setConcurrency: setConcurrency, setVerboseLogging: setVerboseLogging, verbose: verbose, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, disallowParallelEncoding: disallowParallelEncoding, setDisallowParallelEncoding: setDisallowParallelEncoding, setDisableWebSecurity: setDisableWebSecurity, setIgnoreCertificateErrors: setIgnoreCertificateErrors, setHeadless: setHeadless, headless: headless, ignoreCertificateErrors: ignoreCertificateErrors, disableWebSecurity: disableWebSecurity, openGlOption: openGlOption, setOpenGlOption: setOpenGlOption, setEnvVariables: setEnvVariables, envVariables: envVariables, offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytes, setOffthreadVideoCacheSizeInBytes: setOffthreadVideoCacheSizeInBytes, codec: codec })) })] })] }));
603
679
  };
604
680
  const RenderModalWithLoader = (props) => {
605
681
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
@@ -1,7 +1,7 @@
1
1
  import type { Codec, X264Preset } from '@remotion/renderer';
2
2
  import React from 'react';
3
3
  import type { UiOpenGlOptions } from '../../../required-chromium-options';
4
- export type RenderType = 'still' | 'video' | 'audio';
4
+ export type RenderType = 'still' | 'video' | 'audio' | 'sequence';
5
5
  export declare const RenderModalAdvanced: React.FC<{
6
6
  renderMode: RenderType;
7
7
  minConcurrency: number;
@@ -75,6 +75,6 @@ const RenderModalBasic = ({ renderMode, imageFormatOptions, outName, codec, setV
75
75
  const onValueChange = (0, react_1.useCallback)((e) => {
76
76
  setOutName(e.target.value);
77
77
  }, [setOutName]);
78
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [renderMode === 'still' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: true }) })] })) : ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Codec", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(InfoBubble_1.InfoBubble, { title: "Learn more about this option", children: (0, jsx_runtime_1.jsx)(OptionExplainer_1.OptionExplainer, { option: client_1.BrowserSafeApis.options.videoCodecOption }) })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: videoCodecOptions, selectedId: codec, title: "Codec" }) })] })), renderMode === 'still' && resolvedComposition.durationInFrames > 1 ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Frame" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(RemInput_1.RightAlignInput, { children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: frame, onTextChange: onFrameChanged, placeholder: `0-${resolvedComposition.durationInFrames - 1}`, onValueChange: onFrameSetDirectly, name: "frame", step: 1, min: 0, status: "ok", max: resolvedComposition.durationInFrames - 1, rightAlign: true }) }) })] })) : null, renderMode === 'video' && codec === 'prores' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "ProRes profile" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { title: 'proResProfile', selectedId: proResProfile, values: proResProfileOptions }) })] })) : null, renderMode === 'still' ? null : ((0, jsx_runtime_1.jsx)(FrameRangeSetting_1.FrameRangeSetting, { durationInFrames: resolvedComposition.durationInFrames, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame })), (0, jsx_runtime_1.jsx)(RenderModalInput_1.RenderModalInput, { existence: existence, inputStyle: layout_2.input, outName: outName, onValueChange: onValueChange, validationMessage: validationMessage })] }));
78
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [renderMode === 'still' || renderMode === 'sequence' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: true }) })] })) : ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Codec", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(InfoBubble_1.InfoBubble, { title: "Learn more about this option", children: (0, jsx_runtime_1.jsx)(OptionExplainer_1.OptionExplainer, { option: client_1.BrowserSafeApis.options.videoCodecOption }) })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: videoCodecOptions, selectedId: codec, title: "Codec" }) })] })), renderMode === 'still' && resolvedComposition.durationInFrames > 1 ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Frame" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(RemInput_1.RightAlignInput, { children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: frame, onTextChange: onFrameChanged, placeholder: `0-${resolvedComposition.durationInFrames - 1}`, onValueChange: onFrameSetDirectly, name: "frame", step: 1, min: 0, status: "ok", max: resolvedComposition.durationInFrames - 1, rightAlign: true }) }) })] })) : null, renderMode === 'video' && codec === 'prores' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "ProRes profile" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { title: 'proResProfile', selectedId: proResProfile, values: proResProfileOptions }) })] })) : null, renderMode === 'still' ? null : ((0, jsx_runtime_1.jsx)(FrameRangeSetting_1.FrameRangeSetting, { durationInFrames: resolvedComposition.durationInFrames, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame })), (0, jsx_runtime_1.jsx)(RenderModalInput_1.RenderModalInput, { existence: existence, inputStyle: layout_2.input, outName: outName, onValueChange: onValueChange, validationMessage: validationMessage, renderType: renderMode })] }));
79
79
  };
80
80
  exports.RenderModalBasic = RenderModalBasic;
@@ -1,10 +1,12 @@
1
1
  import React from 'react';
2
+ import type { RenderType } from './RenderModalAdvanced';
2
3
  type Props = {
3
4
  existence: boolean;
4
5
  inputStyle: React.CSSProperties;
5
6
  outName: string;
6
7
  onValueChange: React.ChangeEventHandler<HTMLInputElement>;
7
8
  validationMessage: string | null;
9
+ renderType: RenderType;
8
10
  };
9
- export declare function RenderModalInput({ existence, inputStyle, outName, onValueChange, validationMessage, }: Props): JSX.Element;
11
+ export declare function RenderModalInput({ existence, inputStyle, outName, onValueChange, validationMessage, renderType, }: Props): JSX.Element;
10
12
  export {};
@@ -7,7 +7,7 @@ const RemInput_1 = require("../NewComposition/RemInput");
7
7
  const ValidationMessage_1 = require("../NewComposition/ValidationMessage");
8
8
  const layout_2 = require("./layout");
9
9
  // eslint-disable-next-line react/function-component-definition
10
- function RenderModalInput({ existence, inputStyle, outName, onValueChange, validationMessage, }) {
11
- return ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)(layout_1.Column, { children: (0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Output name" }) }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { status: validationMessage ? 'error' : existence ? 'warning' : 'ok', style: inputStyle, type: "text", value: outName, onChange: onValueChange, rightAlign: true }), validationMessage ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: validationMessage, type: 'error' })] })) : existence ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: "Will be overwritten", type: 'warning' })] })) : null] }) })] }));
10
+ function RenderModalInput({ existence, inputStyle, outName, onValueChange, validationMessage, renderType, }) {
11
+ return ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)(layout_1.Column, { children: (0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: renderType === 'sequence' ? 'Folder name' : 'Output name' }) }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { status: validationMessage ? 'error' : existence ? 'warning' : 'ok', style: inputStyle, type: "text", value: outName, onChange: onValueChange, rightAlign: true }), validationMessage ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: validationMessage, type: 'error' })] })) : existence ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: "Will be overwritten", type: 'warning' })] })) : null] }) })] }));
12
12
  }
13
13
  exports.RenderModalInput = RenderModalInput;
@@ -1,4 +1,4 @@
1
- import type { PixelFormat, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
1
+ import type { ColorSpace, PixelFormat, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
2
2
  import React from 'react';
3
3
  import type { SegmentedControlItem } from '../SegmentedControl';
4
4
  import type { RenderType } from './RenderModalAdvanced';
@@ -10,6 +10,8 @@ export declare const RenderModalPicture: React.FC<{
10
10
  setScale: React.Dispatch<React.SetStateAction<number>>;
11
11
  pixelFormat: PixelFormat;
12
12
  setPixelFormat: React.Dispatch<React.SetStateAction<PixelFormat>>;
13
+ colorSpace: ColorSpace;
14
+ setColorSpace: React.Dispatch<React.SetStateAction<ColorSpace>>;
13
15
  imageFormatOptions: SegmentedControlItem[];
14
16
  setQualityControl: React.Dispatch<React.SetStateAction<QualityControl>>;
15
17
  qualityControlType: QualityControl | null;
@@ -5,13 +5,14 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const client_1 = require("@remotion/renderer/client");
6
6
  const react_1 = require("react");
7
7
  const Checkmark_1 = require("../../icons/Checkmark");
8
+ const layout_1 = require("../layout");
8
9
  const ComboBox_1 = require("../NewComposition/ComboBox");
9
10
  const RemInput_1 = require("../NewComposition/RemInput");
10
11
  const SegmentedControl_1 = require("../SegmentedControl");
11
12
  const CrfSetting_1 = require("./CrfSetting");
12
13
  const InfoBubble_1 = require("./InfoBubble");
13
14
  const JpegQualitySetting_1 = require("./JpegQualitySetting");
14
- const layout_1 = require("./layout");
15
+ const layout_2 = require("./layout");
15
16
  const OptionExplainer_1 = require("./OptionExplainer");
16
17
  const RenderModalHr_1 = require("./RenderModalHr");
17
18
  const ScaleSetting_1 = require("./ScaleSetting");
@@ -19,7 +20,7 @@ const qualityControlModes = ['crf', 'bitrate'];
19
20
  const container = {
20
21
  flex: 1,
21
22
  };
22
- const RenderModalPicture = ({ renderMode, scale, setScale, pixelFormat, setPixelFormat, imageFormatOptions, setQualityControl, qualityControlType, videoImageFormat, setJpegQuality, jpegQuality, maxCrf, minCrf, setCrf, shouldDisplayQualityControlPicker, setCustomTargetVideoBitrateValue, crf, customTargetVideoBitrate, stillImageFormat, }) => {
23
+ const RenderModalPicture = ({ renderMode, scale, setScale, pixelFormat, setPixelFormat, imageFormatOptions, setQualityControl, qualityControlType, videoImageFormat, setJpegQuality, jpegQuality, maxCrf, minCrf, setCrf, shouldDisplayQualityControlPicker, setCustomTargetVideoBitrateValue, crf, customTargetVideoBitrate, stillImageFormat, colorSpace, setColorSpace, }) => {
23
24
  const pixelFormatOptions = (0, react_1.useMemo)(() => {
24
25
  return client_1.BrowserSafeApis.validPixelFormats.map((option) => {
25
26
  return {
@@ -36,6 +37,22 @@ const RenderModalPicture = ({ renderMode, scale, setScale, pixelFormat, setPixel
36
37
  };
37
38
  });
38
39
  }, [pixelFormat, setPixelFormat]);
40
+ const colorSpaceOptions = (0, react_1.useMemo)(() => {
41
+ return client_1.BrowserSafeApis.validColorSpaces.map((option) => {
42
+ return {
43
+ label: option,
44
+ onClick: () => setColorSpace(option),
45
+ key: option,
46
+ id: option,
47
+ keyHint: null,
48
+ leftItem: colorSpace === option ? (0, jsx_runtime_1.jsx)(Checkmark_1.Checkmark, {}) : null,
49
+ quickSwitcherLabel: null,
50
+ subMenu: null,
51
+ type: 'item',
52
+ value: option,
53
+ };
54
+ });
55
+ }, [colorSpace, setColorSpace]);
39
56
  const qualityControlOptions = (0, react_1.useMemo)(() => {
40
57
  return qualityControlModes.map((option) => {
41
58
  return {
@@ -49,6 +66,8 @@ const RenderModalPicture = ({ renderMode, scale, setScale, pixelFormat, setPixel
49
66
  const onTargetVideoBitrateChanged = (0, react_1.useCallback)((e) => {
50
67
  setCustomTargetVideoBitrateValue(e.target.value);
51
68
  }, [setCustomTargetVideoBitrateValue]);
52
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Image Format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: false }) })] })) : null, renderMode === 'video' && videoImageFormat === 'jpeg' && ((0, jsx_runtime_1.jsx)(JpegQualitySetting_1.JpegQualitySetting, { jpegQuality: jpegQuality, setJpegQuality: setJpegQuality })), renderMode === 'still' && stillImageFormat === 'jpeg' && ((0, jsx_runtime_1.jsx)(JpegQualitySetting_1.JpegQualitySetting, { jpegQuality: jpegQuality, setJpegQuality: setJpegQuality })), renderMode === 'video' && qualityControlType !== null ? ((0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {})) : null, shouldDisplayQualityControlPicker && renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Quality control" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: qualityControlOptions, needsWrapping: true }) })] })) : null, qualityControlType === 'crf' && renderMode !== 'still' ? ((0, jsx_runtime_1.jsx)(CrfSetting_1.CrfSetting, { crf: crf, min: minCrf, max: maxCrf, setCrf: setCrf, option: client_1.BrowserSafeApis.options.crfOption })) : null, qualityControlType === 'bitrate' && renderMode !== 'still' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_1.label, children: ["Target video bitrate", (0, jsx_runtime_1.jsx)(InfoBubble_1.InfoBubble, { title: "Learn more about this option", children: (0, jsx_runtime_1.jsx)(OptionExplainer_1.OptionExplainer, { option: client_1.BrowserSafeApis.options.videoBitrate }) })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { style: layout_1.input, value: customTargetVideoBitrate, onChange: onTargetVideoBitrateChanged, status: "ok", rightAlign: true }) }) })] })) : null, renderMode === 'video' ? (0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {}) : null, (0, jsx_runtime_1.jsx)(ScaleSetting_1.ScaleSetting, { scale: scale, setScale: setScale }), renderMode === 'video' ? (0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {}) : null, renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Pixel format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: pixelFormatOptions, selectedId: pixelFormat, title: "Pixel Format" }) })] })) : null] }));
69
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Image Format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: false }) })] })) : null, renderMode === 'video' && videoImageFormat === 'jpeg' && ((0, jsx_runtime_1.jsx)(JpegQualitySetting_1.JpegQualitySetting, { jpegQuality: jpegQuality, setJpegQuality: setJpegQuality })), renderMode === 'still' && stillImageFormat === 'jpeg' && ((0, jsx_runtime_1.jsx)(JpegQualitySetting_1.JpegQualitySetting, { jpegQuality: jpegQuality, setJpegQuality: setJpegQuality })), renderMode === 'video' && qualityControlType !== null ? ((0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {})) : null, shouldDisplayQualityControlPicker && renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Quality control" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: qualityControlOptions, needsWrapping: true }) })] })) : null, qualityControlType === 'crf' &&
70
+ renderMode !== 'still' &&
71
+ renderMode !== 'sequence' ? ((0, jsx_runtime_1.jsx)(CrfSetting_1.CrfSetting, { crf: crf, min: minCrf, max: maxCrf, setCrf: setCrf, option: client_1.BrowserSafeApis.options.crfOption })) : null, qualityControlType === 'bitrate' && renderMode !== 'still' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Target video bitrate", (0, jsx_runtime_1.jsx)(InfoBubble_1.InfoBubble, { title: "Learn more about this option", children: (0, jsx_runtime_1.jsx)(OptionExplainer_1.OptionExplainer, { option: client_1.BrowserSafeApis.options.videoBitrate }) })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { style: layout_2.input, value: customTargetVideoBitrate, onChange: onTargetVideoBitrateChanged, status: "ok", rightAlign: true }) }) })] })) : null, renderMode === 'video' ? (0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {}) : null, (0, jsx_runtime_1.jsx)(ScaleSetting_1.ScaleSetting, { scale: scale, setScale: setScale }), renderMode === 'video' ? (0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {}) : null, renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Pixel format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: pixelFormatOptions, selectedId: pixelFormat, title: "Pixel Format" }) })] })) : null, renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Color space", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.25 }), ' ', (0, jsx_runtime_1.jsx)(InfoBubble_1.InfoBubble, { title: "Learn more about this option", children: (0, jsx_runtime_1.jsx)(OptionExplainer_1.OptionExplainer, { option: client_1.BrowserSafeApis.options.colorSpaceOption }) })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: colorSpaceOptions, selectedId: colorSpace, title: "Color Space" }) })] })) : null] }));
53
72
  };
54
73
  exports.RenderModalPicture = RenderModalPicture;
@@ -1,2 +1,2 @@
1
1
  import type { Codec } from '@remotion/renderer';
2
- export declare const humanReadableCodec: (codec: Codec) => "GIF" | "AAC" | "MP3" | "H.264" | "H.264 Matroska" | "H.265" | "ProRes" | "WebM VP8" | "WebM VP9" | "Waveform" | undefined;
2
+ export declare const humanReadableCodec: (codec: Codec) => "AAC" | "MP3" | "GIF" | "H.264" | "H.264 Matroska" | "H.265" | "ProRes" | "WebM VP8" | "WebM VP9" | "Waveform" | undefined;
@@ -53,7 +53,7 @@ const isValidOutName = ({ outName, codec, audioCodec, renderMode, stillImageForm
53
53
  preferLossless: false,
54
54
  });
55
55
  }
56
- if (prefix.length < 1) {
56
+ if (prefix.length < 1 && renderMode !== 'sequence') {
57
57
  throw new Error('The prefix must be at least 1 character long');
58
58
  }
59
59
  if (prefix[0] === '.' || hasDotAfterSlash()) {
@@ -67,4 +67,9 @@ const isValidOutName = ({ outName, codec, audioCodec, renderMode, stillImageForm
67
67
  !isValidStillExtension(extension, stillImageFormat)) {
68
68
  throw new Error(`The extension ${extension} is not supported for still image format ${stillImageFormat}`);
69
69
  }
70
+ if (renderMode === 'sequence') {
71
+ if (outName.includes('.')) {
72
+ throw new Error('Folder names must not contain a dot');
73
+ }
74
+ }
70
75
  };
@@ -1,4 +1,4 @@
1
- import type { AudioCodec, Codec, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
1
+ import type { AudioCodec, Codec, ColorSpace, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
2
2
  import type { RenderJob } from '../../../preview-server/render-queue/job';
3
3
  import type { RequiredChromiumOptions } from '../../../required-chromium-options';
4
4
  import type { EnumPath } from '../RenderModal/SchemaEditor/extract-enum-json-paths';
@@ -16,7 +16,24 @@ export declare const addStillRenderJob: ({ compositionId, outName, imageFormat,
16
16
  inputProps: Record<string, unknown>;
17
17
  offthreadVideoCacheSizeInBytes: number | null;
18
18
  }) => Promise<undefined>;
19
- export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat, jpegQuality, scale, verbose, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, offthreadVideoCacheSizeInBytes, }: {
19
+ export declare const addSequenceRenderJob: ({ compositionId, outName, imageFormat, startFrame, endFrame, scale, verbose, chromiumOptions, delayRenderTimeout, envVariables, inputProps, concurrency, offthreadVideoCacheSizeInBytes, jpegQuality, disallowParallelEncoding, }: {
20
+ compositionId: string;
21
+ outName: string;
22
+ imageFormat: VideoImageFormat;
23
+ jpegQuality: number;
24
+ startFrame: number;
25
+ endFrame: number;
26
+ scale: number;
27
+ verbose: boolean;
28
+ chromiumOptions: RequiredChromiumOptions;
29
+ concurrency: number;
30
+ delayRenderTimeout: number;
31
+ envVariables: Record<string, string>;
32
+ inputProps: Record<string, unknown>;
33
+ offthreadVideoCacheSizeInBytes: number | null;
34
+ disallowParallelEncoding: boolean;
35
+ }) => Promise<undefined>;
36
+ export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat, jpegQuality, scale, verbose, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, offthreadVideoCacheSizeInBytes, colorSpace, }: {
20
37
  compositionId: string;
21
38
  outName: string;
22
39
  imageFormat: VideoImageFormat;
@@ -44,6 +61,7 @@ export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat,
44
61
  envVariables: Record<string, string>;
45
62
  inputProps: Record<string, unknown>;
46
63
  offthreadVideoCacheSizeInBytes: number | null;
64
+ colorSpace: ColorSpace;
47
65
  }) => Promise<undefined>;
48
66
  export declare const unsubscribeFromFileExistenceWatcher: ({ file, clientId, }: {
49
67
  file: string;