@remotion/studio 4.0.396 → 4.0.397

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.
@@ -8,7 +8,7 @@ const check_fullscreen_support_1 = require("../helpers/check-fullscreen-support"
8
8
  const colors_1 = require("../helpers/colors");
9
9
  const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
10
10
  const mobile_layout_1 = require("../helpers/mobile-layout");
11
- const show_browser_rendering_1 = require("../helpers/show-browser-rendering");
11
+ const should_show_render_button_1 = require("../helpers/should-show-render-button");
12
12
  const timeline_layout_1 = require("../helpers/timeline-layout");
13
13
  const loop_1 = require("../state/loop");
14
14
  const CheckboardToggle_1 = require("./CheckboardToggle");
@@ -24,7 +24,6 @@ const RenderButton_1 = require("./RenderButton");
24
24
  const SizeSelector_1 = require("./SizeSelector");
25
25
  const TimelineZoomControls_1 = require("./Timeline/TimelineZoomControls");
26
26
  const TimelineInOutToggle_1 = require("./TimelineInOutToggle");
27
- const TriggerWebRender_1 = require("./WebRender/TriggerWebRender");
28
27
  const layout_1 = require("./layout");
29
28
  const container = {
30
29
  display: 'flex',
@@ -134,6 +133,6 @@ const PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
134
133
  };
135
134
  }
136
135
  });
137
- return ((0, jsx_runtime_1.jsxs)("div", { ref: previewToolbarRef, style: isMobileLayout ? mobileContainer : container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { ref: leftScrollIndicatorRef, style: scrollIndicatorLeft }), isMobileLayout ? null : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)("div", { style: padding }), (0, jsx_runtime_1.jsx)(TimelineZoomControls_1.TimelineZoomControls, {})] }), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(SizeSelector_1.SizeSelector, {}), isStill || isVideoComposition ? ((0, jsx_runtime_1.jsx)(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate })) : null] })), isVideoComposition ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(PlayPause_1.PlayPause, { bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds, loop: loop, playbackRate: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(LoopToggle_1.LoopToggle, { loop: loop, setLoop: setLoop }), (0, jsx_runtime_1.jsx)(MuteToggle_1.MuteToggle, { muted: mediaMuted, setMuted: setMediaMuted }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(TimelineInOutToggle_1.TimelineInOutPointToggle, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 })] })) : null, (0, jsx_runtime_1.jsx)(CheckboardToggle_1.CheckboardToggle, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), isFullscreenSupported && (0, jsx_runtime_1.jsx)(FullscreenToggle_1.FullScreenToggle, {}), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), isMobileLayout && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(SizeSelector_1.SizeSelector, {}), isStill || isVideoComposition ? ((0, jsx_runtime_1.jsx)(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate })) : null] })), (0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)(layout_1.Flex, {}), !isMobileLayout && (0, jsx_runtime_1.jsx)(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), show_browser_rendering_1.SHOW_BROWSER_RENDERING ? (0, jsx_runtime_1.jsx)(TriggerWebRender_1.TriggerWebRender, {}) : null, readOnlyStudio ? null : (0, jsx_runtime_1.jsx)(RenderButton_1.RenderButton, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 })] }), (0, jsx_runtime_1.jsx)(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate }), (0, jsx_runtime_1.jsx)(PlaybackRatePersistor_1.PlaybackRatePersistor, {}), (0, jsx_runtime_1.jsx)("div", { ref: rightScrollIndicatorRef, style: scrollIndicatorRight })] }));
136
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: previewToolbarRef, style: isMobileLayout ? mobileContainer : container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { ref: leftScrollIndicatorRef, style: scrollIndicatorLeft }), isMobileLayout ? null : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)("div", { style: padding }), (0, jsx_runtime_1.jsx)(TimelineZoomControls_1.TimelineZoomControls, {})] }), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(SizeSelector_1.SizeSelector, {}), isStill || isVideoComposition ? ((0, jsx_runtime_1.jsx)(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate })) : null] })), isVideoComposition ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(PlayPause_1.PlayPause, { bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds, loop: loop, playbackRate: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(LoopToggle_1.LoopToggle, { loop: loop, setLoop: setLoop }), (0, jsx_runtime_1.jsx)(MuteToggle_1.MuteToggle, { muted: mediaMuted, setMuted: setMediaMuted }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, jsx_runtime_1.jsx)(TimelineInOutToggle_1.TimelineInOutPointToggle, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 })] })) : null, (0, jsx_runtime_1.jsx)(CheckboardToggle_1.CheckboardToggle, {}), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), isFullscreenSupported && (0, jsx_runtime_1.jsx)(FullscreenToggle_1.FullScreenToggle, {}), (0, jsx_runtime_1.jsx)(layout_1.Flex, {}), isMobileLayout && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Flex, {}), (0, jsx_runtime_1.jsx)(SizeSelector_1.SizeSelector, {}), isStill || isVideoComposition ? ((0, jsx_runtime_1.jsx)(PlaybackRateSelector_1.PlaybackRateSelector, { setPlaybackRate: setPlaybackRate, playbackRate: playbackRate })) : null] })), (0, jsx_runtime_1.jsxs)("div", { style: sideContainer, children: [(0, jsx_runtime_1.jsx)(layout_1.Flex, {}), !isMobileLayout && (0, jsx_runtime_1.jsx)(FpsCounter_1.FpsCounter, { playbackSpeed: playbackRate }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 2 }), (0, should_show_render_button_1.shouldShowRenderButton)(readOnlyStudio) ? ((0, jsx_runtime_1.jsx)(RenderButton_1.RenderButton, { readOnlyStudio: readOnlyStudio })) : null, (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1.5 })] }), (0, jsx_runtime_1.jsx)(PlaybackKeyboardShortcutsManager_1.PlaybackKeyboardShortcutsManager, { setPlaybackRate: setPlaybackRate }), (0, jsx_runtime_1.jsx)(PlaybackRatePersistor_1.PlaybackRatePersistor, {}), (0, jsx_runtime_1.jsx)("div", { ref: rightScrollIndicatorRef, style: scrollIndicatorRight })] }));
138
137
  };
139
138
  exports.PreviewToolbar = PreviewToolbar;
@@ -1,2 +1,5 @@
1
1
  import React from 'react';
2
- export declare const RenderButton: React.FC;
2
+ export type RenderType = 'server-render' | 'client-render';
3
+ export declare const RenderButton: React.FC<{
4
+ readonly readOnlyStudio: boolean;
5
+ }>;
@@ -1,29 +1,107 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.RenderButton = void 0;
4
7
  const jsx_runtime_1 = require("react/jsx-runtime");
5
8
  const player_1 = require("@remotion/player");
6
9
  const react_1 = require("react");
10
+ const react_dom_1 = __importDefault(require("react-dom"));
7
11
  const remotion_1 = require("remotion");
8
12
  const client_id_1 = require("../helpers/client-id");
13
+ const colors_1 = require("../helpers/colors");
14
+ const show_browser_rendering_1 = require("../helpers/show-browser-rendering");
9
15
  const use_keybinding_1 = require("../helpers/use-keybinding");
16
+ const caret_1 = require("../icons/caret");
10
17
  const render_1 = require("../icons/render");
11
18
  const in_out_1 = require("../state/in-out");
12
19
  const modals_1 = require("../state/modals");
13
- const Button_1 = require("./Button");
20
+ const z_index_1 = require("../state/z-index");
21
+ const is_menu_item_1 = require("./Menu/is-menu-item");
22
+ const portals_1 = require("./Menu/portals");
23
+ const styles_1 = require("./Menu/styles");
24
+ const MenuContent_1 = require("./NewComposition/MenuContent");
14
25
  const layout_1 = require("./layout");
15
- const button = {
26
+ const splitButtonContainer = {
27
+ display: 'inline-flex',
28
+ flexDirection: 'row',
29
+ alignItems: 'stretch',
30
+ borderRadius: 4,
31
+ border: `1px solid ${colors_1.INPUT_BORDER_COLOR_UNHOVERED}`,
32
+ backgroundColor: colors_1.INPUT_BACKGROUND,
33
+ overflow: 'hidden',
34
+ };
35
+ const mainButtonStyle = {
16
36
  paddingLeft: 7,
17
37
  paddingRight: 7,
18
38
  paddingTop: 7,
19
39
  paddingBottom: 7,
40
+ background: 'transparent',
41
+ border: 'none',
42
+ color: 'white',
43
+ cursor: 'pointer',
44
+ display: 'flex',
45
+ alignItems: 'center',
46
+ fontSize: 14,
47
+ fontFamily: 'inherit',
48
+ };
49
+ const dividerStyle = {
50
+ width: 1,
51
+ backgroundColor: colors_1.INPUT_BORDER_COLOR_UNHOVERED,
52
+ alignSelf: 'stretch',
53
+ };
54
+ const dropdownTriggerStyle = {
55
+ paddingLeft: 6,
56
+ paddingRight: 6,
57
+ paddingTop: 7,
58
+ paddingBottom: 7,
59
+ background: 'transparent',
60
+ border: 'none',
61
+ color: 'white',
62
+ cursor: 'pointer',
63
+ display: 'flex',
64
+ alignItems: 'center',
65
+ };
66
+ const mainButtonContent = {
67
+ paddingLeft: 4,
68
+ paddingRight: 6,
20
69
  };
21
70
  const label = {
22
71
  fontSize: 14,
23
72
  };
24
- const RenderButton = () => {
73
+ const RENDER_TYPE_STORAGE_KEY = 'remotion.renderType';
74
+ const getInitialRenderType = (readOnlyStudio) => {
75
+ if (!show_browser_rendering_1.SHOW_BROWSER_RENDERING) {
76
+ return 'server-render';
77
+ }
78
+ if (readOnlyStudio) {
79
+ return 'client-render';
80
+ }
81
+ try {
82
+ const stored = localStorage.getItem(RENDER_TYPE_STORAGE_KEY);
83
+ if (stored === 'server-render' || stored === 'client-render') {
84
+ return stored;
85
+ }
86
+ }
87
+ catch (_a) {
88
+ // localStorage might not be available
89
+ }
90
+ return 'server-render';
91
+ };
92
+ const RenderButton = ({ readOnlyStudio, }) => {
25
93
  const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
26
94
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
95
+ const [renderType, setRenderType] = (0, react_1.useState)(() => getInitialRenderType(readOnlyStudio));
96
+ const [dropdownOpened, setDropdownOpened] = (0, react_1.useState)(false);
97
+ const dropdownRef = (0, react_1.useRef)(null);
98
+ const containerRef = (0, react_1.useRef)(null);
99
+ const { currentZIndex } = (0, z_index_1.useZIndex)();
100
+ const size = player_1.PlayerInternals.useElementSize(dropdownRef, {
101
+ triggerOnWindowResize: true,
102
+ shouldApplyCssTransforms: true,
103
+ });
104
+ const refresh = size === null || size === void 0 ? void 0 : size.refresh;
27
105
  const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
28
106
  .previewServerState.type;
29
107
  const shortcut = (0, use_keybinding_1.areKeyboardShortcutsDisabled)() ? '' : '(R)';
@@ -41,7 +119,7 @@ const RenderButton = () => {
41
119
  const video = remotion_1.Internals.useVideo();
42
120
  const getCurrentFrame = player_1.PlayerInternals.useFrameImperative();
43
121
  const { props } = (0, react_1.useContext)(remotion_1.Internals.EditorPropsContext);
44
- const onClick = (0, react_1.useCallback)(() => {
122
+ const openServerRenderModal = (0, react_1.useCallback)(() => {
45
123
  var _a, _b, _c;
46
124
  if (!video) {
47
125
  return null;
@@ -101,9 +179,178 @@ const RenderButton = () => {
101
179
  renderDefaults: defaults,
102
180
  });
103
181
  }, [video, setSelectedModal, getCurrentFrame, props, inFrame, outFrame]);
182
+ const openClientRenderModal = (0, react_1.useCallback)(() => {
183
+ var _a;
184
+ if (!video) {
185
+ return null;
186
+ }
187
+ const defaults = window.remotion_renderDefaults;
188
+ if (!defaults) {
189
+ throw new TypeError('Expected defaults');
190
+ }
191
+ setSelectedModal({
192
+ type: 'web-render',
193
+ compositionId: video.id,
194
+ initialFrame: getCurrentFrame(),
195
+ defaultProps: (_a = props[video.id]) !== null && _a !== void 0 ? _a : video.defaultProps,
196
+ inFrameMark: inFrame,
197
+ outFrameMark: outFrame,
198
+ initialLogLevel: defaults.logLevel,
199
+ });
200
+ }, [video, setSelectedModal, getCurrentFrame, props, inFrame, outFrame]);
201
+ const onClick = (0, react_1.useCallback)(() => {
202
+ if (!show_browser_rendering_1.SHOW_BROWSER_RENDERING || renderType === 'server-render') {
203
+ openServerRenderModal();
204
+ }
205
+ else {
206
+ openClientRenderModal();
207
+ }
208
+ }, [renderType, openServerRenderModal, openClientRenderModal]);
209
+ const onHideDropdown = (0, react_1.useCallback)(() => {
210
+ setDropdownOpened(false);
211
+ }, []);
212
+ const handleRenderTypeChange = (0, react_1.useCallback)((newType) => {
213
+ setRenderType(newType);
214
+ try {
215
+ localStorage.setItem(RENDER_TYPE_STORAGE_KEY, newType);
216
+ }
217
+ catch (_a) {
218
+ // localStorage might not be available
219
+ }
220
+ setDropdownOpened(false);
221
+ if (newType === 'server-render') {
222
+ openServerRenderModal();
223
+ }
224
+ else {
225
+ openClientRenderModal();
226
+ }
227
+ }, [openServerRenderModal, openClientRenderModal]);
228
+ const dropdownValues = (0, react_1.useMemo)(() => {
229
+ return [
230
+ {
231
+ type: 'item',
232
+ id: 'server-render',
233
+ label: 'Server-side render',
234
+ value: 'server-render',
235
+ onClick: () => handleRenderTypeChange('server-render'),
236
+ keyHint: null,
237
+ leftItem: null,
238
+ subMenu: null,
239
+ quickSwitcherLabel: null,
240
+ },
241
+ {
242
+ type: 'item',
243
+ id: 'client-render',
244
+ label: 'Client-side render',
245
+ value: 'client-render',
246
+ onClick: () => handleRenderTypeChange('client-render'),
247
+ keyHint: null,
248
+ leftItem: null,
249
+ subMenu: null,
250
+ quickSwitcherLabel: null,
251
+ },
252
+ ];
253
+ }, [handleRenderTypeChange]);
254
+ (0, react_1.useEffect)(() => {
255
+ const { current } = dropdownRef;
256
+ if (!current) {
257
+ return;
258
+ }
259
+ const onPointerDown = () => {
260
+ return setDropdownOpened((o) => {
261
+ if (!o) {
262
+ refresh === null || refresh === void 0 ? void 0 : refresh();
263
+ }
264
+ return !o;
265
+ });
266
+ };
267
+ const onClickDropdown = (e) => {
268
+ e.stopPropagation();
269
+ const isKeyboardInitiated = e.detail === 0;
270
+ if (!isKeyboardInitiated) {
271
+ return;
272
+ }
273
+ return setDropdownOpened((o) => {
274
+ if (!o) {
275
+ refresh === null || refresh === void 0 ? void 0 : refresh();
276
+ window.addEventListener('pointerup', (evt) => {
277
+ if (!(0, is_menu_item_1.isMenuItem)(evt.target)) {
278
+ setDropdownOpened(false);
279
+ }
280
+ }, {
281
+ once: true,
282
+ });
283
+ }
284
+ return !o;
285
+ });
286
+ };
287
+ current.addEventListener('pointerdown', onPointerDown);
288
+ current.addEventListener('click', onClickDropdown);
289
+ return () => {
290
+ current.removeEventListener('pointerdown', onPointerDown);
291
+ current.removeEventListener('click', onClickDropdown);
292
+ };
293
+ }, [refresh]);
294
+ const spaceToBottom = (0, react_1.useMemo)(() => {
295
+ const margin = 10;
296
+ if (size && dropdownOpened) {
297
+ return size.windowSize.height - (size.top + size.height) - margin;
298
+ }
299
+ return 0;
300
+ }, [dropdownOpened, size]);
301
+ const spaceToTop = (0, react_1.useMemo)(() => {
302
+ const margin = 10;
303
+ if (size && dropdownOpened) {
304
+ return size.top - margin;
305
+ }
306
+ return 0;
307
+ }, [dropdownOpened, size]);
308
+ const derivedMaxHeight = (0, react_1.useMemo)(() => {
309
+ return spaceToTop > spaceToBottom ? spaceToTop : spaceToBottom;
310
+ }, [spaceToBottom, spaceToTop]);
311
+ const portalStyle = (0, react_1.useMemo)(() => {
312
+ if (!dropdownOpened || !size) {
313
+ return null;
314
+ }
315
+ const verticalLayout = spaceToTop > spaceToBottom ? 'bottom' : 'top';
316
+ return {
317
+ ...(verticalLayout === 'top'
318
+ ? {
319
+ ...styles_1.menuContainerTowardsBottom,
320
+ top: size.top + size.height,
321
+ }
322
+ : {
323
+ ...styles_1.menuContainerTowardsTop,
324
+ bottom: size.windowSize.height - size.top,
325
+ }),
326
+ right: size.windowSize.width - size.left - size.width,
327
+ };
328
+ }, [dropdownOpened, size, spaceToBottom, spaceToTop]);
329
+ const containerStyle = (0, react_1.useMemo)(() => {
330
+ return {
331
+ ...splitButtonContainer,
332
+ borderColor: colors_1.INPUT_BORDER_COLOR_UNHOVERED,
333
+ opacity: connectionStatus !== 'connected' ? 0.7 : 1,
334
+ cursor: connectionStatus !== 'connected' ? 'inherit' : 'pointer',
335
+ };
336
+ }, [connectionStatus]);
337
+ const renderLabel = renderType === 'server-render' ? 'Render' : 'Render on web';
338
+ const shouldShowDropdown = (0, react_1.useMemo)(() => {
339
+ // Server render is not available
340
+ if (readOnlyStudio) {
341
+ return false;
342
+ }
343
+ // client render is not available
344
+ if (!show_browser_rendering_1.SHOW_BROWSER_RENDERING) {
345
+ return false;
346
+ }
347
+ return true;
348
+ }, [readOnlyStudio]);
104
349
  if (!video) {
105
350
  return null;
106
351
  }
107
- return ((0, jsx_runtime_1.jsx)(Button_1.Button, { id: "render-modal-button", title: tooltip, onClick: onClick, buttonContainerStyle: button, disabled: connectionStatus !== 'connected', children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", children: [(0, jsx_runtime_1.jsx)(render_1.RenderIcon, { svgProps: iconStyle }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("span", { style: label, children: "Render" })] }) }));
352
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { style: { display: 'none' }, id: "render-modal-button-server", disabled: connectionStatus !== 'connected' && renderType === 'server-render', onClick: openServerRenderModal, type: "button" }), ' ', (0, jsx_runtime_1.jsx)("button", { style: { display: 'none' }, id: "render-modal-button-client", disabled: connectionStatus !== 'connected' && renderType === 'server-render', onClick: openClientRenderModal, type: "button" }), (0, jsx_runtime_1.jsxs)("div", { ref: containerRef, style: containerStyle, title: tooltip, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", style: mainButtonStyle, onClick: onClick, id: "render-modal-button", disabled: connectionStatus !== 'connected' && renderType === 'server-render', children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { align: "center", style: mainButtonContent, children: [(0, jsx_runtime_1.jsx)(render_1.ThinRenderIcon, { fill: "currentcolor", svgProps: iconStyle }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("span", { style: label, children: renderLabel })] }) }), shouldShowDropdown ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: dividerStyle }), (0, jsx_runtime_1.jsx)("button", { ref: dropdownRef, type: "button", style: dropdownTriggerStyle, disabled: connectionStatus !== 'connected', className: is_menu_item_1.MENU_INITIATOR_CLASSNAME, children: (0, jsx_runtime_1.jsx)(caret_1.CaretDown, {}) })] })) : null] }), portalStyle
353
+ ? react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("div", { style: styles_1.fullScreenOverlay, children: (0, jsx_runtime_1.jsx)("div", { style: styles_1.outerPortal, className: "css-reset", children: (0, jsx_runtime_1.jsx)(z_index_1.HigherZIndex, { onOutsideClick: onHideDropdown, onEscape: onHideDropdown, children: (0, jsx_runtime_1.jsx)("div", { style: portalStyle, children: (0, jsx_runtime_1.jsx)(MenuContent_1.MenuContent, { onNextMenu: () => { }, onPreviousMenu: () => { }, values: dropdownValues, onHide: onHideDropdown, leaveLeftSpace: false, preselectIndex: dropdownValues.findIndex((v) => v.id === renderType), topItemCanBeUnselected: false, fixedHeight: derivedMaxHeight }) }) }) }) }), (0, portals_1.getPortal)(currentZIndex))
354
+ : null] }));
108
355
  };
109
356
  exports.RenderButton = RenderButton;
@@ -6,6 +6,7 @@ const studio_shared_1 = require("@remotion/studio-shared");
6
6
  const web_renderer_1 = require("@remotion/web-renderer");
7
7
  const react_1 = require("react");
8
8
  const ShortcutHint_1 = require("../../error-overlay/remotion-overlay/ShortcutHint");
9
+ const audio_1 = require("../../icons/audio");
9
10
  const data_1 = require("../../icons/data");
10
11
  const file_1 = require("../../icons/file");
11
12
  const frame_1 = require("../../icons/frame");
@@ -20,6 +21,7 @@ const get_string_before_suffix_1 = require("./get-string-before-suffix");
20
21
  const render_modals_1 = require("./render-modals");
21
22
  const ResolveCompositionBeforeModal_1 = require("./ResolveCompositionBeforeModal");
22
23
  const WebRenderModalAdvanced_1 = require("./WebRenderModalAdvanced");
24
+ const WebRenderModalAudio_1 = require("./WebRenderModalAudio");
23
25
  const WebRenderModalBasic_1 = require("./WebRenderModalBasic");
24
26
  const WebRenderModalPicture_1 = require("./WebRenderModalPicture");
25
27
  const invalidCharacters = ['?', '*', '+', ':', '%'];
@@ -100,6 +102,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
100
102
  const [endFrame, setEndFrame] = (0, react_1.useState)(() => outFrameMark !== null && outFrameMark !== void 0 ? outFrameMark : null);
101
103
  const [renderProgress, setRenderProgress] = (0, react_1.useState)(null);
102
104
  const [transparent, setTransparent] = (0, react_1.useState)(false);
105
+ const [muted, setMuted] = (0, react_1.useState)(false);
103
106
  const finalEndFrame = (0, react_1.useMemo)(() => {
104
107
  if (endFrame === null) {
105
108
  return resolvedComposition.durationInFrames - 1;
@@ -316,6 +319,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
316
319
  setRenderProgress(progress);
317
320
  },
318
321
  transparent,
322
+ muted,
319
323
  outputTarget: 'web-fs',
320
324
  });
321
325
  setRenderProgress(null);
@@ -348,6 +352,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
348
352
  resolvedComposition.fps,
349
353
  outName,
350
354
  transparent,
355
+ muted,
351
356
  resolvedComposition.defaultProps,
352
357
  resolvedComposition.id,
353
358
  unresolvedComposition.calculateMetadata,
@@ -362,7 +367,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
362
367
  }, [renderMode, onRenderStill, onRenderVideo]);
363
368
  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
364
369
  ? `Rendering... ${renderProgress.renderedFrames}/${finalEndFrame}`
365
- : `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 })) })] })] }));
370
+ : `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, renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'audio', onClick: () => setTab('audio'), children: [(0, jsx_runtime_1.jsx)("div", { style: render_modals_1.iconContainer, children: (0, jsx_runtime_1.jsx)(audio_1.AudioIcon, { style: render_modals_1.icon }) }), "Audio"] })) : 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 })) : tab === 'audio' ? ((0, jsx_runtime_1.jsx)(WebRenderModalAudio_1.WebRenderModalAudio, { muted: muted, setMuted: setMuted })) : ((0, jsx_runtime_1.jsx)(WebRenderModalAdvanced_1.WebRenderModalAdvanced, { renderMode: renderMode, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, mediaCacheSizeInBytes: mediaCacheSizeInBytes, setMediaCacheSizeInBytes: setMediaCacheSizeInBytes, hardwareAcceleration: hardwareAcceleration, setHardwareAcceleration: setHardwareAcceleration })) })] })] }));
366
371
  };
367
372
  const WebRenderModalWithLoader = (props) => {
368
373
  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 }) }) }));
@@ -0,0 +1,5 @@
1
+ import type React from 'react';
2
+ export declare const WebRenderModalAudio: React.FC<{
3
+ readonly muted: boolean;
4
+ readonly setMuted: React.Dispatch<React.SetStateAction<boolean>>;
5
+ }>;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebRenderModalAudio = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const is_menu_item_1 = require("../Menu/is-menu-item");
6
+ const MutedSetting_1 = require("./MutedSetting");
7
+ const container = {
8
+ flex: 1,
9
+ overflowY: 'auto',
10
+ };
11
+ const WebRenderModalAudio = ({ muted, setMuted }) => {
12
+ return ((0, jsx_runtime_1.jsx)("div", { style: container, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: (0, jsx_runtime_1.jsx)(MutedSetting_1.MutedSetting, { enforceAudioTrack: false, muted: muted, setMuted: setMuted }) }));
13
+ };
14
+ exports.WebRenderModalAudio = WebRenderModalAudio;