@remotion/cli 4.1.0-alpha5 → 4.1.0-alpha7
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.
- package/dist/config/image-format.d.ts +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/editor/components/CanvasOrLoading.js +20 -1
- package/dist/editor/components/CopyButton.js +5 -2
- package/dist/editor/components/Editor.js +1 -3
- package/dist/editor/components/FramePersistor.d.ts +0 -2
- package/dist/editor/components/FramePersistor.js +4 -24
- package/dist/editor/components/InitialCompositionLoader.js +1 -22
- package/dist/editor/components/NewComposition/RemInput.d.ts +2 -2
- package/dist/editor/components/NewComposition/RemInputTypeColor.d.ts +1 -1
- package/dist/editor/components/NewComposition/RemTextarea.d.ts +1 -1
- package/dist/editor/components/OpenEditorButton.js +5 -2
- package/dist/editor/components/QuickSwitcher/QuickSwitcherResult.js +3 -3
- package/dist/editor/components/RenderModal/RenderModal.js +5 -2
- package/dist/editor/components/RenderModal/RenderModalBasic.d.ts +2 -3
- package/dist/editor/components/RenderModal/SchemaEditor/SchemaErrorMessages.js +1 -3
- package/dist/editor/components/RenderModal/SchemaEditor/ZodSwitch.js +0 -1
- package/dist/editor/components/RenderModal/human-readable-codec.d.ts +1 -1
- package/dist/editor/components/SetTimelineInOutProvider.js +5 -4
- package/dist/editor/components/SidebarRenderButton.js +3 -1
- package/dist/editor/components/Timeline/TimelineDragHandler.js +45 -19
- package/dist/editor/components/TimelineInOutToggle.d.ts +2 -1
- package/dist/editor/components/TimelineInOutToggle.js +82 -67
- package/dist/editor/helpers/colors.d.ts +1 -1
- package/dist/editor/helpers/is-composition-still.d.ts +1 -1
- package/dist/editor/helpers/is-current-selected-still.js +5 -6
- package/dist/editor/helpers/render-modal-sections.d.ts +1 -0
- package/dist/editor/icons/keys.js +1 -0
- package/dist/editor/state/in-out.d.ts +3 -2
- package/dist/editor/state/in-out.js +22 -5
- package/dist/editor/state/marks.d.ts +3 -2
- package/dist/editor/state/marks.js +6 -6
- package/dist/get-cli-options.d.ts +1 -1
- package/dist/handle-common-errors.js +4 -0
- package/dist/index.d.ts +6 -6
- package/dist/parse-command-line.js +1 -1
- package/dist/preview-server/dev-middleware/range-parser.d.ts +1 -1
- package/dist/preview-server/error-overlay/remotion-overlay/Button.js +1 -0
- package/dist/preview-server/render-queue/open-directory-in-finder.js +11 -5
- package/dist/preview-server/routes.d.ts +1 -0
- package/dist/print-compositions.d.ts +2 -2
- package/package.json +10 -10
|
@@ -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: () => "
|
|
5
|
+
export declare const getUserPreferredVideoImageFormat: () => "png" | "jpeg" | "none" | undefined;
|
package/dist/config/index.d.ts
CHANGED
|
@@ -297,7 +297,7 @@ export declare const ConfigInternals: {
|
|
|
297
297
|
getShouldOutputImageSequence: (frameRange: FrameRange | null) => boolean;
|
|
298
298
|
getDotEnvLocation: () => string | null;
|
|
299
299
|
getUserPreferredStillImageFormat: () => "png" | "jpeg" | "pdf" | "webp" | undefined;
|
|
300
|
-
getUserPreferredVideoImageFormat: () => "
|
|
300
|
+
getUserPreferredVideoImageFormat: () => "png" | "jpeg" | "none" | undefined;
|
|
301
301
|
getWebpackOverrideFn: () => WebpackOverrideFn;
|
|
302
302
|
getWebpackCaching: () => boolean;
|
|
303
303
|
getOutputLocation: () => string | null;
|
|
@@ -10,6 +10,11 @@ const Canvas_1 = require("./Canvas");
|
|
|
10
10
|
const layout_1 = require("./layout");
|
|
11
11
|
const styles_1 = require("./Menu/styles");
|
|
12
12
|
const Spinner_1 = require("./Spinner");
|
|
13
|
+
const FramePersistor_1 = require("./FramePersistor");
|
|
14
|
+
const ZoomPersistor_1 = require("./ZoomPersistor");
|
|
15
|
+
const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
|
|
16
|
+
const timeline_zoom_1 = require("../state/timeline-zoom");
|
|
17
|
+
const imperative_state_1 = require("./Timeline/imperative-state");
|
|
13
18
|
const container = {
|
|
14
19
|
color: 'white',
|
|
15
20
|
flex: 1,
|
|
@@ -22,6 +27,7 @@ const container = {
|
|
|
22
27
|
const CanvasOrLoading = () => {
|
|
23
28
|
const resolved = remotion_1.Internals.useResolvedVideoConfig(null);
|
|
24
29
|
const [takesALongTime, setTakesALongTime] = (0, react_1.useState)(false);
|
|
30
|
+
const { setZoom } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
|
|
25
31
|
(0, react_1.useEffect)(() => {
|
|
26
32
|
const timeout = setTimeout(() => {
|
|
27
33
|
setTakesALongTime(true);
|
|
@@ -30,6 +36,19 @@ const CanvasOrLoading = () => {
|
|
|
30
36
|
clearTimeout(timeout);
|
|
31
37
|
};
|
|
32
38
|
}, []);
|
|
39
|
+
(0, react_1.useEffect)(() => {
|
|
40
|
+
if ((resolved === null || resolved === void 0 ? void 0 : resolved.type) !== 'success') {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const c = resolved.result;
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
46
|
+
direction: 'center',
|
|
47
|
+
frame: (0, imperative_state_1.getCurrentFrame)(),
|
|
48
|
+
durationInFrames: c.durationInFrames,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}, [resolved, setZoom]);
|
|
33
52
|
const style = (0, react_1.useMemo)(() => {
|
|
34
53
|
return {
|
|
35
54
|
...loaderLabel,
|
|
@@ -46,7 +65,7 @@ const CanvasOrLoading = () => {
|
|
|
46
65
|
if (resolved.type === 'error') {
|
|
47
66
|
return (0, jsx_runtime_1.jsx)(exports.ErrorLoading, { error: resolved.error });
|
|
48
67
|
}
|
|
49
|
-
return (0, jsx_runtime_1.jsx)(Canvas_1.Canvas, {});
|
|
68
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(FramePersistor_1.FramePersistor, {}), (0, jsx_runtime_1.jsx)(ZoomPersistor_1.ZoomPersistor, {}), (0, jsx_runtime_1.jsx)(Canvas_1.Canvas, {})] }));
|
|
50
69
|
};
|
|
51
70
|
exports.CanvasOrLoading = CanvasOrLoading;
|
|
52
71
|
const loaderLabel = {
|
|
@@ -10,7 +10,10 @@ const iconStyle = {
|
|
|
10
10
|
width: 16,
|
|
11
11
|
height: 16,
|
|
12
12
|
color: 'white',
|
|
13
|
-
|
|
13
|
+
};
|
|
14
|
+
const buttonContainerStyle = {
|
|
15
|
+
display: 'flex',
|
|
16
|
+
minWidth: '114px',
|
|
14
17
|
};
|
|
15
18
|
const copyIcon = ((0, jsx_runtime_1.jsx)("svg", { "aria-hidden": "true", focusable: "false", "data-prefix": "far", "data-icon": "clipboard", className: "svg-inline--fa fa-clipboard fa-w-12", role: "img", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 384 512", style: iconStyle, children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z" }) }));
|
|
16
19
|
const labelStyle = {
|
|
@@ -29,6 +32,6 @@ const CopyButton = ({ textToCopy, label, labelWhenCopied }) => {
|
|
|
29
32
|
const to = setTimeout(() => setCopied(false), 2000);
|
|
30
33
|
return () => clearTimeout(to);
|
|
31
34
|
}, [copied]);
|
|
32
|
-
return ((0, jsx_runtime_1.jsxs)(Button_1.Button, { onClick: onClick, children: [copyIcon, (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 }), ' ', (0, jsx_runtime_1.jsx)("span", { style: labelStyle, children: copied ? labelWhenCopied : label })] }));
|
|
35
|
+
return ((0, jsx_runtime_1.jsxs)(Button_1.Button, { onClick: onClick, style: {}, buttonContainerStyle: buttonContainerStyle, children: [copyIcon, (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 }), ' ', (0, jsx_runtime_1.jsx)("span", { style: labelStyle, children: copied ? labelWhenCopied : label })] }));
|
|
33
36
|
};
|
|
34
37
|
exports.CopyButton = CopyButton;
|
|
@@ -9,12 +9,10 @@ const noop_1 = require("../helpers/noop");
|
|
|
9
9
|
const timeline_zoom_1 = require("../state/timeline-zoom");
|
|
10
10
|
const z_index_1 = require("../state/z-index");
|
|
11
11
|
const EditorContent_1 = require("./EditorContent");
|
|
12
|
-
const FramePersistor_1 = require("./FramePersistor");
|
|
13
12
|
const GlobalKeybindings_1 = require("./GlobalKeybindings");
|
|
14
13
|
const Modals_1 = require("./Modals");
|
|
15
14
|
const NoRegisterRoot_1 = require("./NoRegisterRoot");
|
|
16
15
|
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
|
|
17
|
-
const ZoomPersistor_1 = require("./ZoomPersistor");
|
|
18
16
|
const background = {
|
|
19
17
|
backgroundColor: colors_1.BACKGROUND,
|
|
20
18
|
display: 'flex',
|
|
@@ -41,6 +39,6 @@ const Editor = () => {
|
|
|
41
39
|
});
|
|
42
40
|
return () => cleanup();
|
|
43
41
|
}, [Root, waitForRoot]);
|
|
44
|
-
return ((0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: noop_1.noop, onOutsideClick: noop_1.noop, children: (0, jsx_runtime_1.jsxs)(timeline_zoom_1.TimelineZoomContext, { children: [(0, jsx_runtime_1.jsxs)("div", { style: background, children: [Root === null ? null : (0, jsx_runtime_1.jsx)(Root, {}), (0, jsx_runtime_1.jsxs)(remotion_1.Internals.CanUseRemotionHooksProvider, { children: [
|
|
42
|
+
return ((0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onEscape: noop_1.noop, onOutsideClick: noop_1.noop, children: (0, jsx_runtime_1.jsxs)(timeline_zoom_1.TimelineZoomContext, { children: [(0, jsx_runtime_1.jsxs)("div", { style: background, children: [Root === null ? null : (0, jsx_runtime_1.jsx)(Root, {}), (0, jsx_runtime_1.jsxs)(remotion_1.Internals.CanUseRemotionHooksProvider, { children: [Root === null ? (0, jsx_runtime_1.jsx)(NoRegisterRoot_1.NoRegisterRoot, {}) : (0, jsx_runtime_1.jsx)(EditorContent_1.EditorContent, {}), (0, jsx_runtime_1.jsx)(GlobalKeybindings_1.GlobalKeybindings, {})] }), (0, jsx_runtime_1.jsx)(NotificationCenter_1.NotificationCenter, {})] }), (0, jsx_runtime_1.jsx)(Modals_1.Modals, {})] }) }));
|
|
45
43
|
};
|
|
46
44
|
exports.Editor = Editor;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
export declare const getCurrentCompositionFromUrl: () => string;
|
|
3
|
-
export declare const persistCurrentFrame: (frame: number) => void;
|
|
4
|
-
export declare const getFrameForComposition: (composition: string) => number;
|
|
5
3
|
export declare const FramePersistor: React.FC;
|
|
@@ -1,41 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FramePersistor = exports.
|
|
3
|
+
exports.FramePersistor = exports.getCurrentCompositionFromUrl = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const remotion_1 = require("remotion");
|
|
6
6
|
const getCurrentCompositionFromUrl = () => {
|
|
7
7
|
return window.location.pathname.substr(1);
|
|
8
8
|
};
|
|
9
9
|
exports.getCurrentCompositionFromUrl = getCurrentCompositionFromUrl;
|
|
10
|
-
const makeKey = (composition) => {
|
|
11
|
-
return `remotion.time.${composition}`;
|
|
12
|
-
};
|
|
13
|
-
const persistCurrentFrame = (frame) => {
|
|
14
|
-
const currentComposition = (0, exports.getCurrentCompositionFromUrl)();
|
|
15
|
-
if (!currentComposition) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
localStorage.setItem(makeKey(currentComposition), String(frame));
|
|
19
|
-
};
|
|
20
|
-
exports.persistCurrentFrame = persistCurrentFrame;
|
|
21
|
-
const getFrameForComposition = (composition) => {
|
|
22
|
-
const frame = localStorage.getItem(makeKey(composition));
|
|
23
|
-
return frame ? Number(frame) : 0;
|
|
24
|
-
};
|
|
25
|
-
exports.getFrameForComposition = getFrameForComposition;
|
|
26
10
|
const FramePersistor = () => {
|
|
27
11
|
const [playing] = remotion_1.Internals.Timeline.usePlayingState();
|
|
12
|
+
const config = (0, remotion_1.useVideoConfig)();
|
|
28
13
|
const frame = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
29
|
-
const { currentComposition } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
30
|
-
const isActive = currentComposition === (0, exports.getCurrentCompositionFromUrl)();
|
|
31
14
|
(0, react_1.useEffect)(() => {
|
|
32
|
-
if (!isActive) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
15
|
if (!playing) {
|
|
36
|
-
(
|
|
16
|
+
remotion_1.Internals.persistCurrentFrame(frame, config.id);
|
|
37
17
|
}
|
|
38
|
-
}, [
|
|
18
|
+
}, [config.id, frame, playing]);
|
|
39
19
|
return null;
|
|
40
20
|
};
|
|
41
21
|
exports.FramePersistor = FramePersistor;
|
|
@@ -4,37 +4,16 @@ exports.InitialCompositionLoader = exports.useSelectComposition = void 0;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const remotion_1 = require("remotion");
|
|
6
6
|
const folders_1 = require("../state/folders");
|
|
7
|
-
const marks_1 = require("../state/marks");
|
|
8
|
-
const timeline_zoom_1 = require("../state/timeline-zoom");
|
|
9
7
|
const CompositionSelector_1 = require("./CompositionSelector");
|
|
10
8
|
const FramePersistor_1 = require("./FramePersistor");
|
|
11
|
-
const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
|
|
12
|
-
const TimelineInOutToggle_1 = require("./TimelineInOutToggle");
|
|
13
|
-
const ZoomPersistor_1 = require("./ZoomPersistor");
|
|
14
9
|
const useSelectComposition = () => {
|
|
15
|
-
const setCurrentFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
|
|
16
|
-
const { setCurrentComposition } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
17
10
|
const { setFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
|
|
18
|
-
const {
|
|
11
|
+
const { setCurrentComposition } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
19
12
|
return (c, push) => {
|
|
20
|
-
var _a;
|
|
21
|
-
(_a = TimelineInOutToggle_1.inOutHandles.current) === null || _a === void 0 ? void 0 : _a.setMarks((0, marks_1.loadMarks)(c.id, c.durationInFrames));
|
|
22
13
|
if (push) {
|
|
23
14
|
window.history.pushState({}, 'Studio', `/${c.id}`);
|
|
24
15
|
}
|
|
25
|
-
const frame = (0, FramePersistor_1.getFrameForComposition)(c.id);
|
|
26
|
-
const zoom = (0, ZoomPersistor_1.getZoomForComposition)(c.id);
|
|
27
|
-
const frameInBounds = Math.min(c.durationInFrames - 1, frame);
|
|
28
|
-
setCurrentFrame(frameInBounds);
|
|
29
16
|
setCurrentComposition(c.id);
|
|
30
|
-
setZoom(() => zoom);
|
|
31
|
-
setTimeout(() => {
|
|
32
|
-
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
33
|
-
direction: 'center',
|
|
34
|
-
frame,
|
|
35
|
-
durationInFrames: c.durationInFrames,
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
17
|
const { folderName, parentFolderName } = c;
|
|
39
18
|
if (folderName !== null) {
|
|
40
19
|
setFoldersExpanded((ex) => {
|
|
@@ -12,6 +12,6 @@ export declare const getInputBorderColor: ({ status, isFocused, isHovered, }: {
|
|
|
12
12
|
status: 'error' | 'warning' | 'ok';
|
|
13
13
|
isFocused: boolean;
|
|
14
14
|
isHovered: boolean;
|
|
15
|
-
}) => "hsla(0, 0%, 100%, 0.15)" | "rgba(
|
|
16
|
-
export declare const RemotionInput: React.ForwardRefExoticComponent<Pick<Props, "key" | keyof React.InputHTMLAttributes<HTMLInputElement
|
|
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>>;
|
|
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, "key" | keyof React.InputHTMLAttributes<HTMLInputElement
|
|
7
|
+
export declare const RemInputTypeColor: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | keyof React.InputHTMLAttributes<HTMLInputElement>> & 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, "
|
|
6
|
+
export declare const RemTextarea: React.ForwardRefExoticComponent<Pick<Props, "status" | "key" | keyof React.InputHTMLAttributes<HTMLTextAreaElement>> & React.RefAttributes<HTMLTextAreaElement>>;
|
|
7
7
|
export {};
|
|
@@ -12,8 +12,11 @@ const svgStyle = {
|
|
|
12
12
|
};
|
|
13
13
|
const buttonStyle = {
|
|
14
14
|
border: 'none',
|
|
15
|
-
width: '
|
|
16
|
-
height: '
|
|
15
|
+
width: '20px',
|
|
16
|
+
height: '20px',
|
|
17
|
+
display: 'flex',
|
|
18
|
+
justifyContent: 'center',
|
|
19
|
+
alignItems: 'center',
|
|
17
20
|
};
|
|
18
21
|
const OpenEditorButton = () => {
|
|
19
22
|
const [hovered, setHovered] = (0, react_1.useState)(false);
|
|
@@ -98,14 +98,14 @@ const QuickSwitcherResult = ({ result, selected }) => {
|
|
|
98
98
|
fontSize: 15,
|
|
99
99
|
};
|
|
100
100
|
}, [hovered, result.type, selected]);
|
|
101
|
-
return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, style: style, onClick: result.onSelected, children: [result.type === 'composition' ? (result.compositionType === 'still' ? ((0, jsx_runtime_1.jsx)(still_1.StillIcon, { color: selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })) : ((0, jsx_runtime_1.jsx)(video_1.FilmIcon, { color: selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle }))) : null, (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: labelContainer, children: result.type === 'search-result' ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", {
|
|
101
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, style: style, onClick: result.onSelected, children: [result.type === 'composition' ? (result.compositionType === 'still' ? ((0, jsx_runtime_1.jsx)(still_1.StillIcon, { color: selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle })) : ((0, jsx_runtime_1.jsx)(video_1.FilmIcon, { color: selected ? 'white' : colors_1.LIGHT_TEXT, style: iconStyle }))) : null, (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: labelContainer, children: result.type === 'search-result' ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", {
|
|
102
102
|
// eslint-disable-next-line react/no-danger
|
|
103
103
|
dangerouslySetInnerHTML: {
|
|
104
104
|
__html: result.titleLine,
|
|
105
|
-
} }), (0, jsx_runtime_1.jsx)("div", {
|
|
105
|
+
}, style: labelStyle }), (0, jsx_runtime_1.jsx)("div", {
|
|
106
106
|
// eslint-disable-next-line react/no-danger
|
|
107
107
|
dangerouslySetInnerHTML: {
|
|
108
108
|
__html: result.subtitleLine,
|
|
109
|
-
} })] })) : ((0, jsx_runtime_1.jsx)("div", { style: labelStyle, children: result.title })) })] }, result.id));
|
|
109
|
+
}, style: labelStyle })] })) : ((0, jsx_runtime_1.jsx)("div", { style: labelStyle, children: result.title })) })] }, result.id));
|
|
110
110
|
};
|
|
111
111
|
exports.QuickSwitcherResult = QuickSwitcherResult;
|
|
@@ -567,7 +567,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
|
|
|
567
567
|
}
|
|
568
568
|
}, [onClickStill, onClickVideo, renderDisabled, renderMode]);
|
|
569
569
|
(0, react_1.useEffect)(() => {
|
|
570
|
-
registerKeybinding({
|
|
570
|
+
const enter = registerKeybinding({
|
|
571
571
|
callback() {
|
|
572
572
|
trigger();
|
|
573
573
|
},
|
|
@@ -575,8 +575,11 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
|
|
|
575
575
|
key: 'Enter',
|
|
576
576
|
event: 'keydown',
|
|
577
577
|
preventDefault: true,
|
|
578
|
-
triggerIfInputFieldFocused:
|
|
578
|
+
triggerIfInputFieldFocused: true,
|
|
579
579
|
});
|
|
580
|
+
return () => {
|
|
581
|
+
enter.unregister();
|
|
582
|
+
};
|
|
580
583
|
}, [registerKeybinding, trigger]);
|
|
581
584
|
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: {
|
|
582
585
|
...buttonStyle,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { Codec, ProResProfile } from '@remotion/renderer';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import type { TCompMetadata } from 'remotion';
|
|
4
|
-
import type { AnyZodObject } from 'zod';
|
|
5
3
|
import type { SegmentedControlItem } from '../SegmentedControl';
|
|
6
4
|
import type { RenderType } from './RenderModalAdvanced';
|
|
5
|
+
import type { VideoConfig } from 'remotion';
|
|
7
6
|
export declare const RenderModalBasic: React.FC<{
|
|
8
7
|
renderMode: RenderType;
|
|
9
8
|
imageFormatOptions: SegmentedControlItem[];
|
|
@@ -14,7 +13,7 @@ export declare const RenderModalBasic: React.FC<{
|
|
|
14
13
|
setProResProfile: React.Dispatch<React.SetStateAction<ProResProfile>>;
|
|
15
14
|
frame: number;
|
|
16
15
|
setFrame: React.Dispatch<React.SetStateAction<number>>;
|
|
17
|
-
resolvedComposition:
|
|
16
|
+
resolvedComposition: VideoConfig;
|
|
18
17
|
setOutName: (value: React.SetStateAction<string>) => void;
|
|
19
18
|
setEndFrame: React.Dispatch<React.SetStateAction<number | null>>;
|
|
20
19
|
startFrame: number;
|
|
@@ -32,9 +32,7 @@ const errorContainer = {
|
|
|
32
32
|
overflowY: 'auto',
|
|
33
33
|
};
|
|
34
34
|
const openDocs = () => {
|
|
35
|
-
window.open(
|
|
36
|
-
// TODO: Make sure to update this link when we release v4
|
|
37
|
-
'https://v4.remotion.dev/docs/parametrized-rendering#define-a-schema-');
|
|
35
|
+
window.open('https://www.remotion.dev/docs/parameterized-rendering#define-a-schema-');
|
|
38
36
|
};
|
|
39
37
|
const ZodNotInstalled = () => {
|
|
40
38
|
return ((0, jsx_runtime_1.jsxs)("div", { style: explainer, children: [(0, jsx_runtime_1.jsxs)("div", { style: errorExplanation, children: ["Install ", (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "zod" }), " as a dependency to interactively control the props of the composition."] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 2, block: true }), (0, jsx_runtime_1.jsx)(Button_1.Button, { onClick: openDocs, children: "Learn how" })] }));
|
|
@@ -27,7 +27,6 @@ const ZodSwitch = ({ schema, jsonPath, value, setValue, defaultValue, onSave, sh
|
|
|
27
27
|
throw new Error('expected zod');
|
|
28
28
|
}
|
|
29
29
|
const zodTypes = (0, get_zod_if_possible_1.useZodTypesIfPossible)();
|
|
30
|
-
// TODO: (Maybe?) enable saving of inserted input props by cmd+s /ctrl + s (also for JSON view)
|
|
31
30
|
if (typeName === z.ZodFirstPartyTypeKind.ZodObject) {
|
|
32
31
|
return ((0, jsx_runtime_1.jsx)(ZodObjectEditor_1.ZodObjectEditor, { setValue: setValue, value: value, defaultValue: defaultValue, jsonPath: jsonPath, schema: schema, onSave: onSave, showSaveButton: showSaveButton, onRemove: onRemove, saving: saving, saveDisabledByParent: saveDisabledByParent, mayPad: mayPad }));
|
|
33
32
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Codec } from '@remotion/renderer';
|
|
2
|
-
export declare const humanReadableCodec: (codec: Codec) => "
|
|
2
|
+
export declare const humanReadableCodec: (codec: Codec) => "GIF" | "AAC" | "MP3" | "H.264" | "H.264 Matroska" | "H.265" | "ProRes" | "WebM VP8" | "WebM VP9" | "Waveform" | undefined;
|
|
@@ -4,16 +4,17 @@ exports.SetTimelineInOutProvider = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const in_out_1 = require("../state/in-out");
|
|
7
|
+
const marks_1 = require("../state/marks");
|
|
7
8
|
const SetTimelineInOutProvider = ({ children }) => {
|
|
8
|
-
const [inAndOutFrames, setInAndOutFrames] = (0, react_1.useState)(
|
|
9
|
-
inFrame: null,
|
|
10
|
-
outFrame: null,
|
|
11
|
-
});
|
|
9
|
+
const [inAndOutFrames, setInAndOutFrames] = (0, react_1.useState)(() => (0, marks_1.loadMarks)());
|
|
12
10
|
const setTimelineInOutContextValue = (0, react_1.useMemo)(() => {
|
|
13
11
|
return {
|
|
14
12
|
setInAndOutFrames,
|
|
15
13
|
};
|
|
16
14
|
}, []);
|
|
15
|
+
(0, react_1.useEffect)(() => {
|
|
16
|
+
(0, marks_1.persistMarks)(inAndOutFrames);
|
|
17
|
+
}, [inAndOutFrames]);
|
|
17
18
|
return ((0, jsx_runtime_1.jsx)(in_out_1.TimelineInOutContext.Provider, { value: inAndOutFrames, children: (0, jsx_runtime_1.jsx)(in_out_1.SetTimelineInOutContext.Provider, { value: setTimelineInOutContextValue, children: children }) }));
|
|
18
19
|
};
|
|
19
20
|
exports.SetTimelineInOutProvider = SetTimelineInOutProvider;
|
|
@@ -22,7 +22,9 @@ const SidebarRenderButton = ({ composition, visible }) => {
|
|
|
22
22
|
}, []);
|
|
23
23
|
const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).type;
|
|
24
24
|
const { props } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
|
|
25
|
-
const isVideo = composition.durationInFrames
|
|
25
|
+
const isVideo = typeof composition.durationInFrames === 'undefined'
|
|
26
|
+
? true
|
|
27
|
+
: composition.durationInFrames > 1;
|
|
26
28
|
const onClick = (0, react_1.useCallback)((e) => {
|
|
27
29
|
var _a;
|
|
28
30
|
const defaults = window.remotion_renderDefaults;
|
|
@@ -9,7 +9,6 @@ const get_left_of_timeline_slider_1 = require("../../helpers/get-left-of-timelin
|
|
|
9
9
|
const timeline_layout_1 = require("../../helpers/timeline-layout");
|
|
10
10
|
const in_out_1 = require("../../state/in-out");
|
|
11
11
|
const timeline_zoom_1 = require("../../state/timeline-zoom");
|
|
12
|
-
const FramePersistor_1 = require("../FramePersistor");
|
|
13
12
|
const is_menu_item_1 = require("../Menu/is-menu-item");
|
|
14
13
|
const timeline_refs_1 = require("./timeline-refs");
|
|
15
14
|
const timeline_scroll_logic_1 = require("./timeline-scroll-logic");
|
|
@@ -17,6 +16,7 @@ const TimelineInOutPointer_1 = require("./TimelineInOutPointer");
|
|
|
17
16
|
const TimelineInOutPointerHandle_1 = require("./TimelineInOutPointerHandle");
|
|
18
17
|
const TimelineSlider_1 = require("./TimelineSlider");
|
|
19
18
|
const TimelineWidthProvider_1 = require("./TimelineWidthProvider");
|
|
19
|
+
const TimelineInOutToggle_1 = require("../TimelineInOutToggle");
|
|
20
20
|
const inner = {
|
|
21
21
|
overflowY: 'auto',
|
|
22
22
|
overflowX: 'hidden',
|
|
@@ -50,6 +50,7 @@ const Inner = () => {
|
|
|
50
50
|
triggerOnWindowResize: true,
|
|
51
51
|
shouldApplyCssTransforms: true,
|
|
52
52
|
});
|
|
53
|
+
const setFrame = remotion_1.Internals.useTimelineSetFrame();
|
|
53
54
|
const [inOutDragging, setInOutDragging] = (0, react_1.useState)({
|
|
54
55
|
dragging: false,
|
|
55
56
|
});
|
|
@@ -254,11 +255,12 @@ const Inner = () => {
|
|
|
254
255
|
width,
|
|
255
256
|
extrapolate: 'clamp',
|
|
256
257
|
});
|
|
257
|
-
(
|
|
258
|
+
remotion_1.Internals.persistCurrentFrame(frame, videoConfig.id);
|
|
259
|
+
setFrame((c) => ({ ...c, [videoConfig.id]: frame }));
|
|
258
260
|
if (dragging.wasPlaying) {
|
|
259
261
|
play();
|
|
260
262
|
}
|
|
261
|
-
}, [dragging, left, play, videoConfig, width]);
|
|
263
|
+
}, [dragging, left, play, videoConfig, setFrame, width]);
|
|
262
264
|
const onPointerUpInOut = (0, react_1.useCallback)((e) => {
|
|
263
265
|
if (!videoConfig) {
|
|
264
266
|
return;
|
|
@@ -277,29 +279,53 @@ const Inner = () => {
|
|
|
277
279
|
});
|
|
278
280
|
if (inOutDragging.dragging === 'in') {
|
|
279
281
|
if (frame < 1) {
|
|
280
|
-
return setInAndOutFrames((prev) =>
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
282
|
+
return setInAndOutFrames((prev) => {
|
|
283
|
+
var _a;
|
|
284
|
+
return ({
|
|
285
|
+
...prev,
|
|
286
|
+
[videoConfig.id]: {
|
|
287
|
+
...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
|
|
288
|
+
inFrame: null,
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
});
|
|
284
292
|
}
|
|
285
293
|
const maxFrame = outFrame === null ? Infinity : outFrame - 1;
|
|
286
|
-
setInAndOutFrames((prev) =>
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
setInAndOutFrames((prev) => {
|
|
295
|
+
var _a;
|
|
296
|
+
return ({
|
|
297
|
+
...prev,
|
|
298
|
+
[videoConfig.id]: {
|
|
299
|
+
...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
|
|
300
|
+
inFrame: Math.min(maxFrame, frame),
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
});
|
|
290
304
|
}
|
|
291
305
|
else {
|
|
292
306
|
if (frame > videoConfig.durationInFrames - 2) {
|
|
293
|
-
return setInAndOutFrames((prev) =>
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
307
|
+
return setInAndOutFrames((prev) => {
|
|
308
|
+
var _a;
|
|
309
|
+
return ({
|
|
310
|
+
...prev,
|
|
311
|
+
[videoConfig.id]: {
|
|
312
|
+
...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
|
|
313
|
+
outFrame: null,
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
});
|
|
297
317
|
}
|
|
298
318
|
const minFrame = inFrame === null ? -Infinity : inFrame + 1;
|
|
299
|
-
setInAndOutFrames((prev) =>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
319
|
+
setInAndOutFrames((prev) => {
|
|
320
|
+
var _a;
|
|
321
|
+
return ({
|
|
322
|
+
...prev,
|
|
323
|
+
[videoConfig.id]: {
|
|
324
|
+
...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : TimelineInOutToggle_1.defaultInOutValue),
|
|
325
|
+
outFrame: Math.max(minFrame, frame),
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
});
|
|
303
329
|
}
|
|
304
330
|
}, [
|
|
305
331
|
inFrame,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { InOutValue } from '../state/in-out';
|
|
2
3
|
export declare const inOutHandles: React.RefObject<{
|
|
3
4
|
inMarkClick: (e: KeyboardEvent | null) => void;
|
|
4
5
|
outMarkClick: (e: KeyboardEvent | null) => void;
|
|
5
6
|
clearMarks: () => void;
|
|
6
|
-
setMarks: (marks: [number | null, number | null]) => void;
|
|
7
7
|
}>;
|
|
8
|
+
export declare const defaultInOutValue: InOutValue;
|
|
8
9
|
export declare const TimelineInOutPointToggle: React.FC;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TimelineInOutPointToggle = exports.inOutHandles = void 0;
|
|
3
|
+
exports.TimelineInOutPointToggle = exports.defaultInOutValue = exports.inOutHandles = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const remotion_1 = require("remotion");
|
|
@@ -10,7 +10,6 @@ const is_current_selected_still_1 = require("../helpers/is-current-selected-stil
|
|
|
10
10
|
const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
11
11
|
const timelineInOutPointer_1 = require("../icons/timelineInOutPointer");
|
|
12
12
|
const in_out_1 = require("../state/in-out");
|
|
13
|
-
const marks_1 = require("../state/marks");
|
|
14
13
|
const ControlButton_1 = require("./ControlButton");
|
|
15
14
|
const getTooltipText = (pointType, key) => [
|
|
16
15
|
`Mark ${pointType}`,
|
|
@@ -24,19 +23,22 @@ const style = {
|
|
|
24
23
|
height: 16,
|
|
25
24
|
};
|
|
26
25
|
exports.inOutHandles = (0, react_1.createRef)();
|
|
26
|
+
exports.defaultInOutValue = { inFrame: null, outFrame: null };
|
|
27
27
|
const TimelineInOutPointToggle = () => {
|
|
28
28
|
const timelinePosition = remotion_1.Internals.Timeline.useTimelinePosition();
|
|
29
29
|
const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
|
|
30
30
|
const { setInAndOutFrames } = (0, in_out_1.useTimelineSetInOutFramePosition)();
|
|
31
|
-
const { currentComposition } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
|
|
32
31
|
const isStill = (0, is_current_selected_still_1.useIsStill)();
|
|
33
32
|
const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
|
|
34
33
|
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
|
35
|
-
const onInOutClear = (0, react_1.useCallback)(() => {
|
|
36
|
-
setInAndOutFrames(() => {
|
|
34
|
+
const onInOutClear = (0, react_1.useCallback)((composition) => {
|
|
35
|
+
setInAndOutFrames((prev) => {
|
|
37
36
|
return {
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
...prev,
|
|
38
|
+
[composition]: {
|
|
39
|
+
inFrame: null,
|
|
40
|
+
outFrame: null,
|
|
41
|
+
},
|
|
40
42
|
};
|
|
41
43
|
});
|
|
42
44
|
}, [setInAndOutFrames]);
|
|
@@ -45,35 +47,51 @@ const TimelineInOutPointToggle = () => {
|
|
|
45
47
|
return null;
|
|
46
48
|
}
|
|
47
49
|
if (e === null || e === void 0 ? void 0 : e.shiftKey) {
|
|
48
|
-
setInAndOutFrames((
|
|
50
|
+
setInAndOutFrames((prev) => {
|
|
51
|
+
var _a;
|
|
49
52
|
return {
|
|
50
|
-
...
|
|
51
|
-
|
|
53
|
+
...prev,
|
|
54
|
+
[videoConfig.id]: {
|
|
55
|
+
...((_a = prev[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
|
|
56
|
+
inFrame: null,
|
|
57
|
+
},
|
|
52
58
|
};
|
|
53
59
|
});
|
|
54
60
|
return null;
|
|
55
61
|
}
|
|
56
62
|
setInAndOutFrames((prev) => {
|
|
57
|
-
|
|
63
|
+
var _a, _b, _c, _d, _e;
|
|
64
|
+
const prevOut = (_a = prev[videoConfig.id]) === null || _a === void 0 ? void 0 : _a.outFrame;
|
|
65
|
+
const biggestPossible = prevOut === undefined || prevOut === null ? Infinity : prevOut - 1;
|
|
58
66
|
const selected = Math.min(timelinePosition, biggestPossible);
|
|
59
67
|
if (selected === 0) {
|
|
60
68
|
return {
|
|
61
69
|
...prev,
|
|
62
|
-
|
|
70
|
+
[videoConfig.id]: {
|
|
71
|
+
...((_b = prev[videoConfig.id]) !== null && _b !== void 0 ? _b : exports.defaultInOutValue),
|
|
72
|
+
inFrame: null,
|
|
73
|
+
},
|
|
63
74
|
};
|
|
64
75
|
}
|
|
65
|
-
|
|
76
|
+
const prevIn = (_c = prev[videoConfig.id]) === null || _c === void 0 ? void 0 : _c.inFrame;
|
|
77
|
+
if (prevIn !== null && prevIn !== undefined) {
|
|
66
78
|
// Disable if already at this position
|
|
67
|
-
if (
|
|
79
|
+
if (prevIn === selected) {
|
|
68
80
|
return {
|
|
69
81
|
...prev,
|
|
70
|
-
|
|
82
|
+
[videoConfig.id]: {
|
|
83
|
+
...((_d = prev[videoConfig.id]) !== null && _d !== void 0 ? _d : exports.defaultInOutValue),
|
|
84
|
+
inFrame: null,
|
|
85
|
+
},
|
|
71
86
|
};
|
|
72
87
|
}
|
|
73
88
|
}
|
|
74
89
|
return {
|
|
75
90
|
...prev,
|
|
76
|
-
|
|
91
|
+
[videoConfig.id]: {
|
|
92
|
+
...((_e = prev[videoConfig.id]) !== null && _e !== void 0 ? _e : exports.defaultInOutValue),
|
|
93
|
+
inFrame: selected,
|
|
94
|
+
},
|
|
77
95
|
};
|
|
78
96
|
});
|
|
79
97
|
}, [setInAndOutFrames, timelinePosition, videoConfig]);
|
|
@@ -83,9 +101,13 @@ const TimelineInOutPointToggle = () => {
|
|
|
83
101
|
}
|
|
84
102
|
e.preventDefault();
|
|
85
103
|
setInAndOutFrames((f) => {
|
|
104
|
+
var _a;
|
|
86
105
|
return {
|
|
87
106
|
...f,
|
|
88
|
-
|
|
107
|
+
[videoConfig.id]: {
|
|
108
|
+
...((_a = f[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
|
|
109
|
+
inFrame: null,
|
|
110
|
+
},
|
|
89
111
|
};
|
|
90
112
|
});
|
|
91
113
|
}, [setInAndOutFrames, videoConfig]);
|
|
@@ -95,9 +117,13 @@ const TimelineInOutPointToggle = () => {
|
|
|
95
117
|
}
|
|
96
118
|
e === null || e === void 0 ? void 0 : e.preventDefault();
|
|
97
119
|
setInAndOutFrames((f) => {
|
|
120
|
+
var _a;
|
|
98
121
|
return {
|
|
99
122
|
...f,
|
|
100
|
-
|
|
123
|
+
[videoConfig.id]: {
|
|
124
|
+
...((_a = f[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
|
|
125
|
+
outFrame: null,
|
|
126
|
+
},
|
|
101
127
|
};
|
|
102
128
|
});
|
|
103
129
|
}, [setInAndOutFrames, videoConfig]);
|
|
@@ -107,37 +133,59 @@ const TimelineInOutPointToggle = () => {
|
|
|
107
133
|
}
|
|
108
134
|
if (e === null || e === void 0 ? void 0 : e.shiftKey) {
|
|
109
135
|
setInAndOutFrames((f) => {
|
|
136
|
+
var _a;
|
|
110
137
|
return {
|
|
111
138
|
...f,
|
|
112
|
-
|
|
139
|
+
[videoConfig.id]: {
|
|
140
|
+
...((_a = f[videoConfig.id]) !== null && _a !== void 0 ? _a : exports.defaultInOutValue),
|
|
141
|
+
outFrame: null,
|
|
142
|
+
},
|
|
113
143
|
};
|
|
114
144
|
});
|
|
115
145
|
return;
|
|
116
146
|
}
|
|
117
147
|
setInAndOutFrames((prev) => {
|
|
118
|
-
|
|
148
|
+
var _a, _b, _c, _d, _e;
|
|
149
|
+
const prevInFrame = (_a = prev[videoConfig.id]) === null || _a === void 0 ? void 0 : _a.inFrame;
|
|
150
|
+
const smallestPossible = prevInFrame === null || prevInFrame === undefined
|
|
151
|
+
? -Infinity
|
|
152
|
+
: prevInFrame + 1;
|
|
119
153
|
const selected = Math.max(timelinePosition, smallestPossible);
|
|
120
154
|
if (selected === videoConfig.durationInFrames - 1) {
|
|
121
155
|
return {
|
|
122
156
|
...prev,
|
|
123
|
-
|
|
157
|
+
[videoConfig.id]: {
|
|
158
|
+
...((_b = prev[videoConfig.id]) !== null && _b !== void 0 ? _b : exports.defaultInOutValue),
|
|
159
|
+
outFrame: null,
|
|
160
|
+
},
|
|
124
161
|
};
|
|
125
162
|
}
|
|
126
|
-
|
|
127
|
-
|
|
163
|
+
const prevOut = (_c = prev[videoConfig.id]) === null || _c === void 0 ? void 0 : _c.outFrame;
|
|
164
|
+
if (prevOut !== null && prevOut !== undefined) {
|
|
165
|
+
if (prevOut === selected) {
|
|
128
166
|
return {
|
|
129
167
|
...prev,
|
|
130
|
-
|
|
168
|
+
[videoConfig.id]: {
|
|
169
|
+
...((_d = prev[videoConfig.id]) !== null && _d !== void 0 ? _d : exports.defaultInOutValue),
|
|
170
|
+
outFrame: null,
|
|
171
|
+
},
|
|
131
172
|
};
|
|
132
173
|
}
|
|
133
174
|
}
|
|
134
175
|
return {
|
|
135
176
|
...prev,
|
|
136
|
-
|
|
177
|
+
[videoConfig.id]: {
|
|
178
|
+
...((_e = prev[videoConfig.id]) !== null && _e !== void 0 ? _e : exports.defaultInOutValue),
|
|
179
|
+
outFrame: selected,
|
|
180
|
+
},
|
|
137
181
|
};
|
|
138
182
|
});
|
|
139
183
|
}, [setInAndOutFrames, timelinePosition, videoConfig]);
|
|
184
|
+
const confId = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.id;
|
|
140
185
|
(0, react_1.useEffect)(() => {
|
|
186
|
+
if (!confId) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
141
189
|
const iKey = keybindings.registerKeybinding({
|
|
142
190
|
event: 'keypress',
|
|
143
191
|
key: 'i',
|
|
@@ -162,7 +210,7 @@ const TimelineInOutPointToggle = () => {
|
|
|
162
210
|
event: 'keypress',
|
|
163
211
|
key: 'x',
|
|
164
212
|
callback: () => {
|
|
165
|
-
onInOutClear();
|
|
213
|
+
onInOutClear(confId);
|
|
166
214
|
},
|
|
167
215
|
commandCtrlKey: false,
|
|
168
216
|
preventDefault: true,
|
|
@@ -173,52 +221,19 @@ const TimelineInOutPointToggle = () => {
|
|
|
173
221
|
iKey.unregister();
|
|
174
222
|
xKey.unregister();
|
|
175
223
|
};
|
|
176
|
-
}, [keybindings, onInMark, onInOutClear, onOutMark]);
|
|
177
|
-
(0, react_1.useEffect)(() => {
|
|
178
|
-
if (!currentComposition || !videoConfig) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
(0, marks_1.persistMarks)(currentComposition, videoConfig.durationInFrames, [
|
|
182
|
-
inFrame,
|
|
183
|
-
outFrame,
|
|
184
|
-
]);
|
|
185
|
-
}, [currentComposition, inFrame, outFrame, videoConfig]);
|
|
186
|
-
// If duration changes and it goes out of range, we reset
|
|
187
|
-
(0, react_1.useEffect)(() => {
|
|
188
|
-
if (outFrame === null) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (!videoConfig) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
if (outFrame >= videoConfig.durationInFrames - 1) {
|
|
195
|
-
onInOutClear();
|
|
196
|
-
}
|
|
197
|
-
}, [onInOutClear, outFrame, videoConfig]);
|
|
198
|
-
(0, react_1.useEffect)(() => {
|
|
199
|
-
if (inFrame === null) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (!videoConfig) {
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (inFrame >= videoConfig.durationInFrames - 1) {
|
|
206
|
-
onInOutClear();
|
|
207
|
-
}
|
|
208
|
-
}, [onInOutClear, inFrame, videoConfig]);
|
|
224
|
+
}, [confId, keybindings, onInMark, onInOutClear, onOutMark]);
|
|
209
225
|
(0, react_1.useImperativeHandle)(exports.inOutHandles, () => {
|
|
210
226
|
return {
|
|
211
|
-
clearMarks:
|
|
227
|
+
clearMarks: () => {
|
|
228
|
+
if (!confId) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
onInOutClear(confId);
|
|
232
|
+
},
|
|
212
233
|
inMarkClick: onInMark,
|
|
213
234
|
outMarkClick: onOutMark,
|
|
214
|
-
setMarks: ([newInFrame, newOutFrame]) => {
|
|
215
|
-
setInAndOutFrames({
|
|
216
|
-
inFrame: newInFrame,
|
|
217
|
-
outFrame: newOutFrame,
|
|
218
|
-
});
|
|
219
|
-
},
|
|
220
235
|
};
|
|
221
|
-
}, [onInMark, onInOutClear, onOutMark
|
|
236
|
+
}, [confId, onInMark, onInOutClear, onOutMark]);
|
|
222
237
|
if (isStill) {
|
|
223
238
|
return null;
|
|
224
239
|
}
|
|
@@ -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" | "hsla(0, 0%, 100%, 0.15)" | "
|
|
19
|
+
}) => "transparent" | "hsla(0, 0%, 100%, 0.15)" | "hsla(0, 0%, 100%, 0.25)" | "rgba(255, 255, 255, 0.06)";
|
|
@@ -13,16 +13,15 @@ const useIsStill = () => {
|
|
|
13
13
|
};
|
|
14
14
|
exports.useIsStill = useIsStill;
|
|
15
15
|
const useDimensions = () => {
|
|
16
|
-
const
|
|
17
|
-
const selected = (0, react_1.useMemo)(() => compositions.find((c) => c.id === currentComposition), [compositions, currentComposition]);
|
|
16
|
+
const config = remotion_1.Internals.useUnsafeVideoConfig();
|
|
18
17
|
return (0, react_1.useMemo)(() => {
|
|
19
|
-
if (!
|
|
18
|
+
if (!config) {
|
|
20
19
|
return null;
|
|
21
20
|
}
|
|
22
21
|
return {
|
|
23
|
-
width:
|
|
24
|
-
height:
|
|
22
|
+
width: config.width,
|
|
23
|
+
height: config.height,
|
|
25
24
|
};
|
|
26
|
-
}, [
|
|
25
|
+
}, [config]);
|
|
27
26
|
};
|
|
28
27
|
exports.useDimensions = useDimensions;
|
|
@@ -4,6 +4,7 @@ exports.ArrowRight = exports.ArrowLeft = exports.ShiftIcon = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const iconStyle = {
|
|
6
6
|
width: 10,
|
|
7
|
+
display: 'inline',
|
|
7
8
|
};
|
|
8
9
|
const ShiftIcon = () => {
|
|
9
10
|
return ((0, jsx_runtime_1.jsx)("svg", { style: iconStyle, viewBox: "0 0 448 512", children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "M48.048 304h73.798v128c0 26.51 21.49 48 48 48h108.308c26.51 0 48-21.49 48-48V304h73.789c42.638 0 64.151-51.731 33.941-81.941l-175.943-176c-18.745-18.745-49.137-18.746-67.882 0l-175.952 176C-16.042 252.208 5.325 304 48.048 304zM224 80l176 176H278.154v176H169.846V256H48L224 80z" }) }));
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
-
export type
|
|
2
|
+
export type InOutValue = {
|
|
3
3
|
inFrame: number | null;
|
|
4
4
|
outFrame: number | null;
|
|
5
5
|
};
|
|
6
|
+
export type TimelineInOutContextValue = Record<string, InOutValue>;
|
|
6
7
|
export type SetTimelineInOutContextValue = {
|
|
7
8
|
setInAndOutFrames: (u: React.SetStateAction<TimelineInOutContextValue>) => void;
|
|
8
9
|
};
|
|
9
10
|
export declare const TimelineInOutContext: React.Context<TimelineInOutContextValue>;
|
|
10
11
|
export declare const SetTimelineInOutContext: React.Context<SetTimelineInOutContextValue>;
|
|
11
|
-
export declare const useTimelineInOutFramePosition: () =>
|
|
12
|
+
export declare const useTimelineInOutFramePosition: () => InOutValue;
|
|
12
13
|
export declare const useTimelineSetInOutFramePosition: () => SetTimelineInOutContextValue;
|
|
@@ -2,18 +2,35 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useTimelineSetInOutFramePosition = exports.useTimelineInOutFramePosition = exports.SetTimelineInOutContext = exports.TimelineInOutContext = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
outFrame: null,
|
|
8
|
-
});
|
|
5
|
+
const remotion_1 = require("remotion");
|
|
6
|
+
exports.TimelineInOutContext = (0, react_1.createContext)({});
|
|
9
7
|
exports.SetTimelineInOutContext = (0, react_1.createContext)({
|
|
10
8
|
setInAndOutFrames: () => {
|
|
11
9
|
throw new Error('default');
|
|
12
10
|
},
|
|
13
11
|
});
|
|
14
12
|
const useTimelineInOutFramePosition = () => {
|
|
13
|
+
var _a, _b, _c, _d;
|
|
14
|
+
const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
|
|
15
15
|
const state = (0, react_1.useContext)(exports.TimelineInOutContext);
|
|
16
|
-
|
|
16
|
+
if (!videoConfig) {
|
|
17
|
+
return { inFrame: null, outFrame: null };
|
|
18
|
+
}
|
|
19
|
+
const maxFrame = videoConfig.durationInFrames - 1;
|
|
20
|
+
const actualInFrame = (_b = (_a = state[videoConfig.id]) === null || _a === void 0 ? void 0 : _a.inFrame) !== null && _b !== void 0 ? _b : null;
|
|
21
|
+
const actualOutFrame = (_d = (_c = state[videoConfig.id]) === null || _c === void 0 ? void 0 : _c.outFrame) !== null && _d !== void 0 ? _d : null;
|
|
22
|
+
return {
|
|
23
|
+
inFrame: actualInFrame === null
|
|
24
|
+
? null
|
|
25
|
+
: actualInFrame >= maxFrame
|
|
26
|
+
? null
|
|
27
|
+
: actualInFrame,
|
|
28
|
+
outFrame: actualOutFrame === null
|
|
29
|
+
? null
|
|
30
|
+
: actualOutFrame >= maxFrame
|
|
31
|
+
? null
|
|
32
|
+
: actualOutFrame,
|
|
33
|
+
};
|
|
17
34
|
};
|
|
18
35
|
exports.useTimelineInOutFramePosition = useTimelineInOutFramePosition;
|
|
19
36
|
const useTimelineSetInOutFramePosition = () => {
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const
|
|
1
|
+
import type { TimelineInOutContextValue } from './in-out';
|
|
2
|
+
export declare const persistMarks: (marks: TimelineInOutContextValue) => void;
|
|
3
|
+
export declare const loadMarks: () => TimelineInOutContextValue;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.loadMarks = exports.persistMarks = void 0;
|
|
4
|
-
const localStorageKey = (
|
|
5
|
-
const persistMarks = (
|
|
6
|
-
localStorage.setItem(localStorageKey(
|
|
4
|
+
const localStorageKey = () => `remotion.editor.marksv2`;
|
|
5
|
+
const persistMarks = (marks) => {
|
|
6
|
+
localStorage.setItem(localStorageKey(), JSON.stringify(marks));
|
|
7
7
|
};
|
|
8
8
|
exports.persistMarks = persistMarks;
|
|
9
|
-
const loadMarks = (
|
|
10
|
-
const item = localStorage.getItem(localStorageKey(
|
|
9
|
+
const loadMarks = () => {
|
|
10
|
+
const item = localStorage.getItem(localStorageKey());
|
|
11
11
|
if (item === null) {
|
|
12
|
-
return
|
|
12
|
+
return {};
|
|
13
13
|
}
|
|
14
14
|
return JSON.parse(item);
|
|
15
15
|
};
|
|
@@ -52,5 +52,9 @@ const handleCommonError = async (err, logLevel) => {
|
|
|
52
52
|
log_1.Log.info('💡 Remotion requires at least Libc 2.34.');
|
|
53
53
|
log_1.Log.info('💡 Get help for this issue: https://github.com/remotion-dev/remotion/issues/2439');
|
|
54
54
|
}
|
|
55
|
+
if (err.message.includes('EBADF')) {
|
|
56
|
+
log_1.Log.info('💡 This error might be fixed by changing your Node version:');
|
|
57
|
+
log_1.Log.info(' https://github.com/remotion-dev/remotion/issues/2452');
|
|
58
|
+
}
|
|
55
59
|
};
|
|
56
60
|
exports.handleCommonError = handleCommonError;
|
package/dist/index.d.ts
CHANGED
|
@@ -112,7 +112,7 @@ export declare const CliInternals: {
|
|
|
112
112
|
videoBitrate: string | null;
|
|
113
113
|
height: number | null;
|
|
114
114
|
width: number | null;
|
|
115
|
-
configFileImageFormat: "
|
|
115
|
+
configFileImageFormat: "png" | "jpeg" | "none" | undefined;
|
|
116
116
|
}>;
|
|
117
117
|
loadConfig: (remotionRoot: string) => Promise<string | null>;
|
|
118
118
|
initializeCli: (remotionRoot: string) => Promise<void>;
|
|
@@ -121,7 +121,7 @@ export declare const CliInternals: {
|
|
|
121
121
|
parsedCli: {
|
|
122
122
|
"browser-executable": import("@remotion/renderer").BrowserExecutable;
|
|
123
123
|
"pixel-format": "yuv420p" | "yuva420p" | "yuv422p" | "yuv444p" | "yuv420p10le" | "yuv422p10le" | "yuv444p10le" | "yuva444p10le";
|
|
124
|
-
"image-format": "
|
|
124
|
+
"image-format": "png" | "jpeg" | "pdf" | "webp" | "none";
|
|
125
125
|
"prores-profile": "4444-xq" | "4444" | "hq" | "standard" | "light" | "proxy";
|
|
126
126
|
"bundle-cache": string;
|
|
127
127
|
"env-file": string;
|
|
@@ -185,7 +185,7 @@ export declare const CliInternals: {
|
|
|
185
185
|
downloadName: string | null;
|
|
186
186
|
outName: string | null;
|
|
187
187
|
configImageFormat: "png" | "jpeg" | "pdf" | "webp" | null;
|
|
188
|
-
cliFlag: "
|
|
188
|
+
cliFlag: "png" | "jpeg" | "pdf" | "webp" | "none" | null;
|
|
189
189
|
isLambda: boolean;
|
|
190
190
|
fromUi: "png" | "jpeg" | "pdf" | "webp" | null;
|
|
191
191
|
}) => {
|
|
@@ -200,9 +200,9 @@ export declare const CliInternals: {
|
|
|
200
200
|
};
|
|
201
201
|
getVideoImageFormat: ({ codec, uiImageFormat, }: {
|
|
202
202
|
codec: import("@remotion/renderer").CodecOrUndefined;
|
|
203
|
-
uiImageFormat: "
|
|
204
|
-
}) => "
|
|
205
|
-
printCompositions: (compositions: import("remotion").
|
|
203
|
+
uiImageFormat: "png" | "jpeg" | "none" | null;
|
|
204
|
+
}) => "png" | "jpeg" | "none";
|
|
205
|
+
printCompositions: (compositions: import("remotion").VideoConfig[]) => void;
|
|
206
206
|
getFinalOutputCodec: ({ cliFlag, configFile, downloadName, outName, uiCodec, }: {
|
|
207
207
|
cliFlag: import("@remotion/renderer").CodecOrUndefined;
|
|
208
208
|
outName: string | null;
|
|
@@ -88,7 +88,7 @@ const parseCommandLine = () => {
|
|
|
88
88
|
config_1.ConfigInternals.setStillFrame(Number(exports.parsedCli.frame));
|
|
89
89
|
}
|
|
90
90
|
if (exports.parsedCli.png) {
|
|
91
|
-
throw new Error('The --png flag has been
|
|
91
|
+
throw new Error('The --png flag has been removed. Use --sequence --image-format=png from now on.');
|
|
92
92
|
}
|
|
93
93
|
if (exports.parsedCli.sequence) {
|
|
94
94
|
config_1.Config.setImageSequence(true);
|
|
@@ -11,5 +11,5 @@ type Range = {
|
|
|
11
11
|
type Ranges = Range[] & {
|
|
12
12
|
type?: string;
|
|
13
13
|
};
|
|
14
|
-
export declare function parseRange(size: number, str: string | string[]): -1 |
|
|
14
|
+
export declare function parseRange(size: number, str: string | string[]): -1 | Ranges | -2;
|
|
15
15
|
export {};
|
|
@@ -13,6 +13,7 @@ const button = {
|
|
|
13
13
|
fontSize: 14,
|
|
14
14
|
color: 'white',
|
|
15
15
|
flexDirection: 'row',
|
|
16
|
+
display: 'flex',
|
|
16
17
|
};
|
|
17
18
|
const ButtonRefForwardFunction = ({ children, onClick, title, disabled, style, id, autoFocus, buttonContainerStyle, }, ref) => {
|
|
18
19
|
const combined = (0, react_1.useMemo)(() => {
|
|
@@ -14,11 +14,17 @@ const openDirectoryInFinder = (dirToOpen, allowedDirectory) => {
|
|
|
14
14
|
if (relativeToProcessCwd.startsWith('..')) {
|
|
15
15
|
throw new Error(`Not allowed to open ${relativeToProcessCwd}`);
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
if ((0, node_os_1.platform)() === 'win32') {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
(0, node_child_process_1.exec)(`start ${dirToOpen}`, (error) => {
|
|
20
|
+
if (error) {
|
|
21
|
+
reject(error);
|
|
22
|
+
}
|
|
23
|
+
resolve();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const command = (0, node_os_1.platform)() === 'darwin' ? 'open' : 'xdg-open';
|
|
22
28
|
const p = (0, node_child_process_1.spawn)(command, [(0, node_os_1.platform)() === 'darwin' ? '-R' : null, dirToOpen].filter(truthy_1.truthy));
|
|
23
29
|
const stderrChunks = [];
|
|
24
30
|
p.stderr.on('data', (d) => stderrChunks.push(d));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
3
|
import type { LiveEventsServer } from './live-events';
|
|
3
4
|
export declare const handleRoutes: ({ hash, hashPrefix, request, response, liveEventsServer, getCurrentInputProps, getEnvVariables, remotionRoot, entryPoint, publicDir, }: {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const printCompositions: (compositions:
|
|
1
|
+
import type { VideoConfig } from 'remotion';
|
|
2
|
+
export declare const printCompositions: (compositions: VideoConfig[]) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/cli",
|
|
3
|
-
"version": "4.1.0-
|
|
3
|
+
"version": "4.1.0-alpha7",
|
|
4
4
|
"description": "CLI for Remotion",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"minimist": "1.2.6",
|
|
34
34
|
"open": "^8.4.2",
|
|
35
35
|
"prompts": "2.4.1",
|
|
36
|
-
"semver": "7.3
|
|
36
|
+
"semver": "7.5.3",
|
|
37
37
|
"source-map": "0.6.1",
|
|
38
|
-
"@remotion/
|
|
39
|
-
"@remotion/
|
|
40
|
-
"@remotion/
|
|
41
|
-
"@remotion/
|
|
42
|
-
"remotion": "4.1.0-
|
|
38
|
+
"@remotion/bundler": "4.1.0-alpha7",
|
|
39
|
+
"@remotion/media-utils": "4.1.0-alpha7",
|
|
40
|
+
"@remotion/player": "4.1.0-alpha7",
|
|
41
|
+
"@remotion/renderer": "4.1.0-alpha7",
|
|
42
|
+
"remotion": "4.1.0-alpha7"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"react": ">=16.8.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@types/semver": "^7.3.4",
|
|
57
57
|
"eslint": "8.42.0",
|
|
58
58
|
"eslint-plugin-10x": "1.5.2",
|
|
59
|
-
"eslint-plugin-react": "7.
|
|
59
|
+
"eslint-plugin-react": "7.32.2",
|
|
60
60
|
"eslint-plugin-react-hooks": "4.4.0",
|
|
61
61
|
"prettier": "^2.7.1",
|
|
62
62
|
"prettier-plugin-organize-imports": "^2.3.4",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"typescript": "4.9.5",
|
|
66
66
|
"vitest": "0.31.1",
|
|
67
67
|
"zod": "^3.21.4",
|
|
68
|
-
"@remotion/
|
|
69
|
-
"@remotion/
|
|
68
|
+
"@remotion/zod-types": "4.1.0-alpha7",
|
|
69
|
+
"@remotion/tailwind": "4.1.0-alpha7"
|
|
70
70
|
},
|
|
71
71
|
"keywords": [
|
|
72
72
|
"remotion",
|