@remotion/studio 4.0.376 → 4.0.377

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.
@@ -23,7 +23,7 @@ const Modals = ({ readOnlyStudio }) => {
23
23
  const { selectedModal: modalContextType } = (0, react_1.useContext)(modals_1.ModalsContext);
24
24
  const canRender = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).previewServerState.type ===
25
25
  'connected';
26
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'duplicate-comp' && ((0, jsx_runtime_1.jsx)(DuplicateComposition_1.DuplicateComposition, { compositionType: modalContextType.compositionType, compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-comp' && ((0, jsx_runtime_1.jsx)(DeleteComposition_1.DeleteComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'rename-comp' && ((0, jsx_runtime_1.jsx)(RenameComposition_1.RenameComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'input-props-override' && ((0, jsx_runtime_1.jsx)(OverrideInputProps_1.OverrideInputPropsModal, {})), modalContextType && modalContextType.type === 'web-render' && ((0, jsx_runtime_1.jsx)(WebRenderModal_1.WebRenderModalWithLoader, { type: "web-render", initialFrame: modalContextType.initialFrame, compositionId: modalContextType.compositionId, defaultProps: modalContextType.defaultProps })), modalContextType &&
26
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'duplicate-comp' && ((0, jsx_runtime_1.jsx)(DuplicateComposition_1.DuplicateComposition, { compositionType: modalContextType.compositionType, compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-comp' && ((0, jsx_runtime_1.jsx)(DeleteComposition_1.DeleteComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'rename-comp' && ((0, jsx_runtime_1.jsx)(RenameComposition_1.RenameComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'input-props-override' && ((0, jsx_runtime_1.jsx)(OverrideInputProps_1.OverrideInputPropsModal, {})), modalContextType && modalContextType.type === 'web-render' && ((0, jsx_runtime_1.jsx)(WebRenderModal_1.WebRenderModalWithLoader, { type: "web-render", initialFrame: modalContextType.initialFrame, compositionId: modalContextType.compositionId, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark })), modalContextType &&
27
27
  canRender &&
28
28
  modalContextType.type === 'server-render' && ((0, jsx_runtime_1.jsx)(ServerRenderModal_1.RenderModalWithLoader, { initialFrame: modalContextType.initialFrame, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialScale: modalContextType.initialScale, initialLogLevel: modalContextType.initialLogLevel, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, initialOffthreadVideoThreads: modalContextType.initialOffthreadVideoThreads, initialMediaCacheSizeInBytes: modalContextType.initialMediaCacheSizeInBytes, 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, initialEnvVariables: modalContextType.initialEnvVariables, initialDisableWebSecurity: modalContextType.initialDisableWebSecurity, initialGl: modalContextType.initialOpenGlRenderer, initialHeadless: modalContextType.initialHeadless, initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors, initialEncodingBufferSize: modalContextType.initialEncodingBufferSize, initialEncodingMaxRate: modalContextType.initialEncodingMaxRate, initialUserAgent: modalContextType.initialUserAgent, initialColorSpace: modalContextType.initialColorSpace, initialMultiProcessOnLinux: modalContextType.initialMultiProcessOnLinux, initialRepro: modalContextType.initialRepro, initialBeep: modalContextType.initialBeep, initialForSeamlessAacConcatenation: modalContextType.initialForSeamlessAacConcatenation, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark, defaultConfigurationAudioCodec: modalContextType.defaultConfigurationAudioCodec, defaultConfigurationVideoCodec: modalContextType.defaultConfigurationVideoCodec, renderTypeOfLastRender: modalContextType.renderTypeOfLastRender, defaultMetadata: modalContextType.defaulMetadata, initialHardwareAcceleration: modalContextType.initialHardwareAcceleration, initialChromeMode: modalContextType.initialChromeMode, renderDefaults: modalContextType.renderDefaults })), modalContextType &&
29
29
  canRender &&
@@ -68,10 +68,9 @@ const validateOutnameForStill = ({ outName, stillImageFormat, }) => {
68
68
  // TODO: Filter out codecs that are not supported for the container
69
69
  // TODO: Add more containers
70
70
  // TODO: Shortcut: Shift + R
71
- // TODO: Apply initial frame range
72
71
  // TODO: Apply defaultCodec
73
72
  // TODO: Apply defaultOutName
74
- const WebRenderModal = ({ initialFrame, defaultProps, }) => {
73
+ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark, }) => {
75
74
  const context = (0, react_1.useContext)(ResolveCompositionBeforeModal_1.ResolvedCompositionContext);
76
75
  if (!context) {
77
76
  throw new Error('Should not be able to render without resolving comp first');
@@ -92,10 +91,28 @@ const WebRenderModal = ({ initialFrame, defaultProps, }) => {
92
91
  const [videoBitrate, setVideoBitrate] = (0, react_1.useState)('high');
93
92
  const [hardwareAcceleration, setHardwareAcceleration] = (0, react_1.useState)('no-preference');
94
93
  const [keyframeIntervalInSeconds, setKeyframeIntervalInSeconds] = (0, react_1.useState)(5);
95
- const [startFrame, setStartFrame] = (0, react_1.useState)(null);
96
- const [endFrame, setEndFrame] = (0, react_1.useState)(null);
94
+ const [startFrame, setStartFrame] = (0, react_1.useState)(() => inFrameMark !== null && inFrameMark !== void 0 ? inFrameMark : null);
95
+ const [endFrame, setEndFrame] = (0, react_1.useState)(() => outFrameMark !== null && outFrameMark !== void 0 ? outFrameMark : null);
97
96
  const [renderProgress, setRenderProgress] = (0, react_1.useState)(null);
98
97
  const [transparent, setTransparent] = (0, react_1.useState)(false);
98
+ const finalEndFrame = (0, react_1.useMemo)(() => {
99
+ if (endFrame === null) {
100
+ return resolvedComposition.durationInFrames - 1;
101
+ }
102
+ return Math.max(0, Math.min(resolvedComposition.durationInFrames - 1, endFrame));
103
+ }, [endFrame, resolvedComposition.durationInFrames]);
104
+ const finalStartFrame = (0, react_1.useMemo)(() => {
105
+ if (startFrame === null) {
106
+ return 0;
107
+ }
108
+ return Math.max(0, Math.min(finalEndFrame, startFrame));
109
+ }, [finalEndFrame, startFrame]);
110
+ const frameRange = (0, react_1.useMemo)(() => {
111
+ if (startFrame === null && endFrame === null) {
112
+ return null;
113
+ }
114
+ return [finalStartFrame, finalEndFrame];
115
+ }, [endFrame, finalEndFrame, finalStartFrame, startFrame]);
99
116
  const [initialOutName] = (0, react_1.useState)(() => {
100
117
  return (0, studio_shared_1.getDefaultOutLocation)({
101
118
  compositionName: resolvedComposition.id,
@@ -285,12 +302,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, }) => {
285
302
  videoBitrate,
286
303
  hardwareAcceleration,
287
304
  keyframeIntervalInSeconds,
288
- frameRange: startFrame !== null || endFrame !== null
289
- ? [
290
- startFrame !== null && startFrame !== void 0 ? startFrame : 0,
291
- endFrame !== null && endFrame !== void 0 ? endFrame : resolvedComposition.durationInFrames - 1,
292
- ]
293
- : null,
305
+ frameRange,
294
306
  onProgress: (progress) => {
295
307
  setRenderProgress(progress);
296
308
  },
@@ -321,8 +333,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, }) => {
321
333
  videoBitrate,
322
334
  hardwareAcceleration,
323
335
  keyframeIntervalInSeconds,
324
- startFrame,
325
- endFrame,
336
+ frameRange,
326
337
  resolvedComposition.durationInFrames,
327
338
  resolvedComposition.width,
328
339
  resolvedComposition.height,
@@ -342,8 +353,8 @@ const WebRenderModal = ({ initialFrame, defaultProps, }) => {
342
353
  }
343
354
  }, [renderMode, onRenderStill, onRenderVideo]);
344
355
  return ((0, jsx_runtime_1.jsxs)("div", { style: render_modals_1.outerModalStyle, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.ModalHeader, { title: `Render ${resolvedComposition.id}` }), (0, jsx_runtime_1.jsxs)("div", { style: render_modals_1.container, children: [(0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }), (0, jsx_runtime_1.jsx)("div", { style: render_modals_1.flexer }), (0, jsx_runtime_1.jsxs)(Button_1.Button, { autoFocus: true, onClick: onRender, style: render_modals_1.buttonStyle, disabled: !outnameValidation.valid, children: [renderProgress
345
- ? `Rendering... ${renderProgress.renderedFrames}/${endFrame !== null && endFrame !== void 0 ? endFrame : resolvedComposition.durationInFrames - 1}`
346
- : `Render ${renderMode}`, (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: render_modals_1.horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: render_modals_1.leftSidebar, children: [(0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'general', onClick: () => setTab('general'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: render_modals_1.icon }) }), "General"] }), (0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: render_modals_1.icon }) }), "Input Props"] }), renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'picture', onClick: () => setTab('picture'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(frame_1.PicIcon, { style: render_modals_1.icon }) }), "Picture"] })) : null, (0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: render_modals_1.icon }) }), "Advanced"] })] }), (0, jsx_runtime_1.jsx)("div", { style: render_modals_1.optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, jsx_runtime_1.jsx)(WebRenderModalBasic_1.WebRenderModalBasic, { renderMode: renderMode, resolvedComposition: resolvedComposition, imageFormat: imageFormat, setStillFormat: setStillFormat, frame: frame, onFrameChanged: onFrameChanged, onFrameSetDirectly: onFrameSetDirectly, container: container, setContainerFormat: setContainerFormat, codec: codec, setCodec: setCodec, startFrame: startFrame, setStartFrame: setStartFrame, endFrame: endFrame, setEndFrame: setEndFrame, outName: outName, onOutNameChange: onOutNameChange, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message, logLevel: logLevel, setLogLevel: setLogLevel })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { defaultProps: inputProps, setDefaultProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props", saving: saving, setSaving: setSaving, readOnlyStudio: false })) : tab === 'picture' ? ((0, jsx_runtime_1.jsx)(WebRenderModalPicture_1.WebRenderModalPicture, { renderMode: renderMode, videoBitrate: videoBitrate, setVideoBitrate: setVideoBitrate, keyframeIntervalInSeconds: keyframeIntervalInSeconds, setKeyframeIntervalInSeconds: setKeyframeIntervalInSeconds, transparent: transparent, setTransparent: setTransparent })) : ((0, jsx_runtime_1.jsx)(WebRenderModalAdvanced_1.WebRenderModalAdvanced, { renderMode: renderMode, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, mediaCacheSizeInBytes: mediaCacheSizeInBytes, setMediaCacheSizeInBytes: setMediaCacheSizeInBytes, hardwareAcceleration: hardwareAcceleration, setHardwareAcceleration: setHardwareAcceleration })) })] })] }));
356
+ ? `Rendering... ${renderProgress.renderedFrames}/${finalEndFrame}`
357
+ : `Render ${renderMode}`, (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: render_modals_1.horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: render_modals_1.leftSidebar, children: [(0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'general', onClick: () => setTab('general'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: render_modals_1.icon }) }), "General"] }), (0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: render_modals_1.icon }) }), "Input Props"] }), renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'picture', onClick: () => setTab('picture'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(frame_1.PicIcon, { style: render_modals_1.icon }) }), "Picture"] })) : null, (0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: render_modals_1.icon }) }), "Advanced"] })] }), (0, jsx_runtime_1.jsx)("div", { style: render_modals_1.optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, jsx_runtime_1.jsx)(WebRenderModalBasic_1.WebRenderModalBasic, { renderMode: renderMode, resolvedComposition: resolvedComposition, imageFormat: imageFormat, setStillFormat: setStillFormat, frame: frame, onFrameChanged: onFrameChanged, onFrameSetDirectly: onFrameSetDirectly, container: container, setContainerFormat: setContainerFormat, codec: codec, setCodec: setCodec, startFrame: finalStartFrame, setStartFrame: setStartFrame, endFrame: finalEndFrame, setEndFrame: setEndFrame, outName: outName, onOutNameChange: onOutNameChange, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message, logLevel: logLevel, setLogLevel: setLogLevel })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { defaultProps: inputProps, setDefaultProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props", saving: saving, setSaving: setSaving, readOnlyStudio: false })) : tab === 'picture' ? ((0, jsx_runtime_1.jsx)(WebRenderModalPicture_1.WebRenderModalPicture, { renderMode: renderMode, videoBitrate: videoBitrate, setVideoBitrate: setVideoBitrate, keyframeIntervalInSeconds: keyframeIntervalInSeconds, setKeyframeIntervalInSeconds: setKeyframeIntervalInSeconds, transparent: transparent, setTransparent: setTransparent })) : ((0, jsx_runtime_1.jsx)(WebRenderModalAdvanced_1.WebRenderModalAdvanced, { renderMode: renderMode, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, mediaCacheSizeInBytes: mediaCacheSizeInBytes, setMediaCacheSizeInBytes: setMediaCacheSizeInBytes, hardwareAcceleration: hardwareAcceleration, setHardwareAcceleration: setHardwareAcceleration })) })] })] }));
347
358
  };
348
359
  const WebRenderModalWithLoader = (props) => {
349
360
  return ((0, jsx_runtime_1.jsx)(DismissableModal_1.DismissableModal, { children: (0, jsx_runtime_1.jsx)(ResolveCompositionBeforeModal_1.ResolveCompositionBeforeModal, { compositionId: props.compositionId, children: (0, jsx_runtime_1.jsx)(WebRenderModal, { ...props }) }) }));
@@ -5,6 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const player_1 = require("@remotion/player");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
+ const in_out_1 = require("../../state/in-out");
8
9
  const modals_1 = require("../../state/modals");
9
10
  const Button_1 = require("../Button");
10
11
  const button = {
@@ -19,6 +20,7 @@ const label = {
19
20
  const TriggerWebRender = () => {
20
21
  const video = remotion_1.Internals.useVideo();
21
22
  const getCurrentFrame = player_1.PlayerInternals.useFrameImperative();
23
+ const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
22
24
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
23
25
  const onClick = (0, react_1.useCallback)(() => {
24
26
  if (!(video === null || video === void 0 ? void 0 : video.id)) {
@@ -30,8 +32,17 @@ const TriggerWebRender = () => {
30
32
  initialFrame: frame,
31
33
  compositionId: video.id,
32
34
  defaultProps: video.defaultProps,
35
+ inFrameMark: inFrame,
36
+ outFrameMark: outFrame,
33
37
  });
34
- }, [getCurrentFrame, setSelectedModal, video === null || video === void 0 ? void 0 : video.id, video === null || video === void 0 ? void 0 : video.defaultProps]);
38
+ }, [
39
+ getCurrentFrame,
40
+ inFrame,
41
+ outFrame,
42
+ setSelectedModal,
43
+ video === null || video === void 0 ? void 0 : video.defaultProps,
44
+ video === null || video === void 0 ? void 0 : video.id,
45
+ ]);
35
46
  if (!video) {
36
47
  return null;
37
48
  }