@remotion/studio 4.0.446 → 4.0.448

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 (29) hide show
  1. package/dist/components/Modals.js +1 -1
  2. package/dist/components/NewComposition/MenuContent.js +58 -0
  3. package/dist/components/NewComposition/menu-typeahead.d.ts +5 -0
  4. package/dist/components/NewComposition/menu-typeahead.js +27 -0
  5. package/dist/components/RenderButton.js +2 -0
  6. package/dist/components/RenderModal/OptionExplainer.js +10 -2
  7. package/dist/components/RenderModal/RenderModalAudio.d.ts +2 -0
  8. package/dist/components/RenderModal/RenderModalAudio.js +20 -1
  9. package/dist/components/RenderModal/ServerRenderModal.d.ts +1 -0
  10. package/dist/components/RenderModal/ServerRenderModal.js +7 -2
  11. package/dist/components/RenderModal/WebRenderModal.js +6 -2
  12. package/dist/components/RenderModal/WebRenderModalAdvanced.d.ts +2 -0
  13. package/dist/components/RenderModal/WebRenderModalAdvanced.js +10 -2
  14. package/dist/components/RenderQueue/ClientRenderQueueProcessor.js +4 -3
  15. package/dist/components/RenderQueue/actions.d.ts +2 -1
  16. package/dist/components/RenderQueue/actions.js +2 -1
  17. package/dist/components/RenderQueue/client-side-render-types.d.ts +1 -0
  18. package/dist/components/SidebarRenderButton.js +1 -0
  19. package/dist/error-overlay/react-overlay/listen-to-runtime-errors.js +2 -1
  20. package/dist/esm/{chunk-2dkkw8x5.js → chunk-9s6mbe6g.js} +308 -113
  21. package/dist/esm/internals.mjs +308 -113
  22. package/dist/esm/previewEntry.mjs +309 -114
  23. package/dist/esm/renderEntry.mjs +3 -2
  24. package/dist/helpers/make-render-command.d.ts +3 -2
  25. package/dist/helpers/make-render-command.js +4 -1
  26. package/dist/helpers/retry-payload.js +4 -0
  27. package/dist/renderEntry.js +1 -0
  28. package/dist/state/modals.d.ts +2 -0
  29. package/package.json +9 -9
@@ -26,6 +26,6 @@ const Modals = ({ readOnlyStudio }) => {
26
26
  'connected';
27
27
  return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'duplicate-comp' && (jsx_runtime_1.jsx(DuplicateComposition_1.DuplicateComposition, { compositionType: modalContextType.compositionType, compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'delete-comp' && (jsx_runtime_1.jsx(DeleteComposition_1.DeleteComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'rename-comp' && (jsx_runtime_1.jsx(RenameComposition_1.RenameComposition, { compositionId: modalContextType.compositionId })), modalContextType && modalContextType.type === 'input-props-override' && (jsx_runtime_1.jsx(OverrideInputProps_1.OverrideInputPropsModal, {})), modalContextType && modalContextType.type === 'web-render' && (jsx_runtime_1.jsx(WebRenderModal_1.WebRenderModalWithLoader, { ...modalContextType })), modalContextType &&
28
28
  modalContextType.type === 'server-render' &&
29
- (canRender || modalContextType.readOnlyStudio) ? (jsx_runtime_1.jsx(ServerRenderModal_1.RenderModalWithLoader, { readOnlyStudio: (_a = modalContextType.readOnlyStudio) !== null && _a !== void 0 ? _a : false, initialFrame: modalContextType.initialFrame, initialDarkMode: modalContextType.initialDarkMode, 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 })) : null, modalContextType && modalContextType.type === 'render-progress' && (jsx_runtime_1.jsx(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && (jsx_runtime_1.jsx(UpdateModal_1.UpdateModal, { info: modalContextType.info, knownBugs: modalContextType.knownBugs })), modalContextType && modalContextType.type === 'install-packages' && (jsx_runtime_1.jsx(InstallPackage_1.InstallPackageModal, { packageManager: modalContextType.packageManager })), modalContextType && modalContextType.type === 'quick-switcher' && (jsx_runtime_1.jsx(QuickSwitcher_1.default, { readOnlyStudio: readOnlyStudio, invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode })), process.env.ASK_AI_ENABLED && jsx_runtime_1.jsx(AskAiModal_1.AskAiModal, {})] }));
29
+ (canRender || modalContextType.readOnlyStudio) ? (jsx_runtime_1.jsx(ServerRenderModal_1.RenderModalWithLoader, { readOnlyStudio: (_a = modalContextType.readOnlyStudio) !== null && _a !== void 0 ? _a : false, initialFrame: modalContextType.initialFrame, initialDarkMode: modalContextType.initialDarkMode, 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, initialSampleRate: modalContextType.initialSampleRate, initialChromeMode: modalContextType.initialChromeMode, renderDefaults: modalContextType.renderDefaults })) : null, modalContextType && modalContextType.type === 'render-progress' && (jsx_runtime_1.jsx(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && (jsx_runtime_1.jsx(UpdateModal_1.UpdateModal, { info: modalContextType.info, knownBugs: modalContextType.knownBugs })), modalContextType && modalContextType.type === 'install-packages' && (jsx_runtime_1.jsx(InstallPackage_1.InstallPackageModal, { packageManager: modalContextType.packageManager })), modalContextType && modalContextType.type === 'quick-switcher' && (jsx_runtime_1.jsx(QuickSwitcher_1.default, { readOnlyStudio: readOnlyStudio, invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode })), process.env.ASK_AI_ENABLED && jsx_runtime_1.jsx(AskAiModal_1.AskAiModal, {})] }));
30
30
  };
31
31
  exports.Modals = Modals;
@@ -10,6 +10,7 @@ const is_menu_item_1 = require("../Menu/is-menu-item");
10
10
  const MenuDivider_1 = require("../Menu/MenuDivider");
11
11
  const MenuSubItem_1 = require("../Menu/MenuSubItem");
12
12
  const styles_1 = require("../Menu/styles");
13
+ const menu_typeahead_1 = require("./menu-typeahead");
13
14
  const BORDER_SIZE = 1;
14
15
  const container = {
15
16
  paddingTop: styles_1.MENU_VERTICAL_PADDING,
@@ -26,6 +27,8 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
26
27
  const containerRef = (0, react_1.useRef)(null);
27
28
  const isMobileLayout = (0, mobile_layout_1.useMobileLayout)();
28
29
  const [subMenuActivated, setSubMenuActivated] = (0, react_1.useState)(false);
30
+ const typeaheadQueryRef = (0, react_1.useRef)('');
31
+ const typeaheadTimeoutRef = (0, react_1.useRef)(null);
29
32
  if (values[0].type === 'divider') {
30
33
  throw new Error('first value cant be divide');
31
34
  }
@@ -38,6 +41,13 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
38
41
  const onItemSelected = (0, react_1.useCallback)((id) => {
39
42
  setSelectedItem(id);
40
43
  }, []);
44
+ const clearTypeahead = (0, react_1.useCallback)(() => {
45
+ typeaheadQueryRef.current = '';
46
+ if (typeaheadTimeoutRef.current !== null) {
47
+ window.clearTimeout(typeaheadTimeoutRef.current);
48
+ typeaheadTimeoutRef.current = null;
49
+ }
50
+ }, []);
41
51
  const isItemSelectable = (0, react_1.useCallback)((v) => {
42
52
  return v.type !== 'divider' && !v.disabled;
43
53
  }, []);
@@ -114,6 +124,35 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
114
124
  }
115
125
  setSubMenuActivated('without-mouse');
116
126
  }, [onNextMenu, selectedItem, values]);
127
+ const onTypeahead = (0, react_1.useCallback)((event) => {
128
+ if (event.ctrlKey ||
129
+ event.metaKey ||
130
+ event.altKey ||
131
+ event.key.length !== 1 ||
132
+ event.key.trim().length === 0) {
133
+ return;
134
+ }
135
+ const { activeElement } = document;
136
+ if (activeElement instanceof HTMLInputElement ||
137
+ activeElement instanceof HTMLTextAreaElement) {
138
+ return;
139
+ }
140
+ typeaheadQueryRef.current = `${typeaheadQueryRef.current}${event.key}`;
141
+ const matchedId = (0, menu_typeahead_1.findTypeaheadMenuItem)({
142
+ query: typeaheadQueryRef.current,
143
+ values,
144
+ });
145
+ if (matchedId !== null) {
146
+ setSelectedItem(matchedId);
147
+ }
148
+ if (typeaheadTimeoutRef.current !== null) {
149
+ window.clearTimeout(typeaheadTimeoutRef.current);
150
+ }
151
+ typeaheadTimeoutRef.current = window.setTimeout(() => {
152
+ typeaheadQueryRef.current = '';
153
+ typeaheadTimeoutRef.current = null;
154
+ }, 700);
155
+ }, [values]);
117
156
  const containerWithHeight = (0, react_1.useMemo)(() => {
118
157
  const containerStyles = { ...container };
119
158
  if (fixedHeight === null) {
@@ -127,6 +166,25 @@ const MenuContent = ({ onHide, values, preselectIndex, onNextMenu, onPreviousMen
127
166
  }
128
167
  return containerStyles;
129
168
  }, [fixedHeight, isMobileLayout]);
169
+ (0, react_1.useEffect)(() => {
170
+ if (!keybindings.isHighestContext ||
171
+ !process.env.KEYBOARD_SHORTCUTS_ENABLED) {
172
+ return;
173
+ }
174
+ const onKeyDown = (event) => {
175
+ onTypeahead(event);
176
+ };
177
+ window.addEventListener('keydown', onKeyDown);
178
+ return () => {
179
+ window.removeEventListener('keydown', onKeyDown);
180
+ clearTypeahead();
181
+ };
182
+ }, [clearTypeahead, keybindings.isHighestContext, onTypeahead]);
183
+ (0, react_1.useEffect)(() => {
184
+ return () => {
185
+ clearTypeahead();
186
+ };
187
+ }, [clearTypeahead]);
130
188
  (0, react_1.useEffect)(() => {
131
189
  const escapeBinding = keybindings.registerKeybinding({
132
190
  event: 'keydown',
@@ -0,0 +1,5 @@
1
+ import type { ComboboxValue } from './ComboBox';
2
+ export declare const findTypeaheadMenuItem: ({ query, values, }: {
3
+ query: string;
4
+ values: ComboboxValue[];
5
+ }) => string | null;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findTypeaheadMenuItem = void 0;
4
+ const getLabelToMatch = (value) => {
5
+ if (value.type === 'divider' || value.disabled) {
6
+ return null;
7
+ }
8
+ if (typeof value.label === 'string') {
9
+ return value.label;
10
+ }
11
+ return null;
12
+ };
13
+ const findTypeaheadMenuItem = ({ query, values, }) => {
14
+ const normalizedQuery = query.trim().toLowerCase();
15
+ if (normalizedQuery.length === 0) {
16
+ return null;
17
+ }
18
+ const matched = values.find((value) => {
19
+ const label = getLabelToMatch(value);
20
+ return label ? label.toLowerCase().startsWith(normalizedQuery) : false;
21
+ });
22
+ if (!matched || matched.type === 'divider') {
23
+ return null;
24
+ }
25
+ return matched.id;
26
+ };
27
+ exports.findTypeaheadMenuItem = findTypeaheadMenuItem;
@@ -225,6 +225,7 @@ const RenderButton = ({ readOnlyStudio, }) => {
225
225
  renderTypeOfLastRender: null,
226
226
  defaulMetadata: defaults.metadata,
227
227
  initialHardwareAcceleration: defaults.hardwareAcceleration,
228
+ initialSampleRate: defaults.sampleRate,
228
229
  initialChromeMode: defaults.chromeMode,
229
230
  initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
230
231
  renderDefaults: defaults,
@@ -262,6 +263,7 @@ const RenderButton = ({ readOnlyStudio, }) => {
262
263
  initialTransparent: null,
263
264
  initialMuted: null,
264
265
  initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
266
+ initialAllowHtmlInCanvas: defaults.allowHtmlInCanvas,
265
267
  });
266
268
  }, [video, setSelectedModal, getCurrentFrame, props, inFrame, outFrame]);
267
269
  const onClick = (0, react_1.useCallback)(() => {
@@ -19,8 +19,9 @@ const padding = {
19
19
  const title = {
20
20
  fontSize: 14,
21
21
  };
22
+ const DESCRIPTION_FONT_SIZE_PX = 14;
22
23
  const description = {
23
- fontSize: 14,
24
+ fontSize: DESCRIPTION_FONT_SIZE_PX,
24
25
  maxWidth: 400,
25
26
  };
26
27
  const link = {
@@ -56,7 +57,14 @@ const OptionExplainer = ({ option }) => {
56
57
  jsx_runtime_1.jsxs("div", { children: [
57
58
  jsx_runtime_1.jsx("strong", { style: title, children: option.name }), option.docLink ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
58
59
  jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("a", { style: link, href: option.docLink, target: "_blank", children: "Docs" })
59
- ] })) : null] }), jsx_runtime_1.jsx("div", { style: description, children: option.description('ssr') })
60
+ ] })) : null] }), jsx_runtime_1.jsxs("div", { style: description, children: [
61
+ jsx_runtime_1.jsx("style", { children: `
62
+ .__remotion-option-explainer-description a,
63
+ .__remotion-option-explainer-description code {
64
+ font-size: ${DESCRIPTION_FONT_SIZE_PX}px;
65
+ }
66
+ ` }), jsx_runtime_1.jsx("div", { className: "__remotion-option-explainer-description", children: option.description('ssr') })
67
+ ] })
60
68
  ] }), jsx_runtime_1.jsx(layout_1.Spacing, { y: 0.5, block: true }), jsx_runtime_1.jsx(MenuDivider_1.MenuDivider, {}), jsx_runtime_1.jsx(layout_1.Spacing, { y: 0.5, block: true }), jsx_runtime_1.jsxs("div", { children: [
61
69
  jsx_runtime_1.jsxs("div", { style: infoRow, children: [
62
70
  jsx_runtime_1.jsx("div", { style: infoRowLabel, children: "CLI flag" }), jsx_runtime_1.jsx("div", { style: flexSpacer }), jsx_runtime_1.jsxs("code", { children: ["--", option.cliFlag] }), jsx_runtime_1.jsx("div", { style: copyWrapper, children: jsx_runtime_1.jsx(CliCopyButton_1.CliCopyButton, { valueToCopy: option.cliFlag }) })
@@ -19,4 +19,6 @@ export declare const RenderModalAudio: React.FC<{
19
19
  readonly setSeparateAudioTo: React.Dispatch<React.SetStateAction<string | null>>;
20
20
  readonly separateAudioTo: string | null;
21
21
  readonly outName: string;
22
+ readonly sampleRate: number;
23
+ readonly setSampleRate: React.Dispatch<React.SetStateAction<number>>;
22
24
  }>;
@@ -21,7 +21,8 @@ const container = {
21
21
  flex: 1,
22
22
  overflowY: 'auto',
23
23
  };
24
- const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setEnforceAudioTrackState, setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate, setCustomTargetAudioBitrateValue, customTargetAudioBitrate, audioCodec, codec, setAudioCodec, forSeamlessAacConcatenation, setForSeamlessAacConcatenation, separateAudioTo, setSeparateAudioTo, outName, }) => {
24
+ const commonSampleRates = [8000, 16000, 22050, 44100, 48000, 96000];
25
+ const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setEnforceAudioTrackState, setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate, setCustomTargetAudioBitrateValue, customTargetAudioBitrate, audioCodec, codec, setAudioCodec, forSeamlessAacConcatenation, setForSeamlessAacConcatenation, separateAudioTo, setSeparateAudioTo, outName, sampleRate, setSampleRate, }) => {
25
26
  const onShouldHaveTargetAudioBitrateChanged = (0, react_1.useCallback)((e) => {
26
27
  setShouldHaveCustomTargetAudioBitrate(e.target.checked);
27
28
  }, [setShouldHaveCustomTargetAudioBitrate]);
@@ -31,6 +32,20 @@ const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setE
31
32
  const onSeamlessAacConcatenationChanges = (0, react_1.useCallback)((e) => {
32
33
  setForSeamlessAacConcatenation(e.target.checked);
33
34
  }, [setForSeamlessAacConcatenation]);
35
+ const sampleRateOptions = (0, react_1.useMemo)(() => {
36
+ return commonSampleRates.map((rate) => ({
37
+ label: rate === 48000 ? `${rate} Hz (default)` : `${rate} Hz`,
38
+ onClick: () => setSampleRate(rate),
39
+ key: String(rate),
40
+ leftItem: sampleRate === rate ? jsx_runtime_1.jsx(Checkmark_1.Checkmark, {}) : null,
41
+ id: String(rate),
42
+ keyHint: null,
43
+ quickSwitcherLabel: null,
44
+ subMenu: null,
45
+ type: 'item',
46
+ value: String(rate),
47
+ }));
48
+ }, [sampleRate, setSampleRate]);
34
49
  const audioCodecOptions = (0, react_1.useCallback)((currentCodec) => {
35
50
  return client_1.BrowserSafeApis.supportedAudioCodecs[currentCodec].map((audioCodecOption) => {
36
51
  return {
@@ -68,6 +83,10 @@ const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setE
68
83
  renderMode !== 'still' &&
69
84
  !muted ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
70
85
  jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Target audio bitrate" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx(RemInput_1.RemotionInput, { style: layout_2.input, value: customTargetAudioBitrate, onChange: onTargetAudioBitrateChanged, status: "ok", rightAlign: true }) }) })
86
+ ] })) : null, renderMode !== 'still' && !muted ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
87
+ jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Sample Rate ",
88
+ jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.OptionExplainerBubble, { id: "sampleRateOption" })
89
+ ] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: sampleRateOptions, selectedId: String(sampleRate), title: "Sample Rate" }) })
71
90
  ] })) : null] }));
72
91
  };
73
92
  exports.RenderModalAudio = RenderModalAudio;
@@ -48,6 +48,7 @@ type RenderModalProps = {
48
48
  readonly defaultConfigurationAudioCodec: AudioCodec | null;
49
49
  readonly initialForSeamlessAacConcatenation: boolean;
50
50
  readonly initialHardwareAcceleration: HardwareAccelerationOption;
51
+ readonly initialSampleRate: number;
51
52
  readonly renderTypeOfLastRender: RenderType | null;
52
53
  readonly initialChromeMode: ChromeMode;
53
54
  readonly initialOffthreadVideoThreads: number | null;
@@ -61,7 +61,7 @@ const reducer = (state, action) => {
61
61
  }
62
62
  return state;
63
63
  };
64
- const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, initialStillImageFormat, initialJpegQuality, initialScale, initialLogLevel, initialConcurrency, maxConcurrency, minConcurrency, initialMuted, initialEnforceAudioTrack, initialProResProfile, initialx264Preset, initialPixelFormat, initialVideoBitrate, initialAudioBitrate, initialEveryNthFrame, initialNumberOfGifLoops, initialDelayRenderTimeout, initialOffthreadVideoCacheSizeInBytes, initialEnvVariables, initialDisableWebSecurity, initialGl, initialHeadless, initialIgnoreCertificateErrors, initialEncodingBufferSize, initialEncodingMaxRate, initialOffthreadVideoThreads, initialMediaCacheSizeInBytes, initialDarkMode, initialUserAgent, defaultProps, inFrameMark, outFrameMark, initialColorSpace, initialMultiProcessOnLinux, defaultConfigurationAudioCodec, defaultConfigurationVideoCodec, initialBeep, initialRepro, initialForSeamlessAacConcatenation, renderTypeOfLastRender, initialHardwareAcceleration, defaultMetadata, initialChromeMode, renderDefaults, }) => {
64
+ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, initialStillImageFormat, initialJpegQuality, initialScale, initialLogLevel, initialConcurrency, maxConcurrency, minConcurrency, initialMuted, initialEnforceAudioTrack, initialProResProfile, initialx264Preset, initialPixelFormat, initialVideoBitrate, initialAudioBitrate, initialEveryNthFrame, initialNumberOfGifLoops, initialDelayRenderTimeout, initialOffthreadVideoCacheSizeInBytes, initialEnvVariables, initialDisableWebSecurity, initialGl, initialHeadless, initialIgnoreCertificateErrors, initialEncodingBufferSize, initialEncodingMaxRate, initialOffthreadVideoThreads, initialMediaCacheSizeInBytes, initialDarkMode, initialUserAgent, defaultProps, inFrameMark, outFrameMark, initialColorSpace, initialMultiProcessOnLinux, defaultConfigurationAudioCodec, defaultConfigurationVideoCodec, initialBeep, initialRepro, initialForSeamlessAacConcatenation, renderTypeOfLastRender, initialHardwareAcceleration, initialSampleRate, defaultMetadata, initialChromeMode, renderDefaults, }) => {
65
65
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
66
66
  const context = (0, react_1.useContext)(ResolveCompositionBeforeModal_1.ResolvedCompositionContext);
67
67
  if (!context) {
@@ -113,6 +113,7 @@ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, in
113
113
  const [repro, setRepro] = (0, react_1.useState)(() => initialRepro);
114
114
  const [enforceAudioTrackState, setEnforceAudioTrackState] = (0, react_1.useState)(() => initialEnforceAudioTrack);
115
115
  const [forSeamlessAacConcatenation, setForSeamlessAacConcatenation] = (0, react_1.useState)(() => initialForSeamlessAacConcatenation);
116
+ const [sampleRate, setSampleRate] = (0, react_1.useState)(() => initialSampleRate);
116
117
  const [renderMode, setRenderModeState] = (0, react_1.useState)(initialRenderType);
117
118
  const [jpegQuality, setJpegQuality] = (0, react_1.useState)(() => initialJpegQuality);
118
119
  const [scale, setScale] = (0, react_1.useState)(() => initialScale);
@@ -480,6 +481,7 @@ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, in
480
481
  chromeMode,
481
482
  offthreadVideoThreads,
482
483
  mediaCacheSizeInBytes,
484
+ sampleRate,
483
485
  })
484
486
  .then(() => {
485
487
  dispatchIfMounted({ type: 'succeed' });
@@ -534,6 +536,7 @@ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, in
534
536
  chromeMode,
535
537
  offthreadVideoThreads,
536
538
  mediaCacheSizeInBytes,
539
+ sampleRate,
537
540
  ]);
538
541
  const onClickSequence = (0, react_1.useCallback)(() => {
539
542
  var _a;
@@ -824,6 +827,7 @@ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, in
824
827
  beepOnFinish,
825
828
  repro,
826
829
  metadata,
830
+ sampleRate,
827
831
  envVariables: (0, convert_env_variables_1.envVariablesArrayToObject)(envVariables),
828
832
  inputProps,
829
833
  });
@@ -873,6 +877,7 @@ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, in
873
877
  resolvedComposition.durationInFrames,
874
878
  resolvedComposition.id,
875
879
  scale,
880
+ sampleRate,
876
881
  separateAudioTo,
877
882
  sequenceImageFormat,
878
883
  startFrame,
@@ -987,7 +992,7 @@ const RenderModal = ({ readOnlyStudio, initialFrame, initialVideoImageFormat, in
987
992
  jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(gif_1.GifIcon, { style: render_modals_1.icon }) }),
988
993
  "GIF"] })) : null, shownTabs.includes('advanced') ? (jsx_runtime_1.jsxs(vertical_1.VerticalTab, { style: render_modals_1.horizontalTab, selected: tab === 'advanced', onClick: () => setTab('advanced'), children: [
989
994
  jsx_runtime_1.jsx("div", { style: render_modals_1.iconContainer, children: jsx_runtime_1.jsx(gear_1.GearIcon, { style: render_modals_1.icon }) }),
990
- "Other"] })) : null] }), jsx_runtime_1.jsx("div", { style: render_modals_1.optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? (jsx_runtime_1.jsx(RenderModalBasic_1.RenderModalBasic, { codec: codec, resolvedComposition: resolvedComposition, frame: frame, imageFormatOptions: imageFormatOptions, outName: outName, proResProfile: proResProfile, renderMode: renderMode, setVideoCodec: setCodec, setFrame: setFrame, setOutName: setOutName, setProResProfile: setProResProfile, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, setVerboseLogging: setLogLevel, logLevel: logLevel, showOutputName: !readOnlyStudio, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? (jsx_runtime_1.jsx(RenderModalPicture_1.RenderModalPicture, { renderMode: renderMode, scale: scale, setScale: setScale, pixelFormat: pixelFormat, pixelFormatOptions: pixelFormatOptions, imageFormatOptions: imageFormatOptions, crf: crf, setCrf: setCrf, customTargetVideoBitrate: customTargetVideoBitrate, maxCrf: maxCrf, minCrf: minCrf, jpegQuality: jpegQuality, qualityControlType: qualityControlType, setJpegQuality: setJpegQuality, setColorSpace: setColorSpace, colorSpace: colorSpace, setCustomTargetVideoBitrateValue: setCustomTargetVideoBitrateValue, setQualityControl: setQualityControl, videoImageFormat: videoImageFormat, stillImageFormat: stillImageFormat, shouldDisplayQualityControlPicker: supportsBothQualityControls, encodingBufferSize: encodingBufferSize, setEncodingBufferSize: setEncodingBufferSize, encodingMaxRate: encodingMaxRate, setEncodingMaxRate: setEncodingMaxRate, compositionWidth: resolvedComposition.width, compositionHeight: resolvedComposition.height })) : tab === 'audio' ? (jsx_runtime_1.jsx(RenderModalAudio_1.RenderModalAudio, { muted: muted, renderMode: renderMode, setMuted: setMuted, codec: codec, audioCodec: audioCodec, setAudioCodec: setAudioCodec, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrackState: setEnforceAudioTrackState, customTargetAudioBitrate: customTargetAudioBitrate, setCustomTargetAudioBitrateValue: setCustomTargetAudioBitrateValue, setShouldHaveCustomTargetAudioBitrate: setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate: shouldHaveCustomTargetAudioBitrate, forSeamlessAacConcatenation: forSeamlessAacConcatenation, setForSeamlessAacConcatenation: setForSeamlessAacConcatenation, separateAudioTo: separateAudioTo, setSeparateAudioTo: setSeparateAudioTo, outName: outName })) : tab === 'gif' ? (jsx_runtime_1.jsx(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? (jsx_runtime_1.jsx(DataEditor_1.DataEditor, { defaultProps: inputProps, setDefaultProps: setInputProps, unresolvedComposition: unresolvedComposition, propsEditType: "input-props", canSaveDefaultProps: {
995
+ "Other"] })) : null] }), jsx_runtime_1.jsx("div", { style: render_modals_1.optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? (jsx_runtime_1.jsx(RenderModalBasic_1.RenderModalBasic, { codec: codec, resolvedComposition: resolvedComposition, frame: frame, imageFormatOptions: imageFormatOptions, outName: outName, proResProfile: proResProfile, renderMode: renderMode, setVideoCodec: setCodec, setFrame: setFrame, setOutName: setOutName, setProResProfile: setProResProfile, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, setVerboseLogging: setLogLevel, logLevel: logLevel, showOutputName: !readOnlyStudio, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? (jsx_runtime_1.jsx(RenderModalPicture_1.RenderModalPicture, { renderMode: renderMode, scale: scale, setScale: setScale, pixelFormat: pixelFormat, pixelFormatOptions: pixelFormatOptions, imageFormatOptions: imageFormatOptions, crf: crf, setCrf: setCrf, customTargetVideoBitrate: customTargetVideoBitrate, maxCrf: maxCrf, minCrf: minCrf, jpegQuality: jpegQuality, qualityControlType: qualityControlType, setJpegQuality: setJpegQuality, setColorSpace: setColorSpace, colorSpace: colorSpace, setCustomTargetVideoBitrateValue: setCustomTargetVideoBitrateValue, setQualityControl: setQualityControl, videoImageFormat: videoImageFormat, stillImageFormat: stillImageFormat, shouldDisplayQualityControlPicker: supportsBothQualityControls, encodingBufferSize: encodingBufferSize, setEncodingBufferSize: setEncodingBufferSize, encodingMaxRate: encodingMaxRate, setEncodingMaxRate: setEncodingMaxRate, compositionWidth: resolvedComposition.width, compositionHeight: resolvedComposition.height })) : tab === 'audio' ? (jsx_runtime_1.jsx(RenderModalAudio_1.RenderModalAudio, { muted: muted, renderMode: renderMode, setMuted: setMuted, codec: codec, audioCodec: audioCodec, setAudioCodec: setAudioCodec, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrackState: setEnforceAudioTrackState, customTargetAudioBitrate: customTargetAudioBitrate, setCustomTargetAudioBitrateValue: setCustomTargetAudioBitrateValue, setShouldHaveCustomTargetAudioBitrate: setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate: shouldHaveCustomTargetAudioBitrate, forSeamlessAacConcatenation: forSeamlessAacConcatenation, setForSeamlessAacConcatenation: setForSeamlessAacConcatenation, separateAudioTo: separateAudioTo, setSeparateAudioTo: setSeparateAudioTo, outName: outName, sampleRate: sampleRate, setSampleRate: setSampleRate })) : tab === 'gif' ? (jsx_runtime_1.jsx(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? (jsx_runtime_1.jsx(DataEditor_1.DataEditor, { defaultProps: inputProps, setDefaultProps: setInputProps, unresolvedComposition: unresolvedComposition, propsEditType: "input-props", canSaveDefaultProps: {
991
996
  canUpdate: false,
992
997
  reason: 'render dialogue',
993
998
  determined: false,
@@ -80,7 +80,7 @@ const validateOutnameForStill = ({ outName, stillImageFormat, }) => {
80
80
  // TODO: Shortcut: Shift + R
81
81
  // TODO: Apply defaultCodec
82
82
  // TODO: Apply defaultOutName
83
- const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark, initialLogLevel, initialLicenseKey, initialStillImageFormat, initialDefaultOutName, initialScale, initialDelayRenderTimeout, initialMediaCacheSizeInBytes, initialContainer, initialVideoCodec, initialAudioCodec, initialAudioBitrate, initialVideoBitrate, initialHardwareAcceleration, initialKeyframeIntervalInSeconds, initialTransparent, initialMuted, }) => {
83
+ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark, initialLogLevel, initialLicenseKey, initialStillImageFormat, initialDefaultOutName, initialScale, initialDelayRenderTimeout, initialMediaCacheSizeInBytes, initialContainer, initialVideoCodec, initialAudioCodec, initialAudioBitrate, initialVideoBitrate, initialHardwareAcceleration, initialKeyframeIntervalInSeconds, initialTransparent, initialMuted, initialAllowHtmlInCanvas, }) => {
84
84
  var _a;
85
85
  const context = (0, react_1.useContext)(ResolveCompositionBeforeModal_1.ResolvedCompositionContext);
86
86
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
@@ -124,6 +124,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
124
124
  const [muted, setMuted] = (0, react_1.useState)(initialMuted !== null && initialMuted !== void 0 ? initialMuted : false);
125
125
  const [scale, setScale] = (0, react_1.useState)(initialScale !== null && initialScale !== void 0 ? initialScale : 1);
126
126
  const [licenseKey, setLicenseKey] = (0, react_1.useState)(initialLicenseKey);
127
+ const [allowHtmlInCanvas, setAllowHtmlInCanvas] = (0, react_1.useState)(initialAllowHtmlInCanvas !== null && initialAllowHtmlInCanvas !== void 0 ? initialAllowHtmlInCanvas : false);
127
128
  const encodableAudioCodecs = (0, use_encodable_audio_codecs_1.useEncodableAudioCodecs)(container);
128
129
  const encodableVideoCodecs = (0, use_encodable_video_codecs_1.useEncodableVideoCodecs)(container);
129
130
  const effectiveAudioCodec = (0, react_1.useMemo)(() => {
@@ -336,6 +337,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
336
337
  logLevel,
337
338
  licenseKey,
338
339
  scale,
340
+ allowHtmlInCanvas,
339
341
  }, compositionRef);
340
342
  }
341
343
  else {
@@ -362,6 +364,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
362
364
  logLevel,
363
365
  licenseKey,
364
366
  scale,
367
+ allowHtmlInCanvas,
365
368
  }, compositionRef);
366
369
  }
367
370
  setSidebarCollapsedState({ left: null, right: 'expanded' });
@@ -402,6 +405,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
402
405
  addClientStillJob,
403
406
  addClientVideoJob,
404
407
  scale,
408
+ allowHtmlInCanvas,
405
409
  ]);
406
410
  return (jsx_runtime_1.jsxs("div", { style: render_modals_1.outerModalStyle, children: [
407
411
  jsx_runtime_1.jsx(ModalHeader_1.ModalHeader, { title: `Render ${resolvedComposition.id}` }), jsx_runtime_1.jsxs("div", { style: render_modals_1.container, children: [
@@ -426,7 +430,7 @@ const WebRenderModal = ({ initialFrame, defaultProps, inFrameMark, outFrameMark,
426
430
  canUpdate: false,
427
431
  reason: 'render dialogue',
428
432
  determined: false,
429
- } })) : tab === 'picture' ? (jsx_runtime_1.jsx(WebRenderModalPicture_1.WebRenderModalPicture, { renderMode: renderMode, videoBitrate: videoBitrate, setVideoBitrate: setVideoBitrate, keyframeIntervalInSeconds: keyframeIntervalInSeconds, setKeyframeIntervalInSeconds: setKeyframeIntervalInSeconds, transparent: transparent, setTransparent: setTransparent, scale: scale, setScale: setScale, compositionWidth: resolvedComposition.width, compositionHeight: resolvedComposition.height })) : tab === 'audio' ? (jsx_runtime_1.jsx(WebRenderModalAudio_1.WebRenderModalAudio, { renderMode: renderMode, muted: muted, setMuted: setMuted, audioCodec: audioCodec, setAudioCodec: setAudioCodec, audioBitrate: audioBitrate, setAudioBitrate: setAudioBitrate, container: container, encodableCodecs: encodableAudioCodecs, effectiveAudioCodec: effectiveAudioCodec })) : tab === 'advanced' ? (jsx_runtime_1.jsx(WebRenderModalAdvanced_1.WebRenderModalAdvanced, { renderMode: renderMode, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, mediaCacheSizeInBytes: mediaCacheSizeInBytes, setMediaCacheSizeInBytes: setMediaCacheSizeInBytes, hardwareAcceleration: hardwareAcceleration, setHardwareAcceleration: setHardwareAcceleration })) : (jsx_runtime_1.jsx(WebRenderModalLicense_1.WebRenderModalLicense, { licenseKey: licenseKey, setLicenseKey: setLicenseKey, initialPublicLicenseKey: initialLicenseKey })) })
433
+ } })) : tab === 'picture' ? (jsx_runtime_1.jsx(WebRenderModalPicture_1.WebRenderModalPicture, { renderMode: renderMode, videoBitrate: videoBitrate, setVideoBitrate: setVideoBitrate, keyframeIntervalInSeconds: keyframeIntervalInSeconds, setKeyframeIntervalInSeconds: setKeyframeIntervalInSeconds, transparent: transparent, setTransparent: setTransparent, scale: scale, setScale: setScale, compositionWidth: resolvedComposition.width, compositionHeight: resolvedComposition.height })) : tab === 'audio' ? (jsx_runtime_1.jsx(WebRenderModalAudio_1.WebRenderModalAudio, { renderMode: renderMode, muted: muted, setMuted: setMuted, audioCodec: audioCodec, setAudioCodec: setAudioCodec, audioBitrate: audioBitrate, setAudioBitrate: setAudioBitrate, container: container, encodableCodecs: encodableAudioCodecs, effectiveAudioCodec: effectiveAudioCodec })) : tab === 'advanced' ? (jsx_runtime_1.jsx(WebRenderModalAdvanced_1.WebRenderModalAdvanced, { renderMode: renderMode, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, mediaCacheSizeInBytes: mediaCacheSizeInBytes, setMediaCacheSizeInBytes: setMediaCacheSizeInBytes, hardwareAcceleration: hardwareAcceleration, setHardwareAcceleration: setHardwareAcceleration, allowHtmlInCanvas: allowHtmlInCanvas, setAllowHtmlInCanvas: setAllowHtmlInCanvas })) : (jsx_runtime_1.jsx(WebRenderModalLicense_1.WebRenderModalLicense, { licenseKey: licenseKey, setLicenseKey: setLicenseKey, initialPublicLicenseKey: initialLicenseKey })) })
430
434
  ] })
431
435
  ] }));
432
436
  };
@@ -8,6 +8,8 @@ type WebRenderModalAdvancedProps = {
8
8
  readonly setMediaCacheSizeInBytes: React.Dispatch<React.SetStateAction<number | null>>;
9
9
  readonly hardwareAcceleration: 'no-preference' | 'prefer-hardware' | 'prefer-software';
10
10
  readonly setHardwareAcceleration: (value: 'no-preference' | 'prefer-hardware' | 'prefer-software') => void;
11
+ readonly allowHtmlInCanvas: boolean;
12
+ readonly setAllowHtmlInCanvas: React.Dispatch<React.SetStateAction<boolean>>;
11
13
  };
12
14
  export declare const WebRenderModalAdvanced: React.FC<WebRenderModalAdvancedProps>;
13
15
  export {};
@@ -13,7 +13,7 @@ const OptionExplainerBubble_1 = require("./OptionExplainerBubble");
13
13
  const tabContainer = {
14
14
  flex: 1,
15
15
  };
16
- const WebRenderModalAdvanced = ({ renderMode, delayRenderTimeout, setDelayRenderTimeout, mediaCacheSizeInBytes, setMediaCacheSizeInBytes, hardwareAcceleration, setHardwareAcceleration, }) => {
16
+ const WebRenderModalAdvanced = ({ renderMode, delayRenderTimeout, setDelayRenderTimeout, mediaCacheSizeInBytes, setMediaCacheSizeInBytes, hardwareAcceleration, setHardwareAcceleration, allowHtmlInCanvas, setAllowHtmlInCanvas, }) => {
17
17
  const toggleCustomMediaCacheSizeInBytes = (0, react_1.useCallback)(() => {
18
18
  setMediaCacheSizeInBytes((previous) => {
19
19
  if (previous === null) {
@@ -22,6 +22,9 @@ const WebRenderModalAdvanced = ({ renderMode, delayRenderTimeout, setDelayRender
22
22
  return null;
23
23
  });
24
24
  }, [setMediaCacheSizeInBytes]);
25
+ const toggleAllowHtmlInCanvas = (0, react_1.useCallback)(() => {
26
+ setAllowHtmlInCanvas((prev) => !prev);
27
+ }, [setAllowHtmlInCanvas]);
25
28
  const changeMediaCacheSizeInBytes = (0, react_1.useCallback)((cb) => {
26
29
  setMediaCacheSizeInBytes((prev) => {
27
30
  if (prev === null) {
@@ -77,6 +80,11 @@ const WebRenderModalAdvanced = ({ renderMode, delayRenderTimeout, setDelayRender
77
80
  ] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: mediaCacheSizeInBytes !== null, onChange: toggleCustomMediaCacheSizeInBytes, name: "media-cache-size" }) })
78
81
  ] }), mediaCacheSizeInBytes === null ? null : (jsx_runtime_1.jsx(NumberSetting_1.NumberSetting, { name: "@remotion/media cache size", formatter: (w) => `${w} bytes`, min: 0, max: 10000000000, step: 10 * 1024 * 1024, value: mediaCacheSizeInBytes, onValueChanged: changeMediaCacheSizeInBytes })), renderMode === 'video' ? (jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
79
82
  jsx_runtime_1.jsx("div", { style: layout_2.label, children: "Hardware Acceleration" }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(ComboBox_1.Combobox, { values: hardwareAccelerationOptions, selectedId: hardwareAcceleration, title: "Hardware Acceleration" }) })
80
- ] })) : null] }));
83
+ ] })) : null, jsx_runtime_1.jsxs("div", { style: layout_2.optionRow, children: [
84
+ jsx_runtime_1.jsxs("div", { style: layout_2.label, children: ["Allow HTML-in-canvas ",
85
+ jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(OptionExplainerBubble_1.OptionExplainerBubble, { id: "allowHtmlInCanvasOption" })
86
+ ] }), jsx_runtime_1.jsx("div", { style: layout_2.rightRow, children: jsx_runtime_1.jsx(Checkbox_1.Checkbox, { checked: allowHtmlInCanvas, onChange: toggleAllowHtmlInCanvas, name: "allow-html-in-canvas" }) })
87
+ ] })
88
+ ] }));
81
89
  };
82
90
  exports.WebRenderModalAdvanced = WebRenderModalAdvanced;
@@ -25,7 +25,7 @@ const ClientRenderQueueProcessor = () => {
25
25
  if (!compositionRef) {
26
26
  throw new Error(`Composition not found for job ${job.id}`);
27
27
  }
28
- const { blob } = await (0, web_renderer_1.renderStillOnWeb)({
28
+ const blob = await (await (0, web_renderer_1.renderStillOnWeb)({
29
29
  composition: {
30
30
  component: compositionRef.component,
31
31
  width: compositionRef.width,
@@ -37,7 +37,6 @@ const ClientRenderQueueProcessor = () => {
37
37
  id: job.compositionId,
38
38
  },
39
39
  frame: job.frame,
40
- imageFormat: job.imageFormat,
41
40
  inputProps: job.inputProps,
42
41
  delayRenderTimeoutInMilliseconds: job.delayRenderTimeout,
43
42
  mediaCacheSizeInBytes: job.mediaCacheSizeInBytes,
@@ -45,7 +44,8 @@ const ClientRenderQueueProcessor = () => {
45
44
  licenseKey: (_b = job.licenseKey) !== null && _b !== void 0 ? _b : undefined,
46
45
  scale: job.scale,
47
46
  signal,
48
- });
47
+ allowHtmlInCanvas: job.allowHtmlInCanvas,
48
+ })).blob({ format: job.imageFormat });
49
49
  return {
50
50
  getBlob: () => Promise.resolve(blob),
51
51
  width: compositionRef.width,
@@ -97,6 +97,7 @@ const ClientRenderQueueProcessor = () => {
97
97
  },
98
98
  outputTarget: 'web-fs',
99
99
  licenseKey: (_c = job.licenseKey) !== null && _c !== void 0 ? _c : undefined,
100
+ allowHtmlInCanvas: job.allowHtmlInCanvas,
100
101
  });
101
102
  return {
102
103
  getBlob,
@@ -43,7 +43,7 @@ export declare const addSequenceRenderJob: ({ compositionId, outName, imageForma
43
43
  chromeMode: "chrome-for-testing" | "headless-shell";
44
44
  mediaCacheSizeInBytes: number | null;
45
45
  }) => Promise<undefined>;
46
- export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat, jpegQuality, scale, logLevel, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, colorSpace, multiProcessOnLinux, encodingMaxRate, encodingBufferSize, beepOnFinish, repro, forSeamlessAacConcatenation, separateAudioTo, metadata, hardwareAcceleration, chromeMode, mediaCacheSizeInBytes, }: {
46
+ export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat, jpegQuality, scale, logLevel, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, colorSpace, multiProcessOnLinux, encodingMaxRate, encodingBufferSize, beepOnFinish, repro, forSeamlessAacConcatenation, separateAudioTo, metadata, hardwareAcceleration, chromeMode, mediaCacheSizeInBytes, sampleRate, }: {
47
47
  compositionId: string;
48
48
  outName: string;
49
49
  imageFormat: "jpeg" | "none" | "png";
@@ -84,6 +84,7 @@ export declare const addVideoRenderJob: ({ compositionId, outName, imageFormat,
84
84
  hardwareAcceleration: "disable" | "if-possible" | "required";
85
85
  chromeMode: "chrome-for-testing" | "headless-shell";
86
86
  mediaCacheSizeInBytes: number | null;
87
+ sampleRate: number;
87
88
  }) => Promise<undefined>;
88
89
  export declare const unsubscribeFromFileExistenceWatcher: ({ file, clientId, }: {
89
90
  file: string;
@@ -63,7 +63,7 @@ const addSequenceRenderJob = ({ compositionId, outName, imageFormat, startFrame,
63
63
  });
64
64
  };
65
65
  exports.addSequenceRenderJob = addSequenceRenderJob;
66
- const addVideoRenderJob = ({ compositionId, outName, imageFormat, jpegQuality, scale, logLevel, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, colorSpace, multiProcessOnLinux, encodingMaxRate, encodingBufferSize, beepOnFinish, repro, forSeamlessAacConcatenation, separateAudioTo, metadata, hardwareAcceleration, chromeMode, mediaCacheSizeInBytes, }) => {
66
+ const addVideoRenderJob = ({ compositionId, outName, imageFormat, jpegQuality, scale, logLevel, codec, concurrency, crf, startFrame, endFrame, muted, enforceAudioTrack, proResProfile, x264Preset, pixelFormat, audioBitrate, videoBitrate, everyNthFrame, numberOfGifLoops, delayRenderTimeout, audioCodec, disallowParallelEncoding, chromiumOptions, envVariables, inputProps, offthreadVideoCacheSizeInBytes, offthreadVideoThreads, colorSpace, multiProcessOnLinux, encodingMaxRate, encodingBufferSize, beepOnFinish, repro, forSeamlessAacConcatenation, separateAudioTo, metadata, hardwareAcceleration, chromeMode, mediaCacheSizeInBytes, sampleRate, }) => {
67
67
  return (0, call_api_1.callApi)('/api/render', {
68
68
  compositionId,
69
69
  type: 'video',
@@ -110,6 +110,7 @@ const addVideoRenderJob = ({ compositionId, outName, imageFormat, jpegQuality, s
110
110
  hardwareAcceleration,
111
111
  chromeMode,
112
112
  mediaCacheSizeInBytes,
113
+ sampleRate,
113
114
  });
114
115
  };
115
116
  exports.addVideoRenderJob = addVideoRenderJob;
@@ -40,6 +40,7 @@ type ClientRenderJobBase = {
40
40
  logLevel: LogLevel;
41
41
  licenseKey: string | null;
42
42
  scale: number;
43
+ allowHtmlInCanvas: boolean;
43
44
  };
44
45
  export type ClientStillRenderJob = ClientRenderJobBase & {
45
46
  type: 'client-still';
@@ -76,6 +76,7 @@ const SidebarRenderButton = ({ composition, visible }) => {
76
76
  renderTypeOfLastRender: null,
77
77
  defaulMetadata: defaults.metadata,
78
78
  initialHardwareAcceleration: defaults.hardwareAcceleration,
79
+ initialSampleRate: defaults.sampleRate,
79
80
  initialChromeMode: defaults.chromeMode,
80
81
  initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
81
82
  renderDefaults: defaults,
@@ -26,7 +26,8 @@ exports.getErrorRecord = getErrorRecord;
26
26
  const crashWithFrames = (crash) => (error) => {
27
27
  var _a;
28
28
  const didHookOrderChange = error.message.startsWith('Rendered fewer hooks') ||
29
- error.message.startsWith('Rendered more hooks');
29
+ error.message.startsWith('Rendered more hooks') ||
30
+ error.message.startsWith('Should have a queue');
30
31
  const key = 'remotion.lastCrashBecauseOfHooks';
31
32
  const previousCrashWasBecauseOfHooks = window.localStorage.getItem(key);
32
33
  // When rendering conditional hooks, refreshing does not help.