@remotion/cli 4.0.20 → 4.0.22

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 (62) hide show
  1. package/dist/benchmark.js +2 -1
  2. package/dist/config/index.d.ts +2 -0
  3. package/dist/config/index.js +4 -0
  4. package/dist/config/log.d.ts +1 -1
  5. package/dist/config/presets-profile.d.ts +3 -0
  6. package/dist/config/presets-profile.js +12 -0
  7. package/dist/config/x264-preset.d.ts +3 -0
  8. package/dist/config/x264-preset.js +12 -0
  9. package/dist/editor/components/AssetSelectorItem.js +1 -1
  10. package/dist/editor/components/CompositionSelector.d.ts +3 -0
  11. package/dist/editor/components/CompositionSelector.js +39 -1
  12. package/dist/editor/components/CompositionSelectorItem.js +1 -1
  13. package/dist/editor/components/Editor.js +14 -1
  14. package/dist/editor/components/Modals.js +1 -1
  15. package/dist/editor/components/NewComposition/RemInput.d.ts +2 -2
  16. package/dist/editor/components/NewComposition/RemInputTypeColor.d.ts +1 -1
  17. package/dist/editor/components/QuickSwitcher/QuickSwitcherContent.js +27 -0
  18. package/dist/editor/components/RenderButton.js +1 -0
  19. package/dist/editor/components/RenderModal/RenderModal.d.ts +2 -1
  20. package/dist/editor/components/RenderModal/RenderModal.js +11 -2
  21. package/dist/editor/components/RenderModal/RenderModalAdvanced.d.ts +4 -0
  22. package/dist/editor/components/RenderModal/RenderModalAdvanced.js +21 -2
  23. package/dist/editor/components/RenderModal/RenderModalBasic.js +1 -1
  24. package/dist/editor/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.js +1 -1
  25. package/dist/editor/components/RenderQueue/RenderQueueCopyToClipboard.d.ts +6 -0
  26. package/dist/editor/components/RenderQueue/RenderQueueCopyToClipboard.js +51 -0
  27. package/dist/editor/components/RenderQueue/RenderQueueItem.js +2 -1
  28. package/dist/editor/components/RenderQueue/actions.d.ts +6 -2
  29. package/dist/editor/components/RenderQueue/actions.js +10 -2
  30. package/dist/editor/components/RightPanel.d.ts +8 -0
  31. package/dist/editor/components/RightPanel.js +112 -0
  32. package/dist/editor/components/SidebarRenderButton.js +1 -0
  33. package/dist/editor/helpers/colors.d.ts +1 -1
  34. package/dist/editor/helpers/document-title.js +1 -0
  35. package/dist/editor/helpers/presets-labels.d.ts +2 -0
  36. package/dist/editor/helpers/presets-labels.js +37 -0
  37. package/dist/editor/state/modals.d.ts +2 -1
  38. package/dist/get-cli-options.d.ts +2 -1
  39. package/dist/get-cli-options.js +6 -0
  40. package/dist/index.d.ts +10 -8
  41. package/dist/log.d.ts +4 -4
  42. package/dist/parse-command-line.d.ts +2 -1
  43. package/dist/parse-command-line.js +3 -0
  44. package/dist/preview-server/api-routes.js +2 -0
  45. package/dist/preview-server/api-types.d.ts +2 -1
  46. package/dist/preview-server/error-overlay/react-overlay/listen-to-runtime-errors.js +1 -0
  47. package/dist/preview-server/error-overlay/react-overlay/utils/get-file-source.js +3 -2
  48. package/dist/preview-server/hot-middleware/process-update.d.ts +0 -5
  49. package/dist/preview-server/hot-middleware/process-update.js +21 -2
  50. package/dist/preview-server/render-queue/copy-still-to-clipboard.d.ts +1 -0
  51. package/dist/preview-server/render-queue/copy-still-to-clipboard.js +8 -0
  52. package/dist/preview-server/render-queue/job.d.ts +6 -1
  53. package/dist/preview-server/render-queue/make-retry-payload.js +3 -1
  54. package/dist/preview-server/render-queue/process-video.js +2 -1
  55. package/dist/preview-server/routes/add-render.js +1 -0
  56. package/dist/preview-server/routes/copy-still-to-clipboard-handler.d.ts +3 -0
  57. package/dist/preview-server/routes/copy-still-to-clipboard-handler.js +17 -0
  58. package/dist/preview-server/routes.js +4 -2
  59. package/dist/render-flows/render.d.ts +3 -2
  60. package/dist/render-flows/render.js +2 -1
  61. package/dist/render.js +2 -1
  62. package/package.json +8 -8
@@ -1,4 +1,4 @@
1
- import type { AudioCodec, Codec, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
1
+ import type { AudioCodec, Codec, 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';
@@ -15,7 +15,7 @@ export declare const addStillRenderJob: ({ compositionId, outName, imageFormat,
15
15
  envVariables: Record<string, string>;
16
16
  inputProps: Record<string, unknown>;
17
17
  }) => Promise<undefined>;
18
- export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat, jpegQuality, scale, verbose, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, }: {
18
+ 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, }: {
19
19
  compositionId: string;
20
20
  outName: string;
21
21
  imageFormat: VideoImageFormat;
@@ -30,6 +30,7 @@ export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat,
30
30
  muted: boolean;
31
31
  enforceAudioTrack: boolean;
32
32
  proResProfile: ProResProfile | null;
33
+ x264Preset: X264Preset | null;
33
34
  pixelFormat: PixelFormat;
34
35
  audioBitrate: string | null;
35
36
  videoBitrate: string | null;
@@ -53,6 +54,9 @@ export declare const subscribeToFileExistenceWatcher: ({ file, clientId, }: {
53
54
  export declare const openInFileExplorer: ({ directory }: {
54
55
  directory: string;
55
56
  }) => Promise<void>;
57
+ export declare const copyToClipboard: ({ outName }: {
58
+ outName: string;
59
+ }) => Promise<void>;
56
60
  export declare const removeRenderJob: (job: RenderJob) => Promise<undefined>;
57
61
  export declare const cancelRenderJob: (job: RenderJob) => Promise<import("../../../preview-server/render-queue/job").CancelRenderResponse>;
58
62
  export declare const updateAvailable: (signal: AbortSignal) => Promise<import("../../../preview-server/render-queue/job").UpdateAvailableResponse>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.canUpdateDefaultProps = exports.updateDefaultProps = exports.updateAvailable = exports.cancelRenderJob = exports.removeRenderJob = exports.openInFileExplorer = exports.subscribeToFileExistenceWatcher = exports.unsubscribeFromFileExistenceWatcher = exports.addVideoRenderJob = exports.addStillRenderJob = void 0;
3
+ exports.canUpdateDefaultProps = exports.updateDefaultProps = exports.updateAvailable = exports.cancelRenderJob = exports.removeRenderJob = exports.copyToClipboard = exports.openInFileExplorer = exports.subscribeToFileExistenceWatcher = exports.unsubscribeFromFileExistenceWatcher = exports.addVideoRenderJob = exports.addStillRenderJob = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const callApi = (endpoint, body, signal) => {
6
6
  return new Promise((resolve, reject) => {
@@ -47,7 +47,7 @@ const addStillRenderJob = ({ compositionId, outName, imageFormat, jpegQuality, f
47
47
  });
48
48
  };
49
49
  exports.addStillRenderJob = addStillRenderJob;
50
- const addVideoRenderJob = ({ compositionId, outName, imageFormat, jpegQuality, scale, verbose, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, }) => {
50
+ 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, }) => {
51
51
  return callApi('/api/render', {
52
52
  compositionId,
53
53
  type: 'video',
@@ -64,6 +64,7 @@ const addVideoRenderJob = ({ compositionId, outName, imageFormat, jpegQuality, s
64
64
  muted,
65
65
  enforceAudioTrack,
66
66
  proResProfile,
67
+ x264Preset,
67
68
  pixelFormat,
68
69
  audioBitrate,
69
70
  videoBitrate,
@@ -101,6 +102,13 @@ const openInFileExplorer = ({ directory }) => {
101
102
  return callApi('/api/open-in-file-explorer', body);
102
103
  };
103
104
  exports.openInFileExplorer = openInFileExplorer;
105
+ const copyToClipboard = ({ outName }) => {
106
+ const body = {
107
+ outName,
108
+ };
109
+ return callApi('/api/copy-still-to-clipboard', body);
110
+ };
111
+ exports.copyToClipboard = copyToClipboard;
104
112
  const removeRenderJob = (job) => {
105
113
  return callApi('/api/remove-render', {
106
114
  jobId: job.id,
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ type SidebarPanel = 'input-props' | 'renders';
3
+ export declare const persistSelectedPanel: (panel: SidebarPanel) => void;
4
+ export declare const rightSidebarTabs: React.RefObject<{
5
+ selectRendersPanel: () => void;
6
+ }>;
7
+ export declare const RightPanel: React.FC<{}>;
8
+ export {};
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RightPanel = exports.rightSidebarTabs = exports.persistSelectedPanel = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const remotion_1 = require("remotion");
7
+ const ShortcutHint_1 = require("../../preview-server/error-overlay/remotion-overlay/ShortcutHint");
8
+ const colors_1 = require("../helpers/colors");
9
+ const DataEditor_1 = require("./RenderModal/DataEditor");
10
+ const deep_equal_1 = require("./RenderModal/SchemaEditor/deep-equal");
11
+ const RenderQueue_1 = require("./RenderQueue");
12
+ const RendersTab_1 = require("./RendersTab");
13
+ const Tabs_1 = require("./Tabs");
14
+ const container = {
15
+ height: '100%',
16
+ width: '100%',
17
+ position: 'absolute',
18
+ display: 'flex',
19
+ flexDirection: 'column',
20
+ };
21
+ const circle = {
22
+ width: 8,
23
+ height: 8,
24
+ borderRadius: 4,
25
+ };
26
+ const localStorageKey = 'remotion.sidebarPanel';
27
+ const getSelectedPanel = () => {
28
+ const panel = localStorage.getItem(localStorageKey);
29
+ if (panel === 'renders') {
30
+ return 'renders';
31
+ }
32
+ return 'input-props';
33
+ };
34
+ const tabsContainer = {
35
+ backgroundColor: colors_1.BACKGROUND,
36
+ };
37
+ const persistSelectedPanel = (panel) => {
38
+ localStorage.setItem(localStorageKey, panel);
39
+ };
40
+ exports.persistSelectedPanel = persistSelectedPanel;
41
+ exports.rightSidebarTabs = (0, react_1.createRef)();
42
+ const RightPanel = () => {
43
+ const { props, updateProps } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
44
+ const [saving, setSaving] = (0, react_1.useState)(false);
45
+ const [panel, setPanel] = (0, react_1.useState)(() => getSelectedPanel());
46
+ const onCompositionsSelected = (0, react_1.useCallback)(() => {
47
+ setPanel('input-props');
48
+ (0, exports.persistSelectedPanel)('input-props');
49
+ }, []);
50
+ const onRendersSelected = (0, react_1.useCallback)(() => {
51
+ setPanel('renders');
52
+ (0, exports.persistSelectedPanel)('renders');
53
+ }, []);
54
+ (0, react_1.useImperativeHandle)(exports.rightSidebarTabs, () => {
55
+ return {
56
+ selectRendersPanel: () => {
57
+ setPanel('renders');
58
+ (0, exports.persistSelectedPanel)('renders');
59
+ },
60
+ };
61
+ }, []);
62
+ const { compositions, currentComposition } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
63
+ const circleStyle = (0, react_1.useMemo)(() => {
64
+ const onTabColor = saving ? colors_1.LIGHT_TEXT : 'white';
65
+ return {
66
+ ...circle,
67
+ backgroundColor: panel === 'input-props' ? onTabColor : colors_1.LIGHT_TEXT,
68
+ cursor: 'help',
69
+ };
70
+ }, [panel, saving]);
71
+ const composition = (0, react_1.useMemo)(() => {
72
+ for (const comp of compositions) {
73
+ if (comp.id === currentComposition) {
74
+ return comp;
75
+ }
76
+ }
77
+ return null;
78
+ }, [compositions, currentComposition]);
79
+ const saveToolTip = (0, react_1.useMemo)(() => {
80
+ return process.env.KEYBOARD_SHORTCUTS_ENABLED
81
+ ? `Save using ${ShortcutHint_1.cmdOrCtrlCharacter}+S`
82
+ : 'There are unsaved changes';
83
+ }, []);
84
+ const setInputProps = (0, react_1.useCallback)((newProps) => {
85
+ if (composition === null) {
86
+ return;
87
+ }
88
+ updateProps({
89
+ id: composition.id,
90
+ defaultProps: composition.defaultProps,
91
+ newProps,
92
+ });
93
+ }, [composition, updateProps]);
94
+ const actualProps = (0, react_1.useMemo)(() => {
95
+ var _a, _b;
96
+ if (composition === null) {
97
+ return {};
98
+ }
99
+ return (_b = (_a = props[composition.id]) !== null && _a !== void 0 ? _a : composition.defaultProps) !== null && _b !== void 0 ? _b : {};
100
+ }, [composition, props]);
101
+ const unsavedChangesExist = (0, react_1.useMemo)(() => {
102
+ if (composition === null || composition.defaultProps === undefined) {
103
+ return false;
104
+ }
105
+ return !(0, deep_equal_1.deepEqual)(composition.defaultProps, actualProps);
106
+ }, [actualProps, composition]);
107
+ if (composition === null) {
108
+ return null;
109
+ }
110
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { style: tabsContainer, children: (0, jsx_runtime_1.jsxs)(Tabs_1.Tabs, { children: [(0, jsx_runtime_1.jsxs)(Tabs_1.Tab, { selected: panel === 'input-props', onClick: onCompositionsSelected, style: { justifyContent: 'space-between' }, children: ["Props", unsavedChangesExist ? ((0, jsx_runtime_1.jsx)("div", { title: saveToolTip, style: circleStyle })) : null] }), (0, jsx_runtime_1.jsx)(RendersTab_1.RendersTab, { onClick: onRendersSelected, selected: panel === 'renders' })] }) }), panel === 'renders' ? ((0, jsx_runtime_1.jsx)(RenderQueue_1.RenderQueue, {})) : ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { unresolvedComposition: composition, inputProps: actualProps, setInputProps: setInputProps, mayShowSaveButton: true, propsEditType: "default-props", saving: saving, setSaving: setSaving }, composition.id))] }));
111
+ };
112
+ exports.RightPanel = RightPanel;
@@ -61,6 +61,7 @@ const SidebarRenderButton = ({ composition, visible }) => {
61
61
  initialMuted: defaults.muted,
62
62
  initialEnforceAudioTrack: defaults.enforceAudioTrack,
63
63
  initialProResProfile: defaults.proResProfile,
64
+ initialx264Preset: defaults.x264Preset,
64
65
  initialPixelFormat: defaults.pixelFormat,
65
66
  initialAudioBitrate: defaults.audioBitrate,
66
67
  initialVideoBitrate: defaults.videoBitrate,
@@ -16,4 +16,4 @@ export declare const BLUE_DISABLED = "#284f73";
16
16
  export declare const getBackgroundFromHoverState: ({ selected, hovered, }: {
17
17
  selected: boolean;
18
18
  hovered: boolean;
19
- }) => "transparent" | "rgba(255, 255, 255, 0.06)" | "hsla(0, 0%, 100%, 0.15)" | "hsla(0, 0%, 100%, 0.25)";
19
+ }) => "transparent" | "hsla(0, 0%, 100%, 0.15)" | "hsla(0, 0%, 100%, 0.25)" | "rgba(255, 255, 255, 0.06)";
@@ -12,6 +12,7 @@ const setCurrentVideoId = (id) => {
12
12
  };
13
13
  exports.setCurrentVideoId = setCurrentVideoId;
14
14
  const setUnsavedProps = (unsaved) => {
15
+ window.remotion_unsavedProps = unsaved;
15
16
  unsavedProps = unsaved;
16
17
  };
17
18
  exports.setUnsavedProps = setUnsavedProps;
@@ -0,0 +1,2 @@
1
+ import type { X264Preset } from '@remotion/renderer';
2
+ export declare const labelx264Preset: (profile: X264Preset) => "medium" | "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "slow" | "slower" | "veryslow" | "placebo";
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.labelx264Preset = void 0;
4
+ const labelx264Preset = (profile) => {
5
+ if (profile === 'ultrafast') {
6
+ return 'ultrafast';
7
+ }
8
+ if (profile === 'superfast') {
9
+ return 'superfast';
10
+ }
11
+ if (profile === 'veryfast') {
12
+ return 'veryfast';
13
+ }
14
+ if (profile === 'faster') {
15
+ return 'faster';
16
+ }
17
+ if (profile === 'fast') {
18
+ return 'fast';
19
+ }
20
+ if (profile === 'medium') {
21
+ return 'medium';
22
+ }
23
+ if (profile === 'slow') {
24
+ return 'slow';
25
+ }
26
+ if (profile === 'slower') {
27
+ return 'slower';
28
+ }
29
+ if (profile === 'veryslow') {
30
+ return 'veryslow';
31
+ }
32
+ if (profile === 'placebo') {
33
+ return 'placebo';
34
+ }
35
+ throw new TypeError(`Unknown x264 preset: ${profile}`);
36
+ };
37
+ exports.labelx264Preset = labelx264Preset;
@@ -1,4 +1,4 @@
1
- import type { AudioCodec, Codec, OpenGlRenderer, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
1
+ import type { AudioCodec, Codec, OpenGlRenderer, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
2
2
  import type React from 'react';
3
3
  import type { QuickSwitcherMode } from '../components/QuickSwitcher/NoResults';
4
4
  import type { RenderType } from '../components/RenderModal/RenderModalAdvanced';
@@ -22,6 +22,7 @@ export type RenderModalState = {
22
22
  initialMuted: boolean;
23
23
  initialEnforceAudioTrack: boolean;
24
24
  initialProResProfile: ProResProfile;
25
+ initialx264Preset: X264Preset;
25
26
  initialPixelFormat: PixelFormat;
26
27
  initialVideoBitrate: string | null;
27
28
  initialAudioBitrate: string | null;
@@ -16,11 +16,12 @@ export declare const getCliOptions: (options: {
16
16
  crf: import("@remotion/renderer").Crf | null;
17
17
  pixelFormat: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
18
18
  proResProfile: "4444-xq" | "4444" | "hq" | "standard" | "light" | "proxy" | undefined;
19
+ x264Preset: "medium" | "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "slow" | "slower" | "veryslow" | "placebo" | undefined;
19
20
  everyNthFrame: number;
20
21
  numberOfGifLoops: import("./config/number-of-gif-loops").Loop;
21
22
  stillFrame: number;
22
23
  browserExecutable: BrowserExecutable;
23
- logLevel: "error" | "verbose" | "info" | "warn";
24
+ logLevel: "verbose" | "info" | "warn" | "error";
24
25
  scale: number;
25
26
  chromiumOptions: ChromiumOptions;
26
27
  overwrite: boolean;
@@ -44,6 +44,10 @@ const getProResProfile = () => {
44
44
  const proResProfile = config_1.ConfigInternals.getProResProfile();
45
45
  return proResProfile;
46
46
  };
47
+ const getx264Preset = () => {
48
+ const x264Preset = config_1.ConfigInternals.getPresetProfile();
49
+ return x264Preset;
50
+ };
47
51
  const getAndValidateBrowser = async (browserExecutable) => {
48
52
  const browser = getBrowser();
49
53
  try {
@@ -71,6 +75,7 @@ const getCliOptions = async (options) => {
71
75
  const videoBitrate = config_1.ConfigInternals.getVideoBitrate();
72
76
  const pixelFormat = config_1.ConfigInternals.getPixelFormat();
73
77
  const proResProfile = getProResProfile();
78
+ const x264Preset = getx264Preset();
74
79
  const browserExecutable = config_1.ConfigInternals.getBrowserExecutable();
75
80
  const scale = config_1.ConfigInternals.getScale();
76
81
  const port = config_1.ConfigInternals.getServerPort();
@@ -99,6 +104,7 @@ const getCliOptions = async (options) => {
99
104
  crf,
100
105
  pixelFormat,
101
106
  proResProfile,
107
+ x264Preset,
102
108
  everyNthFrame,
103
109
  numberOfGifLoops,
104
110
  stillFrame: config_1.ConfigInternals.getStillFrame(),
package/dist/index.d.ts CHANGED
@@ -63,24 +63,24 @@ export declare const CliInternals: {
63
63
  verbose: (message?: any, ...optionalParams: any[]) => void;
64
64
  verboseAdvanced: (options: {
65
65
  indent: boolean;
66
- logLevel: "error" | "verbose" | "info" | "warn";
66
+ logLevel: "verbose" | "info" | "warn" | "error";
67
67
  } & {
68
68
  tag?: string | undefined;
69
69
  }, message?: any, ...optionalParams: any[]) => void;
70
70
  info: (message?: any, ...optionalParams: any[]) => void;
71
71
  infoAdvanced: (options: {
72
72
  indent: boolean;
73
- logLevel: "error" | "verbose" | "info" | "warn";
73
+ logLevel: "verbose" | "info" | "warn" | "error";
74
74
  }, message?: any, ...optionalParams: any[]) => void;
75
75
  warn: (message?: any, ...optionalParams: any[]) => void;
76
76
  warnAdvanced: (options: {
77
77
  indent: boolean;
78
- logLevel: "error" | "verbose" | "info" | "warn";
78
+ logLevel: "verbose" | "info" | "warn" | "error";
79
79
  }, message?: any, ...optionalParams: any[]) => void;
80
80
  error: (message?: any, ...optionalParams: any[]) => void;
81
81
  errorAdvanced: (options: {
82
82
  indent: boolean;
83
- logLevel: "error" | "verbose" | "info" | "warn";
83
+ logLevel: "verbose" | "info" | "warn" | "error";
84
84
  } & {
85
85
  tag?: string | undefined;
86
86
  }, message?: any, ...optionalParams: any[]) => void;
@@ -101,11 +101,12 @@ export declare const CliInternals: {
101
101
  crf: import("@remotion/renderer").Crf | null;
102
102
  pixelFormat: "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
103
103
  proResProfile: "4444-xq" | "4444" | "hq" | "standard" | "light" | "proxy" | undefined;
104
+ x264Preset: "medium" | "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "slow" | "slower" | "veryslow" | "placebo" | undefined;
104
105
  everyNthFrame: number;
105
106
  numberOfGifLoops: import("./config/number-of-gif-loops").Loop;
106
107
  stillFrame: number;
107
108
  browserExecutable: import("@remotion/renderer").BrowserExecutable;
108
- logLevel: "error" | "verbose" | "info" | "warn";
109
+ logLevel: "verbose" | "info" | "warn" | "error";
109
110
  scale: number;
110
111
  chromiumOptions: import("@remotion/renderer").ChromiumOptions;
111
112
  overwrite: boolean;
@@ -129,6 +130,7 @@ export declare const CliInternals: {
129
130
  "pixel-format": "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
130
131
  "image-format": "none" | "png" | "jpeg" | "pdf" | "webp";
131
132
  "prores-profile": "4444-xq" | "4444" | "hq" | "standard" | "light" | "proxy";
133
+ "x264-preset": "medium" | "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "slow" | "slower" | "veryslow" | "placebo";
132
134
  "bundle-cache": string;
133
135
  "env-file": string;
134
136
  "ignore-certificate-errors": string;
@@ -180,7 +182,7 @@ export declare const CliInternals: {
180
182
  } & {
181
183
  _: string[];
182
184
  };
183
- handleCommonError: (err: Error, logLevel: "error" | "verbose" | "info" | "warn") => Promise<void>;
185
+ handleCommonError: (err: Error, logLevel: "verbose" | "info" | "warn" | "error") => Promise<void>;
184
186
  formatBytes: (number: number, options?: Intl.NumberFormatOptions & {
185
187
  locale: string;
186
188
  bits?: boolean | undefined;
@@ -222,7 +224,7 @@ export declare const CliInternals: {
222
224
  };
223
225
  listOfRemotionPackages: string[];
224
226
  shouldUseNonOverlayingLogger: ({ logLevel, }: {
225
- logLevel: "error" | "verbose" | "info" | "warn";
227
+ logLevel: "verbose" | "info" | "warn" | "error";
226
228
  }) => boolean;
227
229
  getCompositionWithDimensionOverride: ({ height, width, args, compositionIdFromUi, chromiumOptions, envVariables, port, puppeteerInstance, timeoutInMilliseconds, browserExecutable, serveUrlOrWebpackUrl, indent, serializedInputPropsWithCustomSchema, logLevel, server, }: {
228
230
  height: number | null;
@@ -237,7 +239,7 @@ export declare const CliInternals: {
237
239
  browserExecutable: import("@remotion/renderer").BrowserExecutable;
238
240
  serveUrlOrWebpackUrl: string;
239
241
  indent: boolean;
240
- logLevel: "error" | "verbose" | "info" | "warn";
242
+ logLevel: "verbose" | "info" | "warn" | "error";
241
243
  serializedInputPropsWithCustomSchema: string;
242
244
  server: import("@remotion/renderer").RemotionServer;
243
245
  }) => Promise<{
package/dist/log.d.ts CHANGED
@@ -2,24 +2,24 @@ export declare const Log: {
2
2
  verbose: (message?: any, ...optionalParams: any[]) => void;
3
3
  verboseAdvanced: (options: {
4
4
  indent: boolean;
5
- logLevel: "error" | "verbose" | "info" | "warn";
5
+ logLevel: "verbose" | "info" | "warn" | "error";
6
6
  } & {
7
7
  tag?: string | undefined;
8
8
  }, message?: any, ...optionalParams: any[]) => void;
9
9
  info: (message?: any, ...optionalParams: any[]) => void;
10
10
  infoAdvanced: (options: {
11
11
  indent: boolean;
12
- logLevel: "error" | "verbose" | "info" | "warn";
12
+ logLevel: "verbose" | "info" | "warn" | "error";
13
13
  }, message?: any, ...optionalParams: any[]) => void;
14
14
  warn: (message?: any, ...optionalParams: any[]) => void;
15
15
  warnAdvanced: (options: {
16
16
  indent: boolean;
17
- logLevel: "error" | "verbose" | "info" | "warn";
17
+ logLevel: "verbose" | "info" | "warn" | "error";
18
18
  }, message?: any, ...optionalParams: any[]) => void;
19
19
  error: (message?: any, ...optionalParams: any[]) => void;
20
20
  errorAdvanced: (options: {
21
21
  indent: boolean;
22
- logLevel: "error" | "verbose" | "info" | "warn";
22
+ logLevel: "verbose" | "info" | "warn" | "error";
23
23
  } & {
24
24
  tag?: string | undefined;
25
25
  }, message?: any, ...optionalParams: any[]) => void;
@@ -1,9 +1,10 @@
1
- import type { AudioCodec, BrowserExecutable, Codec, OpenGlRenderer, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
1
+ import type { AudioCodec, BrowserExecutable, Codec, OpenGlRenderer, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
2
2
  type CommandLineOptions = {
3
3
  ['browser-executable']: BrowserExecutable;
4
4
  ['pixel-format']: PixelFormat;
5
5
  ['image-format']: VideoImageFormat | StillImageFormat;
6
6
  ['prores-profile']: ProResProfile;
7
+ ['x264-preset']: X264Preset;
7
8
  ['bundle-cache']: string;
8
9
  ['env-file']: string;
9
10
  ['ignore-certificate-errors']: string;
@@ -105,6 +105,9 @@ const parseCommandLine = () => {
105
105
  if (exports.parsedCli['prores-profile']) {
106
106
  config_1.Config.setProResProfile(String(exports.parsedCli['prores-profile']));
107
107
  }
108
+ if (exports.parsedCli['x264-preset']) {
109
+ config_1.Config.setX264Preset(String(exports.parsedCli['x264-preset']));
110
+ }
108
111
  if (exports.parsedCli.overwrite) {
109
112
  config_1.Config.setOverwriteOutput(exports.parsedCli.overwrite);
110
113
  }
@@ -4,6 +4,7 @@ exports.allApiRoutes = void 0;
4
4
  const add_render_1 = require("./routes/add-render");
5
5
  const can_update_default_props_1 = require("./routes/can-update-default-props");
6
6
  const cancel_render_1 = require("./routes/cancel-render");
7
+ const copy_still_to_clipboard_handler_1 = require("./routes/copy-still-to-clipboard-handler");
7
8
  const open_in_file_explorer_1 = require("./routes/open-in-file-explorer");
8
9
  const remove_render_1 = require("./routes/remove-render");
9
10
  const subscribe_to_file_existence_1 = require("./routes/subscribe-to-file-existence");
@@ -17,6 +18,7 @@ exports.allApiRoutes = {
17
18
  '/api/subscribe-to-file-existence': subscribe_to_file_existence_1.subscribeToFileExistence,
18
19
  '/api/remove-render': remove_render_1.handleRemoveRender,
19
20
  '/api/open-in-file-explorer': open_in_file_explorer_1.handleOpenInFileExplorer,
21
+ '/api/copy-still-to-clipboard': copy_still_to_clipboard_handler_1.handleCopyStillToClipboard,
20
22
  '/api/update-default-props': update_default_props_1.updateDefaultPropsHandler,
21
23
  '/api/can-update-default-props': can_update_default_props_1.canUpdateDefaultPropsHandler,
22
24
  '/api/update-available': update_available_1.handleUpdate,
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import type { IncomingMessage, ServerResponse } from 'node:http';
3
- import type { AddRenderRequest, CancelRenderRequest, CancelRenderResponse, CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse, OpenInFileExplorerRequest, RemoveRenderRequest, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, UnsubscribeFromFileExistenceRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse } from './render-queue/job';
3
+ import type { AddRenderRequest, CancelRenderRequest, CancelRenderResponse, CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse, CopyStillToClipboardRequest, OpenInFileExplorerRequest, RemoveRenderRequest, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, UnsubscribeFromFileExistenceRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse } from './render-queue/job';
4
4
  export type ApiHandler<ReqData, ResData> = (params: {
5
5
  input: ReqData;
6
6
  entryPoint: string;
@@ -19,6 +19,7 @@ export type ApiRoutes = {
19
19
  '/api/subscribe-to-file-existence': ReqAndRes<SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse>;
20
20
  '/api/remove-render': ReqAndRes<RemoveRenderRequest, undefined>;
21
21
  '/api/open-in-file-explorer': ReqAndRes<OpenInFileExplorerRequest, void>;
22
+ '/api/copy-still-to-clipboard': ReqAndRes<CopyStillToClipboardRequest, void>;
22
23
  '/api/update-default-props': ReqAndRes<UpdateDefaultPropsRequest, UpdateDefaultPropsResponse>;
23
24
  '/api/can-update-default-props': ReqAndRes<CanUpdateDefaultPropsRequest, CanUpdateDefaultPropsResponse>;
24
25
  '/api/update-available': ReqAndRes<UpdateAvailableRequest, UpdateAvailableResponse>;
@@ -42,6 +42,7 @@ const crashWithFrames = (crash) => (error) => {
42
42
  if (didHookOrderChange && !justRefreshedBecauseOfHooks) {
43
43
  // eslint-disable-next-line no-console
44
44
  console.log('Hook order changed. Reloading app...');
45
+ window.remotion_unsavedProps = false;
45
46
  window.location.reload();
46
47
  }
47
48
  else {
@@ -7,14 +7,15 @@ exports.getFileSource = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const allowedFileExtensions = ['js', 'ts', 'tsx', 'jsx', 'map', 'mjs'];
10
+ // Must be async function for proper error handling
10
11
  const getFileSource = (remotionRoot, p) => {
11
12
  if (!allowedFileExtensions.find((extension) => p.endsWith(extension))) {
12
- throw new Error(`Not allowed to open ${p}`);
13
+ return Promise.reject(new Error(`Not allowed to open ${p}`));
13
14
  }
14
15
  const resolved = node_path_1.default.resolve(remotionRoot, p);
15
16
  const relativeToProcessCwd = node_path_1.default.relative(remotionRoot, resolved);
16
17
  if (relativeToProcessCwd.startsWith('..')) {
17
- throw new Error(`Not allowed to open ${relativeToProcessCwd}`);
18
+ return Promise.reject(new Error(`Not allowed to open ${relativeToProcessCwd}`));
18
19
  }
19
20
  return node_fs_1.default.promises.readFile(p, 'utf-8');
20
21
  };
@@ -3,10 +3,5 @@
3
3
  * https://github.com/webpack-contrib/webpack-hot-middleware#readme
4
4
  * and rewritten in TypeScript. This file is MIT licensed
5
5
  */
6
- /**
7
- * Based heavily on https://github.com/webpack/webpack/blob/
8
- * c0afdf9c6abc1dd70707c594e473802a566f7b6e/hot/only-dev-server.js
9
- * Original copyright Tobias Koppers @sokra (MIT license)
10
- */
11
6
  import type { HotMiddlewareOptions, ModuleMap } from './types';
12
7
  export declare const processUpdate: (hash: string | undefined, moduleMap: ModuleMap, options: HotMiddlewareOptions) => void;
@@ -7,6 +7,12 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.processUpdate = void 0;
10
+ /**
11
+ * Based heavily on https://github.com/webpack/webpack/blob/
12
+ * c0afdf9c6abc1dd70707c594e473802a566f7b6e/hot/only-dev-server.js
13
+ * Original copyright Tobias Koppers @sokra (MIT license)
14
+ */
15
+ const NotificationCenter_1 = require("../../editor/components/Notifications/NotificationCenter");
10
16
  if (!__webpack_module__.hot) {
11
17
  throw new Error('[Fast refresh] Hot Module Replacement is disabled.');
12
18
  }
@@ -128,16 +134,29 @@ const processUpdate = function (hash, moduleMap, options) {
128
134
  }
129
135
  if (options.warn) {
130
136
  console.warn('[Fast refresh] Update check failed: ' + (err.stack || err.message));
131
- window.location.reload();
137
+ if (!window.remotion_unsavedProps) {
138
+ window.location.reload();
139
+ }
132
140
  }
133
141
  }
134
142
  function performReload() {
143
+ var _a;
135
144
  if (!reload) {
136
145
  return;
137
146
  }
138
147
  if (options.warn)
139
148
  console.warn('[Fast refresh] Reloading page');
140
- window.location.reload();
149
+ if (window.remotion_unsavedProps) {
150
+ (_a = NotificationCenter_1.notificationCenter.current) === null || _a === void 0 ? void 0 : _a.addNotification({
151
+ id: 'random',
152
+ content: 'Fast refresh needs to reload the page, but you have unsaved props. Save then reload the page to apply changes.',
153
+ created: new Date().getMilliseconds(),
154
+ duration: 1,
155
+ });
156
+ }
157
+ else {
158
+ window.location.reload();
159
+ }
141
160
  }
142
161
  };
143
162
  exports.processUpdate = processUpdate;
@@ -0,0 +1 @@
1
+ export declare const copyStillToClipBoard: (img: string) => Promise<void>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.copyStillToClipBoard = void 0;
4
+ const renderer_1 = require("@remotion/renderer");
5
+ const copyStillToClipBoard = (img) => {
6
+ return renderer_1.RenderInternals.copyImageToClipboard(img, 'info');
7
+ };
8
+ exports.copyStillToClipBoard = copyStillToClipBoard;
@@ -1,4 +1,4 @@
1
- import type { AudioCodec, Codec, makeCancelSignal, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
1
+ import type { AudioCodec, Codec, makeCancelSignal, PixelFormat, ProResProfile, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
2
2
  import type { EnumPath } from '../../editor/components/RenderModal/SchemaEditor/extract-enum-json-paths';
3
3
  import type { AggregateRenderProgress } from '../../progress-types';
4
4
  import type { RequiredChromiumOptions } from '../../required-chromium-options';
@@ -43,6 +43,7 @@ type RenderJobDynamicFields = ({
43
43
  muted: boolean;
44
44
  enforceAudioTrack: boolean;
45
45
  proResProfile: ProResProfile | null;
46
+ x264Preset: X264Preset | null;
46
47
  pixelFormat: PixelFormat;
47
48
  audioBitrate: string | null;
48
49
  videoBitrate: string | null;
@@ -88,6 +89,7 @@ type AddRenderRequestDynamicFields = {
88
89
  muted: boolean;
89
90
  enforceAudioTrack: boolean;
90
91
  proResProfile: ProResProfile | null;
92
+ x264Preset: X264Preset | null;
91
93
  pixelFormat: PixelFormat;
92
94
  audioBitrate: string | null;
93
95
  videoBitrate: string | null;
@@ -113,6 +115,9 @@ export type RemoveRenderRequest = {
113
115
  export type OpenInFileExplorerRequest = {
114
116
  directory: string;
115
117
  };
118
+ export type CopyStillToClipboardRequest = {
119
+ outName: string;
120
+ };
116
121
  export type SubscribeToFileExistenceRequest = {
117
122
  file: string;
118
123
  clientId: string;