@remotion/cli 3.3.43 → 3.3.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/code-frame.js +18 -7
  2. package/dist/config/log.d.ts +1 -1
  3. package/dist/derive-codec-from-file-extension.d.ts +1 -0
  4. package/dist/derive-codec-from-file-extension.js +27 -0
  5. package/dist/editor/components/Canvas.js +1 -1
  6. package/dist/editor/components/Modals.js +1 -1
  7. package/dist/editor/components/RenderButton.js +29 -8
  8. package/dist/editor/components/RenderModal/CrfSetting.d.ts +2 -2
  9. package/dist/editor/components/RenderModal/CrfSetting.js +11 -24
  10. package/dist/editor/components/RenderModal/EveryNthFrameSetting.d.ts +5 -0
  11. package/dist/editor/components/RenderModal/EveryNthFrameSetting.js +9 -0
  12. package/dist/editor/components/RenderModal/NumberOfLoopsSetting.d.ts +5 -0
  13. package/dist/editor/components/RenderModal/NumberOfLoopsSetting.js +26 -0
  14. package/dist/editor/components/RenderModal/NumberSetting.d.ts +9 -0
  15. package/dist/editor/components/RenderModal/NumberSetting.js +26 -0
  16. package/dist/editor/components/RenderModal/RenderModal.d.ts +19 -5
  17. package/dist/editor/components/RenderModal/RenderModal.js +225 -181
  18. package/dist/editor/components/RenderModal/RenderModalAdvanced.d.ts +11 -0
  19. package/dist/editor/components/RenderModal/RenderModalAdvanced.js +15 -0
  20. package/dist/editor/components/RenderModal/RenderModalAudio.d.ts +13 -0
  21. package/dist/editor/components/RenderModal/RenderModalAudio.js +22 -0
  22. package/dist/editor/components/RenderModal/RenderModalBasic.d.ts +22 -0
  23. package/dist/editor/components/RenderModal/RenderModalBasic.js +70 -0
  24. package/dist/editor/components/RenderModal/RenderModalGeneral.d.ts +0 -0
  25. package/dist/editor/components/RenderModal/RenderModalGeneral.js +1 -0
  26. package/dist/editor/components/RenderModal/RenderModalGif.d.ts +9 -0
  27. package/dist/editor/components/RenderModal/RenderModalGif.js +16 -0
  28. package/dist/editor/components/RenderModal/RenderModalHr.d.ts +2 -0
  29. package/dist/editor/components/RenderModal/RenderModalHr.js +18 -0
  30. package/dist/editor/components/RenderModal/RenderModalPicture.d.ts +28 -0
  31. package/dist/editor/components/RenderModal/RenderModalPicture.js +51 -0
  32. package/dist/editor/components/RenderModal/ScaleSetting.js +2 -18
  33. package/dist/editor/components/RenderModal/human-readable-codec.d.ts +2 -0
  34. package/dist/editor/components/RenderModal/human-readable-codec.js +36 -0
  35. package/dist/editor/components/RenderModal/layout.d.ts +1 -0
  36. package/dist/editor/components/RenderModal/layout.js +8 -2
  37. package/dist/editor/components/RenderQueue/RenderQueueRemoveItem.js +2 -1
  38. package/dist/editor/components/RenderQueue/actions.d.ts +15 -2
  39. package/dist/editor/components/RenderQueue/actions.js +14 -1
  40. package/dist/editor/components/RenderToolbarIcon.js +30 -8
  41. package/dist/editor/components/SegmentedControl.js +1 -1
  42. package/dist/editor/components/SidebarContent.js +2 -1
  43. package/dist/editor/icons/audio.d.ts +2 -0
  44. package/dist/editor/icons/audio.js +6 -0
  45. package/dist/editor/icons/file.d.ts +2 -0
  46. package/dist/editor/icons/file.js +6 -0
  47. package/dist/editor/icons/frame.d.ts +2 -0
  48. package/dist/editor/icons/frame.js +6 -0
  49. package/dist/editor/icons/gear.d.ts +2 -0
  50. package/dist/editor/icons/gear.js +6 -0
  51. package/dist/editor/icons/gif.d.ts +2 -0
  52. package/dist/editor/icons/gif.js +6 -0
  53. package/dist/get-cli-options.d.ts +1 -1
  54. package/dist/index.d.ts +1 -1
  55. package/dist/make-progress-bar.js +14 -1
  56. package/dist/preview-server/render-queue/get-default-video-contexts.d.ts +1 -1
  57. package/dist/preview-server/render-queue/job.d.ts +27 -1
  58. package/dist/preview-server/render-queue/make-retry-payload.js +52 -10
  59. package/dist/preview-server/render-queue/process-video.js +16 -9
  60. package/dist/preview-server/routes/add-render.js +13 -0
  61. package/dist/preview-server/start-server.d.ts +1 -1
  62. package/dist/preview-server/start-server.js +33 -4
  63. package/dist/render-flows/render.d.ts +14 -4
  64. package/dist/render-flows/render.js +40 -13
  65. package/dist/setup-env-variables.d.ts +2 -0
  66. package/dist/setup-env-variables.js +36 -0
  67. package/package.json +7 -7
@@ -6,19 +6,25 @@ const client_1 = require("@remotion/renderer/client");
6
6
  const react_1 = require("react");
7
7
  const remotion_1 = require("remotion");
8
8
  const Button_1 = require("../../../preview-server/error-overlay/remotion-overlay/Button");
9
- const colors_1 = require("../../helpers/colors");
10
- const use_file_existence_1 = require("../../helpers/use-file-existence");
9
+ const audio_1 = require("../../icons/audio");
10
+ const file_1 = require("../../icons/file");
11
+ const frame_1 = require("../../icons/frame");
12
+ const gear_1 = require("../../icons/gear");
13
+ const gif_1 = require("../../icons/gif");
11
14
  const modals_1 = require("../../state/modals");
12
- const CollapsableOptions_1 = require("../CollapsableOptions");
13
15
  const layout_1 = require("../layout");
14
16
  const ModalContainer_1 = require("../ModalContainer");
15
17
  const ModalHeader_1 = require("../ModalHeader");
16
- const InputDragger_1 = require("../NewComposition/InputDragger");
17
- const RemInput_1 = require("../NewComposition/RemInput");
18
- const ValidationMessage_1 = require("../NewComposition/ValidationMessage");
19
18
  const actions_1 = require("../RenderQueue/actions");
20
19
  const SegmentedControl_1 = require("../SegmentedControl");
21
20
  const SidebarContent_1 = require("../SidebarContent");
21
+ const Tabs_1 = require("../Tabs");
22
+ const CrfSetting_1 = require("./CrfSetting");
23
+ const RenderModalAdvanced_1 = require("./RenderModalAdvanced");
24
+ const RenderModalAudio_1 = require("./RenderModalAudio");
25
+ const RenderModalBasic_1 = require("./RenderModalBasic");
26
+ const RenderModalGif_1 = require("./RenderModalGif");
27
+ const RenderModalPicture_1 = require("./RenderModalPicture");
22
28
  const initialState = { type: 'idle' };
23
29
  const reducer = (state, action) => {
24
30
  if (action.type === 'start') {
@@ -46,69 +52,130 @@ const container = {
46
52
  width: '100%',
47
53
  borderBottom: '1px solid black',
48
54
  };
49
- const optionRow = {
55
+ const scrollPanel = {
56
+ minHeight: '35vh',
57
+ maxHeight: '50vh',
58
+ overflow: 'auto',
59
+ minWidth: 650,
60
+ };
61
+ const horizontalLayout = {
50
62
  display: 'flex',
51
63
  flexDirection: 'row',
52
- alignItems: 'flex-start',
53
- minHeight: 40,
54
- paddingLeft: 16,
55
- paddingRight: 16,
56
64
  };
57
- const label = {
58
- width: 150,
59
- fontSize: 14,
60
- lineHeight: '40px',
61
- color: colors_1.LIGHT_TEXT,
65
+ const leftSidebar = {
66
+ padding: 12,
62
67
  };
63
- const rightRow = {
68
+ const horizontalTab = {
69
+ width: 250,
64
70
  display: 'flex',
65
71
  flexDirection: 'row',
66
- justifyContent: 'flex-end',
67
- alignSelf: 'center',
68
- flex: 1,
72
+ alignItems: 'center',
73
+ textAlign: 'left',
74
+ fontSize: 16,
75
+ fontWeight: 'bold',
76
+ paddingLeft: 15,
77
+ paddingTop: 12,
78
+ paddingBottom: 12,
69
79
  };
70
- const buttonRow = {
71
- display: 'flex',
72
- flexDirection: 'row',
73
- justifyContent: 'flex-end',
74
- borderTop: '1px solid black',
75
- paddingTop: 8,
76
- paddingBottom: 8,
77
- paddingLeft: 16,
78
- paddingRight: 16,
80
+ const iconContainer = {
81
+ width: 20,
82
+ height: 20,
83
+ marginRight: 15,
84
+ display: 'inline-flex',
85
+ justifyContent: 'center',
86
+ alignItems: 'center',
87
+ };
88
+ const icon = {
89
+ color: 'currentcolor',
90
+ height: 20,
79
91
  };
80
- const input = {
81
- minWidth: 250,
82
- textAlign: 'right',
92
+ const buttonStyle = {
93
+ backgroundColor: 'var(--blue)',
94
+ color: 'white',
95
+ };
96
+ const flexer = {
97
+ flex: 1,
83
98
  };
84
- const MIN_QUALITY = 1;
85
- const MAX_QUALITY = 100;
86
- const MIN_SCALE = 0.1;
87
- const MAX_SCALE = 10;
88
- const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQuality, initialScale, initialVerbose, initialOutName, initialRenderType, initialCodec, }) => {
99
+ const RenderModal = ({ compositionId, initialFrame, initialVideoImageFormat, initialStillImageFormat, initialQuality, initialScale, initialVerbose, initialOutName, initialRenderType, initialAudioCodec, initialVideoCodec, initialConcurrency, maxConcurrency, minConcurrency, initialMuted, initialEnforceAudioTrack, initialProResProfile, initialPixelFormat, initialVideoBitrate, initialAudioBitrate, initialEveryNthFrame, initialNumberOfGifLoops, initialDelayRenderTimeout, }) => {
89
100
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
90
101
  const onQuit = (0, react_1.useCallback)(() => {
91
102
  setSelectedModal(null);
92
103
  }, [setSelectedModal]);
93
104
  const isMounted = (0, react_1.useRef)(true);
94
105
  const [state, dispatch] = (0, react_1.useReducer)(reducer, initialState);
95
- const [frame, setFrame] = (0, react_1.useState)(() => initialFrame);
96
- const [imageFormat, setImageFormat] = (0, react_1.useState)(() => initialImageFormat);
97
- const [videoCodec, setVideoCodec] = (0, react_1.useState)(initialCodec);
98
- const [videoImageFormat, setVideoImageFormat] = (0, react_1.useState)('jpeg');
99
- const [renderMode, setRenderMode] = (0, react_1.useState)(initialRenderType);
100
- const [quality, setQuality] = (0, react_1.useState)(() => initialQuality !== null && initialQuality !== void 0 ? initialQuality : 80);
106
+ const [unclampedFrame, setFrame] = (0, react_1.useState)(() => initialFrame);
107
+ const [stillImageFormat, setStillImageFormat] = (0, react_1.useState)(() => initialStillImageFormat);
108
+ const [videoImageFormat, setVideoImageFormat] = (0, react_1.useState)(() => initialVideoImageFormat);
109
+ const [concurrency, setConcurrency] = (0, react_1.useState)(() => initialConcurrency);
110
+ const [videoCodec, setVideoSpecificalCodec] = (0, react_1.useState)(() => initialVideoCodec);
111
+ const [audioCodec, setAudioSpecificalCodec] = (0, react_1.useState)(() => initialAudioCodec);
112
+ const [mutedState, setMuted] = (0, react_1.useState)(() => initialMuted);
113
+ const [enforceAudioTrackState, setEnforceAudioTrackState] = (0, react_1.useState)(() => initialEnforceAudioTrack);
114
+ const [renderMode, setRenderModeState] = (0, react_1.useState)(initialRenderType);
115
+ const [quality, setQuality] = (0, react_1.useState)(() => initialQuality);
101
116
  const [scale, setScale] = (0, react_1.useState)(() => initialScale);
102
117
  const [verbose, setVerboseLogging] = (0, react_1.useState)(() => initialVerbose);
103
118
  const [outName, setOutName] = (0, react_1.useState)(() => initialOutName);
119
+ const [endFrameOrNull, setEndFrame] = (0, react_1.useState)(() => null);
120
+ const [startFrameOrNull, setStartFrame] = (0, react_1.useState)(() => null);
121
+ const [proResProfileSetting, setProResProfile] = (0, react_1.useState)(() => initialProResProfile);
122
+ const [pixelFormat, setPixelFormat] = (0, react_1.useState)(() => initialPixelFormat);
123
+ const [qualityControlType, setQualityControl] = (0, react_1.useState)(() => initialVideoBitrate === null ? 'crf' : 'bitrate');
124
+ const [shouldHaveCustomTargetAudioBitrate, setShouldHaveCustomTargetAudioBitrate,] = (0, react_1.useState)(() => initialAudioBitrate !== null);
125
+ const [customTargetAudioBitrate, setCustomTargetAudioBitrateValue] = (0, react_1.useState)(() => initialAudioBitrate !== null && initialAudioBitrate !== void 0 ? initialAudioBitrate : '256K');
126
+ const [customTargetVideoBitrate, setCustomTargetVideoBitrateValue] = (0, react_1.useState)(() => initialVideoBitrate !== null && initialVideoBitrate !== void 0 ? initialVideoBitrate : '1M');
127
+ const [limitNumberOfGifLoops, setLimitNumberOfGifLoops] = (0, react_1.useState)(() => initialNumberOfGifLoops !== null);
128
+ const [numberOfGifLoopsSetting, setNumberOfGifLoopsSetting] = (0, react_1.useState)(() => initialNumberOfGifLoops !== null && initialNumberOfGifLoops !== void 0 ? initialNumberOfGifLoops : 1);
129
+ // TODO: Allow to modify
130
+ const [delayRenderTimeout] = (0, react_1.useState)(() => initialDelayRenderTimeout);
131
+ const codec = (0, react_1.useMemo)(() => {
132
+ if (renderMode === 'audio') {
133
+ return audioCodec;
134
+ }
135
+ return videoCodec;
136
+ }, [audioCodec, renderMode, videoCodec]);
137
+ const numberOfGifLoops = (0, react_1.useMemo)(() => {
138
+ if (codec === 'gif' && limitNumberOfGifLoops) {
139
+ return numberOfGifLoopsSetting;
140
+ }
141
+ return null;
142
+ }, [codec, limitNumberOfGifLoops, numberOfGifLoopsSetting]);
143
+ const audioBitrate = (0, react_1.useMemo)(() => {
144
+ if (shouldHaveCustomTargetAudioBitrate) {
145
+ return customTargetAudioBitrate;
146
+ }
147
+ return null;
148
+ }, [customTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate]);
149
+ const videoBitrate = (0, react_1.useMemo)(() => {
150
+ if (qualityControlType === 'bitrate') {
151
+ return customTargetVideoBitrate;
152
+ }
153
+ return null;
154
+ }, [customTargetVideoBitrate, qualityControlType]);
155
+ const { crf, maxCrf, minCrf, setCrf, shouldDisplayOption: shouldDisplayCrfOption, } = (0, CrfSetting_1.useCrfState)(codec);
104
156
  const dispatchIfMounted = (0, react_1.useCallback)((payload) => {
105
157
  if (isMounted.current === false)
106
158
  return;
107
159
  dispatch(payload);
108
160
  }, []);
109
- const onValueChange = (0, react_1.useCallback)((e) => {
110
- setOutName(e.target.value);
111
- }, []);
161
+ const muted = (0, react_1.useMemo)(() => {
162
+ if (renderMode === 'video') {
163
+ return mutedState;
164
+ }
165
+ return false;
166
+ }, [mutedState, renderMode]);
167
+ const enforceAudioTrack = (0, react_1.useMemo)(() => {
168
+ if (renderMode === 'video') {
169
+ return enforceAudioTrackState;
170
+ }
171
+ return false;
172
+ }, [enforceAudioTrackState, renderMode]);
173
+ const proResProfile = (0, react_1.useMemo)(() => {
174
+ if (renderMode === 'video' && codec === 'prores') {
175
+ return proResProfileSetting;
176
+ }
177
+ return null;
178
+ }, [codec, proResProfileSetting, renderMode]);
112
179
  const { compositions } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
113
180
  const currentComposition = (0, react_1.useMemo)(() => {
114
181
  for (const composition of compositions) {
@@ -121,27 +188,55 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
121
188
  if (currentComposition === null) {
122
189
  throw new Error('This composition does not exist');
123
190
  }
191
+ const endFrame = (0, react_1.useMemo)(() => {
192
+ if (endFrameOrNull === null) {
193
+ return currentComposition.durationInFrames - 1;
194
+ }
195
+ return Math.max(0, Math.min(currentComposition.durationInFrames - 1, endFrameOrNull));
196
+ }, [currentComposition.durationInFrames, endFrameOrNull]);
197
+ const startFrame = (0, react_1.useMemo)(() => {
198
+ if (startFrameOrNull === null) {
199
+ return 0;
200
+ }
201
+ return Math.max(0, Math.min(endFrame - 1, startFrameOrNull));
202
+ }, [endFrame, startFrameOrNull]);
203
+ const frame = (0, react_1.useMemo)(() => {
204
+ const parsed = Math.floor(unclampedFrame);
205
+ return Math.max(0, Math.min(currentComposition.durationInFrames - 1, parsed));
206
+ }, [currentComposition.durationInFrames, unclampedFrame]);
124
207
  const getStringBeforeSuffix = (0, react_1.useCallback)((fileName) => {
125
208
  const dotPos = fileName.lastIndexOf('.');
126
209
  const bitBeforeDot = fileName.substring(0, dotPos);
127
210
  return bitBeforeDot;
128
211
  }, []);
129
- const setCodec = (0, react_1.useCallback)((codec) => {
130
- setVideoCodec(codec);
131
- setOutName((prev) => {
132
- // TODO: Check file extension for h264-mkv (render throws error atm)
133
- const codecSuffix = client_1.BrowserSafeApis.getFileExtensionFromCodec(codec, 'final');
134
- const newFileName = getStringBeforeSuffix(prev) + '.' + codecSuffix;
135
- return newFileName;
136
- });
212
+ const setDefaultOutName = (0, react_1.useCallback)((options) => {
213
+ if (options.type === 'still') {
214
+ setOutName((prev) => {
215
+ const newFileName = getStringBeforeSuffix(prev) + '.' + options.imageFormat;
216
+ return newFileName;
217
+ });
218
+ }
219
+ else {
220
+ setOutName((prev) => {
221
+ const codecSuffix = client_1.BrowserSafeApis.getFileExtensionFromCodec(options.codec);
222
+ const newFileName = getStringBeforeSuffix(prev) + '.' + codecSuffix;
223
+ return newFileName;
224
+ });
225
+ }
137
226
  }, [getStringBeforeSuffix]);
227
+ const setCodec = (0, react_1.useCallback)((newCodec) => {
228
+ if (renderMode === 'audio') {
229
+ setAudioSpecificalCodec(newCodec);
230
+ }
231
+ else {
232
+ setVideoSpecificalCodec(newCodec);
233
+ }
234
+ setDefaultOutName({ type: 'render', codec: newCodec });
235
+ }, [renderMode, setDefaultOutName]);
138
236
  const setStillFormat = (0, react_1.useCallback)((format) => {
139
- setImageFormat(format);
140
- setOutName((prev) => {
141
- const newFileName = getStringBeforeSuffix(prev) + '.' + format;
142
- return newFileName;
143
- });
144
- }, [getStringBeforeSuffix]);
237
+ setStillImageFormat(format);
238
+ setDefaultOutName({ type: 'still', imageFormat: format });
239
+ }, [setDefaultOutName]);
145
240
  const onClickStill = (0, react_1.useCallback)(() => {
146
241
  var _a;
147
242
  (_a = SidebarContent_1.leftSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectRendersPanel();
@@ -149,8 +244,8 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
149
244
  (0, actions_1.addStillRenderJob)({
150
245
  compositionId,
151
246
  outName,
152
- imageFormat,
153
- quality: imageFormat === 'jpeg' ? quality : null,
247
+ imageFormat: stillImageFormat,
248
+ quality: stillImageFormat === 'jpeg' ? quality : null,
154
249
  frame,
155
250
  scale,
156
251
  verbose,
@@ -166,13 +261,20 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
166
261
  compositionId,
167
262
  dispatchIfMounted,
168
263
  frame,
169
- imageFormat,
264
+ stillImageFormat,
170
265
  outName,
171
266
  quality,
172
267
  scale,
173
268
  setSelectedModal,
174
269
  verbose,
175
270
  ]);
271
+ const [everyNthFrameSetting, setEveryNthFrameSetting] = (0, react_1.useState)(() => initialEveryNthFrame);
272
+ const everyNthFrame = (0, react_1.useMemo)(() => {
273
+ if (codec === 'gif') {
274
+ return everyNthFrameSetting;
275
+ }
276
+ return 1;
277
+ }, [codec, everyNthFrameSetting]);
176
278
  const onClickVideo = (0, react_1.useCallback)(() => {
177
279
  var _a;
178
280
  (_a = SidebarContent_1.leftSidebarTabs.current) === null || _a === void 0 ? void 0 : _a.selectRendersPanel();
@@ -181,11 +283,23 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
181
283
  compositionId,
182
284
  outName,
183
285
  imageFormat: videoImageFormat,
184
- quality: imageFormat === 'jpeg' ? quality : null,
286
+ quality: stillImageFormat === 'jpeg' ? quality : null,
185
287
  scale,
186
288
  verbose,
187
- // TODO: Make this configurable
188
- codec: videoCodec,
289
+ codec,
290
+ concurrency,
291
+ crf: qualityControlType === 'crf' ? crf : null,
292
+ endFrame,
293
+ startFrame,
294
+ muted,
295
+ enforceAudioTrack,
296
+ proResProfile,
297
+ pixelFormat,
298
+ audioBitrate,
299
+ videoBitrate,
300
+ everyNthFrame,
301
+ numberOfGifLoops,
302
+ delayRenderTimeout,
189
303
  })
190
304
  .then(() => {
191
305
  dispatchIfMounted({ type: 'succeed' });
@@ -195,70 +309,36 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
195
309
  dispatchIfMounted({ type: 'fail' });
196
310
  });
197
311
  }, [
198
- compositionId,
199
312
  dispatchIfMounted,
200
- imageFormat,
313
+ compositionId,
201
314
  outName,
315
+ videoImageFormat,
316
+ stillImageFormat,
202
317
  quality,
203
318
  scale,
204
- setSelectedModal,
205
319
  verbose,
206
- videoCodec,
207
- videoImageFormat,
320
+ codec,
321
+ concurrency,
322
+ qualityControlType,
323
+ crf,
324
+ endFrame,
325
+ startFrame,
326
+ muted,
327
+ enforceAudioTrack,
328
+ proResProfile,
329
+ pixelFormat,
330
+ audioBitrate,
331
+ videoBitrate,
332
+ everyNthFrame,
333
+ numberOfGifLoops,
334
+ delayRenderTimeout,
335
+ setSelectedModal,
208
336
  ]);
209
- const onQualityChangedDirectly = (0, react_1.useCallback)((newQuality) => {
210
- setQuality(newQuality);
211
- }, []);
212
- const onQualityChanged = (0, react_1.useCallback)((e) => {
213
- setQuality((q) => {
214
- const newQuality = parseInt(e, 10);
215
- if (Number.isNaN(newQuality)) {
216
- return q;
217
- }
218
- const newQualityClamped = Math.min(MAX_QUALITY, Math.max(newQuality, MIN_QUALITY));
219
- return newQualityClamped;
220
- });
221
- }, []);
222
- const onScaleSetDirectly = (0, react_1.useCallback)((newScale) => {
223
- setScale(newScale);
224
- }, []);
225
- const onScaleChanged = (0, react_1.useCallback)((e) => {
226
- setScale((q) => {
227
- const newScale = parseFloat(e);
228
- if (Number.isNaN(newScale)) {
229
- return q;
230
- }
231
- const newScaleClamped = Math.min(MAX_SCALE, Math.max(newScale, MIN_SCALE));
232
- return newScaleClamped;
233
- });
234
- }, []);
235
- const onFrameSetDirectly = (0, react_1.useCallback)((newFrame) => {
236
- console.log(newFrame);
237
- if (newFrame > currentComposition.durationInFrames - 1) {
238
- setFrame(currentComposition.durationInFrames - 1);
239
- }
240
- else {
241
- setFrame(newFrame);
242
- }
243
- }, [currentComposition.durationInFrames, setFrame]);
244
- const onFrameChanged = (0, react_1.useCallback)((e) => {
245
- setFrame((q) => {
246
- const newFrame = parseFloat(e);
247
- if (Number.isNaN(newFrame)) {
248
- return q;
249
- }
250
- // TODO: User could change frame inbetween 😈
251
- return newFrame > currentComposition.durationInFrames - 1
252
- ? currentComposition.durationInFrames - 1
253
- : newFrame;
254
- });
255
- }, []);
256
337
  (0, react_1.useEffect)(() => {
257
338
  return () => {
258
339
  isMounted.current = false;
259
340
  };
260
341
  }, []);
261
- const existence = (0, use_file_existence_1.useFileExistence)(outName);
262
342
  const imageFormatOptions = (0, react_1.useMemo)(() => {
263
343
  return [
264
344
  {
@@ -268,7 +348,7 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
268
348
  : () => setVideoImageFormat('png'),
269
349
  key: 'png',
270
350
  selected: renderMode === 'still'
271
- ? imageFormat === 'png'
351
+ ? stillImageFormat === 'png'
272
352
  : videoImageFormat === 'png',
273
353
  },
274
354
  {
@@ -278,32 +358,23 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
278
358
  : () => setVideoImageFormat('jpeg'),
279
359
  key: 'jpeg',
280
360
  selected: renderMode === 'still'
281
- ? imageFormat === 'jpeg'
361
+ ? stillImageFormat === 'jpeg'
282
362
  : videoImageFormat === 'jpeg',
283
363
  },
284
364
  ];
285
- }, [imageFormat, renderMode, setStillFormat, videoImageFormat]);
286
- const videoCodecOptions = (0, react_1.useMemo)(() => {
287
- const codecs = [
288
- 'h264',
289
- 'h265',
290
- 'vp8',
291
- 'vp9',
292
- 'mp3',
293
- 'aac',
294
- 'wav',
295
- 'prores',
296
- 'gif',
297
- ];
298
- return codecs.map((codec) => {
299
- return {
300
- label: codec,
301
- onClick: () => setCodec(codec),
302
- key: codec,
303
- selected: videoCodec === codec,
304
- };
305
- });
306
- }, [setCodec, videoCodec]);
365
+ }, [stillImageFormat, renderMode, setStillFormat, videoImageFormat]);
366
+ const setRenderMode = (0, react_1.useCallback)((newRenderMode) => {
367
+ setRenderModeState(newRenderMode);
368
+ if (newRenderMode === 'audio') {
369
+ setDefaultOutName({ type: 'render', codec: audioCodec });
370
+ }
371
+ if (newRenderMode === 'video') {
372
+ setDefaultOutName({ type: 'render', codec: videoCodec });
373
+ }
374
+ if (newRenderMode === 'still') {
375
+ setDefaultOutName({ type: 'still', imageFormat: stillImageFormat });
376
+ }
377
+ }, [audioCodec, setDefaultOutName, stillImageFormat, videoCodec]);
307
378
  const renderTabOptions = (0, react_1.useMemo)(() => {
308
379
  if ((currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.durationInFrames) < 2) {
309
380
  return [
@@ -311,7 +382,6 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
311
382
  label: 'Still',
312
383
  onClick: () => {
313
384
  setRenderMode('still');
314
- setStillFormat(imageFormat);
315
385
  },
316
386
  key: 'still',
317
387
  selected: renderMode === 'still',
@@ -323,7 +393,6 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
323
393
  label: 'Still',
324
394
  onClick: () => {
325
395
  setRenderMode('still');
326
- setStillFormat(imageFormat);
327
396
  },
328
397
  key: 'still',
329
398
  selected: renderMode === 'still',
@@ -332,46 +401,21 @@ const RenderModal = ({ compositionId, initialFrame, initialImageFormat, initialQ
332
401
  label: 'Video',
333
402
  onClick: () => {
334
403
  setRenderMode('video');
335
- setCodec(videoCodec);
336
404
  },
337
405
  key: 'video',
338
406
  selected: renderMode === 'video',
339
407
  },
408
+ {
409
+ label: 'Audio',
410
+ onClick: () => {
411
+ setRenderMode('audio');
412
+ },
413
+ key: 'audio',
414
+ selected: renderMode === 'audio',
415
+ },
340
416
  ];
341
- }, [
342
- currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.durationInFrames,
343
- imageFormat,
344
- renderMode,
345
- setCodec,
346
- setStillFormat,
347
- videoCodec,
348
- ]);
349
- const onVerboseLoggingChanged = (0, react_1.useCallback)((e) => {
350
- setVerboseLogging(e.target.checked);
351
- }, []);
352
- if (renderMode === 'still') {
353
- return ((0, jsx_runtime_1.jsxs)(ModalContainer_1.ModalContainer, { onOutsideClick: onQuit, onEscape: onQuit, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.NewCompHeader, { title: `Render ${compositionId}` }), (0, jsx_runtime_1.jsx)("div", { style: container, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { block: true, y: 0.5 }), (0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Format" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: true }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Output name" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput
354
- // TODO: Validate and reject folders or weird file names
355
- , {
356
- // TODO: Validate and reject folders or weird file names
357
- warning: existence, style: input, type: "text", value: outName, onChange: onValueChange }), existence ? ((0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: "Will be overwritten" })) : null] }) })] }), currentComposition.durationInFrames > 1 ? ((0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Frame" }), (0, jsx_runtime_1.jsxs)("div", { style: rightRow, children: [(0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: frame, onTextChange: onFrameChanged,
358
- // TODO: Actual frame
359
- placeholder: "0-100",
360
- // TODO: Debug the number input field
361
- onValueChange: onFrameSetDirectly, name: "frame", step: 1, min: 0,
362
- // TODO: Add actual frame
363
- max: currentComposition.durationInFrames - 1 }), ' '] })] })) : null, (0, jsx_runtime_1.jsxs)(CollapsableOptions_1.CollapsableOptions, { showLabel: "Show advanced settings", hideLabel: "Hide advanced settings", children: [(0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Scale" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: scale, onTextChange: onScaleChanged, placeholder: "0.1-10",
364
- // TODO: Does not allow non-integer steps
365
- // TODO: Cannot click and type in 0.2
366
- onValueChange: onScaleSetDirectly, name: "scale", step: 0.1, min: MIN_SCALE, max: MAX_SCALE }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Verbose logging" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)("input", { type: 'checkbox', checked: verbose, onChange: onVerboseLoggingChanged }) })] }), imageFormat === 'jpeg' && ((0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "JPEG Quality" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: quality, onTextChange: onQualityChanged, placeholder: "0-100", onValueChange: onQualityChangedDirectly, name: "quality", step: 1, min: MIN_QUALITY, max: MAX_QUALITY }) })] }))] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { block: true, y: 0.5 }), (0, jsx_runtime_1.jsx)("div", { style: buttonRow, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { autoFocus: true, onClick: onClickStill, disabled: state.type === 'load', children: state.type === 'idle' ? 'Render still' : 'Rendering...' }) })] })] }));
367
- }
368
- return ((0, jsx_runtime_1.jsxs)(ModalContainer_1.ModalContainer, { onOutsideClick: onQuit, onEscape: onQuit, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.NewCompHeader, { title: `Render ${compositionId}` }), (0, jsx_runtime_1.jsx)("div", { style: container, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { block: true, y: 0.5 }), (0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Codec" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: videoCodecOptions, needsWrapping: true }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Output name" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput
369
- // TODO: Validate and reject folders or weird file names
370
- , {
371
- // TODO: Validate and reject folders or weird file names
372
- warning: existence, style: input, type: "text", value: outName, onChange: onValueChange }), existence ? ((0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: "Will be overwritten" })) : null] }) })] }), (0, jsx_runtime_1.jsxs)(CollapsableOptions_1.CollapsableOptions, { showLabel: "Show advanced settings", hideLabel: "Hide advanced settings", children: [(0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Scale" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: scale, onTextChange: onScaleChanged, placeholder: "0.1-10",
373
- // TODO: Direct input does not allow non-integer steps
374
- // TODO: Cannot click and type in 0.2
375
- onValueChange: onScaleSetDirectly, name: "scale", step: 0.1, min: MIN_SCALE, max: MAX_SCALE }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Verbose logging" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)("input", { type: 'checkbox', checked: verbose, onChange: onVerboseLoggingChanged }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "Image Format" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: false }) })] }), videoImageFormat === 'jpeg' && ((0, jsx_runtime_1.jsxs)("div", { style: optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: label, children: "JPEG Quality" }), (0, jsx_runtime_1.jsx)("div", { style: rightRow, children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: quality, onTextChange: onQualityChanged, placeholder: "0-100", onValueChange: onQualityChangedDirectly, name: "quality", step: 1, min: MIN_QUALITY, max: MAX_QUALITY }) })] }))] }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { block: true, y: 0.5 }), (0, jsx_runtime_1.jsx)("div", { style: buttonRow, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { autoFocus: true, onClick: onClickVideo, disabled: state.type === 'load', children: state.type === 'idle' ? 'Render video' : 'Rendering...' }) })] })] }));
417
+ }, [currentComposition === null || currentComposition === void 0 ? void 0 : currentComposition.durationInFrames, renderMode, setRenderMode]);
418
+ const [tab, setTab] = (0, react_1.useState)('general');
419
+ return ((0, jsx_runtime_1.jsxs)(ModalContainer_1.ModalContainer, { onOutsideClick: onQuit, onEscape: onQuit, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.NewCompHeader, { title: `Render ${compositionId}` }), (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.jsx)(Button_1.Button, { autoFocus: true, onClick: renderMode === 'still' ? onClickStill : onClickVideo, disabled: state.type === 'load', style: buttonStyle, children: state.type === 'idle' ? `Render ${renderMode}` : 'Rendering...' })] }), (0, jsx_runtime_1.jsxs)("div", { style: horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftSidebar, children: [(0, jsx_runtime_1.jsxs)(Tabs_1.Tab, { style: horizontalTab, selected: tab === 'general', onClick: () => setTab('general'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(file_1.FileIcon, { style: icon }) }), "General"] }), (0, jsx_runtime_1.jsxs)(Tabs_1.Tab, { style: horizontalTab, selected: tab === 'picture', onClick: () => setTab('picture'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(frame_1.PicIcon, { style: icon }) }), "Picture"] }), renderMode === 'still' ? null : ((0, jsx_runtime_1.jsxs)(Tabs_1.Tab, { style: horizontalTab, selected: tab === 'audio', onClick: () => setTab('audio'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(audio_1.AudioIcon, { style: icon }) }), "Audio"] })), codec === 'gif' ? ((0, jsx_runtime_1.jsxs)(Tabs_1.Tab, { style: horizontalTab, selected: tab === 'gif', onClick: () => setTab('gif'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gif_1.GifIcon, { style: icon }) }), "GIF"] })) : null, (0, jsx_runtime_1.jsxs)(Tabs_1.Tab, { style: horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(gear_1.GearIcon, { style: icon }) }), "Other"] })] }), (0, jsx_runtime_1.jsxs)("div", { style: scrollPanel, children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { block: true, y: 0.5 }), tab === 'general' ? ((0, jsx_runtime_1.jsx)(RenderModalBasic_1.RenderModalBasic, { codec: codec, currentComposition: currentComposition, frame: frame, imageFormatOptions: imageFormatOptions, outName: outName, proResProfile: proResProfile, renderMode: renderMode, setCodec: setCodec, setFrame: setFrame, setOutName: setOutName, setProResProfile: setProResProfile, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame })) : tab === 'picture' ? ((0, jsx_runtime_1.jsx)(RenderModalPicture_1.RenderModalPicture, { renderMode: renderMode, scale: scale, setScale: setScale, pixelFormat: pixelFormat, setPixelFormat: setPixelFormat, imageFormatOptions: imageFormatOptions, crf: crf, setCrf: setCrf, customTargetVideoBitrate: customTargetVideoBitrate, maxCrf: maxCrf, minCrf: minCrf, quality: quality, qualityControlType: qualityControlType, setQuality: setQuality, setCustomTargetVideoBitrateValue: setCustomTargetVideoBitrateValue, setQualityControl: setQualityControl, shouldDisplayCrfOption: shouldDisplayCrfOption, videoImageFormat: videoImageFormat, stillImageFormat: stillImageFormat })) : tab === 'audio' ? ((0, jsx_runtime_1.jsx)(RenderModalAudio_1.RenderModalAudio, { muted: muted, renderMode: renderMode, setMuted: setMuted, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrackState: setEnforceAudioTrackState, customTargetAudioBitrate: customTargetAudioBitrate, setCustomTargetAudioBitrateValue: setCustomTargetAudioBitrateValue, setShouldHaveCustomTargetAudioBitrate: setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate: shouldHaveCustomTargetAudioBitrate })) : tab === 'gif' ? ((0, jsx_runtime_1.jsx)(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : ((0, jsx_runtime_1.jsx)(RenderModalAdvanced_1.RenderModalAdvanced, { concurrency: concurrency, maxConcurrency: maxConcurrency, minConcurrency: minConcurrency, renderMode: renderMode, setConcurrency: setConcurrency, setVerboseLogging: setVerboseLogging, verbose: verbose })), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { block: true, y: 0.5 })] })] })] }));
376
420
  };
377
421
  exports.RenderModal = RenderModal;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export declare type RenderType = 'still' | 'video' | 'audio';
3
+ export declare const RenderModalAdvanced: React.FC<{
4
+ renderMode: RenderType;
5
+ minConcurrency: number;
6
+ maxConcurrency: number;
7
+ setConcurrency: React.Dispatch<React.SetStateAction<number>>;
8
+ concurrency: number;
9
+ setVerboseLogging: React.Dispatch<React.SetStateAction<boolean>>;
10
+ verbose: boolean;
11
+ }>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenderModalAdvanced = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const Checkbox_1 = require("../Checkbox");
7
+ const layout_1 = require("./layout");
8
+ const NumberSetting_1 = require("./NumberSetting");
9
+ const RenderModalAdvanced = ({ renderMode, maxConcurrency, minConcurrency, setConcurrency, concurrency, setVerboseLogging, verbose, }) => {
10
+ const onVerboseLoggingChanged = (0, react_1.useCallback)((e) => {
11
+ setVerboseLogging(e.target.checked);
12
+ }, [setVerboseLogging]);
13
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [renderMode === 'still' ? null : ((0, jsx_runtime_1.jsx)(NumberSetting_1.NumberSetting, { min: minConcurrency, max: maxConcurrency, step: 1, name: "Concurrency", onValueChanged: setConcurrency, value: concurrency })), (0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Verbose logging" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { checked: verbose, onChange: onVerboseLoggingChanged }) })] })] }));
14
+ };
15
+ exports.RenderModalAdvanced = RenderModalAdvanced;
@@ -0,0 +1,13 @@
1
+ /// <reference types="react" />
2
+ import type { RenderType } from './RenderModalAdvanced';
3
+ export declare const RenderModalAudio: React.FC<{
4
+ muted: boolean;
5
+ setMuted: React.Dispatch<React.SetStateAction<boolean>>;
6
+ renderMode: RenderType;
7
+ enforceAudioTrack: boolean;
8
+ setEnforceAudioTrackState: React.Dispatch<React.SetStateAction<boolean>>;
9
+ shouldHaveCustomTargetAudioBitrate: boolean;
10
+ setShouldHaveCustomTargetAudioBitrate: React.Dispatch<React.SetStateAction<boolean>>;
11
+ setCustomTargetAudioBitrateValue: React.Dispatch<React.SetStateAction<string>>;
12
+ customTargetAudioBitrate: string;
13
+ }>;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenderModalAudio = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const Checkbox_1 = require("../Checkbox");
7
+ const RemInput_1 = require("../NewComposition/RemInput");
8
+ const EnforceAudioTrackSetting_1 = require("./EnforceAudioTrackSetting");
9
+ const layout_1 = require("./layout");
10
+ const MutedSetting_1 = require("./MutedSetting");
11
+ const RenderModalHr_1 = require("./RenderModalHr");
12
+ const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setEnforceAudioTrackState, setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate, setCustomTargetAudioBitrateValue, customTargetAudioBitrate, }) => {
13
+ const onShouldHaveTargetAudioBitrateChanged = (0, react_1.useCallback)((e) => {
14
+ setShouldHaveCustomTargetAudioBitrate(e.target.checked);
15
+ }, [setShouldHaveCustomTargetAudioBitrate]);
16
+ // TODO: When rendering, mp3 does not support the "crf" option. Ignoring.
17
+ const onTargetAudioBitrateChanged = (0, react_1.useCallback)((e) => {
18
+ setCustomTargetAudioBitrateValue(e.target.value);
19
+ }, [setCustomTargetAudioBitrateValue]);
20
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [renderMode === 'video' && ((0, jsx_runtime_1.jsx)(MutedSetting_1.MutedSetting, { muted: muted, setMuted: setMuted })), renderMode === 'video' && ((0, jsx_runtime_1.jsx)(EnforceAudioTrackSetting_1.EnforceAudioTrackSetting, { enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrack: setEnforceAudioTrackState })), (0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {}), renderMode === 'still' ? null : ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Custom audio bitrate" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { checked: shouldHaveCustomTargetAudioBitrate, onChange: onShouldHaveTargetAudioBitrateChanged }) })] })), shouldHaveCustomTargetAudioBitrate && renderMode !== 'still' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Target audio bitrate" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { style: layout_1.input, value: customTargetAudioBitrate, onChange: onTargetAudioBitrateChanged }) }) })] })) : null] }));
21
+ };
22
+ exports.RenderModalAudio = RenderModalAudio;