@remotion/studio 4.0.122 → 4.0.124

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 (40) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/components/AssetSelector.d.ts +3 -1
  3. package/dist/components/AssetSelector.js +29 -2
  4. package/dist/components/AssetSelectorItem.d.ts +2 -0
  5. package/dist/components/AssetSelectorItem.js +27 -4
  6. package/dist/components/ExplorerPanel.d.ts +3 -1
  7. package/dist/components/ExplorerPanel.js +2 -2
  8. package/dist/components/Modals.js +1 -1
  9. package/dist/components/NewComposition/RemInput.d.ts +1 -1
  10. package/dist/components/RenderButton.js +1 -0
  11. package/dist/components/RenderModal/RenderModal.d.ts +1 -0
  12. package/dist/components/RenderModal/RenderModal.js +22 -14
  13. package/dist/components/RenderModal/RenderModalAudio.d.ts +5 -0
  14. package/dist/components/RenderModal/RenderModalAudio.js +14 -3
  15. package/dist/components/RenderModal/RenderModalBasic.js +2 -2
  16. package/dist/components/RenderModal/RenderModalOutputName.d.ts +11 -0
  17. package/dist/components/RenderModal/RenderModalOutputName.js +12 -0
  18. package/dist/components/RenderModal/SeparateAudioOption.d.ts +13 -0
  19. package/dist/components/RenderModal/SeparateAudioOption.js +42 -0
  20. package/dist/components/RenderModal/get-string-before-suffix.d.ts +1 -0
  21. package/dist/components/RenderModal/get-string-before-suffix.js +11 -0
  22. package/dist/components/RenderModal/human-readable-codec.d.ts +1 -1
  23. package/dist/components/RenderModal/human-readable-codec.js +4 -0
  24. package/dist/components/RenderModal/out-name-checker.d.ts +6 -1
  25. package/dist/components/RenderModal/out-name-checker.js +36 -4
  26. package/dist/components/RenderQueue/actions.d.ts +3 -1
  27. package/dist/components/RenderQueue/actions.js +3 -1
  28. package/dist/components/SidebarRenderButton.js +1 -0
  29. package/dist/components/TopPanel.js +1 -1
  30. package/dist/components/utils.d.ts +1 -0
  31. package/dist/components/utils.js +53 -0
  32. package/dist/helpers/colors.d.ts +1 -1
  33. package/dist/helpers/convert-env-variables.d.ts +8 -2
  34. package/dist/helpers/render-modal-sections.d.ts +0 -1
  35. package/dist/helpers/retry-payload.js +3 -0
  36. package/dist/helpers/use-asset-drag-events.d.ts +12 -0
  37. package/dist/helpers/use-asset-drag-events.js +38 -0
  38. package/dist/state/modals.d.ts +1 -0
  39. package/package.json +7 -7
  40. package/tsconfig.tsbuildinfo +1 -1
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @remotion/studio@4.0.121 build /Users/jonathanburger/remotion/packages/studio
3
+ > @remotion/studio@4.0.123 build /Users/jonathanburger/remotion/packages/studio
4
4
  > tsc -d
5
5
 
@@ -1,2 +1,4 @@
1
1
  import React from 'react';
2
- export declare const AssetSelector: React.FC;
2
+ export declare const AssetSelector: React.FC<{
3
+ readOnlyStudio: boolean;
4
+ }>;
@@ -22,6 +22,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
25
28
  Object.defineProperty(exports, "__esModule", { value: true });
26
29
  exports.AssetSelector = void 0;
27
30
  const jsx_runtime_1 = require("react/jsx-runtime");
@@ -31,10 +34,12 @@ const client_id_1 = require("../helpers/client-id");
31
34
  const colors_1 = require("../helpers/colors");
32
35
  const create_folder_tree_1 = require("../helpers/create-folder-tree");
33
36
  const persist_open_folders_1 = require("../helpers/persist-open-folders");
37
+ const use_asset_drag_events_1 = __importDefault(require("../helpers/use-asset-drag-events"));
34
38
  const folders_1 = require("../state/folders");
35
39
  const z_index_1 = require("../state/z-index");
36
40
  const AssetSelectorItem_1 = require("./AssetSelectorItem");
37
41
  const styles_1 = require("./Menu/styles");
42
+ const utils_1 = require("./utils");
38
43
  const container = {
39
44
  display: 'flex',
40
45
  flexDirection: 'column',
@@ -60,10 +65,14 @@ const list = {
60
65
  height: '100%',
61
66
  overflowY: 'auto',
62
67
  };
63
- const AssetSelector = () => {
68
+ const AssetSelector = ({ readOnlyStudio }) => {
64
69
  const { tabIndex } = (0, z_index_1.useZIndex)();
65
70
  const { assetFoldersExpanded, setAssetFoldersExpanded } = (0, react_1.useContext)(folders_1.FolderContext);
71
+ const [dropLocation, setDropLocation] = (0, react_1.useState)(null);
66
72
  const { subscribeToEvent } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
73
+ const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
74
+ .previewServerState.type;
75
+ const shouldAllowUpload = connectionStatus === 'connected' && !readOnlyStudio;
67
76
  const [{ publicFolderExists, staticFiles }, setState] = react_1.default.useState(() => {
68
77
  return {
69
78
  staticFiles: (0, remotion_1.getStaticFiles)(),
@@ -98,6 +107,24 @@ const AssetSelector = () => {
98
107
  return foldersExpandedState;
99
108
  });
100
109
  }, [setAssetFoldersExpanded]);
101
- return ((0, jsx_runtime_1.jsx)("div", { style: container, children: staticFiles.length === 0 ? (publicFolderExists ? ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, place a file in the", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " folder of your project."] }) })) : ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, create a folder called", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " in the root of your project and place a file in it."] }) }))) : ((0, jsx_runtime_1.jsx)("div", { className: "__remotion-vertical-scrollbar", style: list, children: (0, jsx_runtime_1.jsx)(AssetSelectorItem_1.AssetFolderTree, { item: assetTree, level: 0, parentFolder: null, name: null, tabIndex: tabIndex, toggleFolder: toggleFolder }) })) }));
110
+ const { isDropDiv, onDragEnter, onDragLeave } = (0, use_asset_drag_events_1.default)({
111
+ name: null,
112
+ parentFolder: null,
113
+ dropLocation,
114
+ setDropLocation,
115
+ });
116
+ const onDragOver = (0, react_1.useCallback)((e) => {
117
+ e.preventDefault();
118
+ }, []);
119
+ const onDrop = (0, react_1.useCallback)((e) => {
120
+ e.preventDefault();
121
+ e.stopPropagation();
122
+ (0, utils_1.handleUploadFile)(e.dataTransfer.files[0], dropLocation || '/');
123
+ setDropLocation(null);
124
+ }, [dropLocation]);
125
+ return ((0, jsx_runtime_1.jsx)("div", { style: container, onDragOver: shouldAllowUpload ? onDragOver : undefined, onDrop: shouldAllowUpload ? onDrop : undefined, children: staticFiles.length === 0 ? (publicFolderExists ? ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, place a file in the", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " folder of your project or drag and drop a file here."] }) })) : ((0, jsx_runtime_1.jsx)("div", { style: emptyState, children: (0, jsx_runtime_1.jsxs)("div", { style: label, children: ["To add assets, create a folder called", ' ', (0, jsx_runtime_1.jsx)("code", { style: styles_1.inlineCodeSnippet, children: "public" }), " in the root of your project and place a file in it."] }) }))) : ((0, jsx_runtime_1.jsx)("div", { className: "__remotion-vertical-scrollbar", style: {
126
+ ...list,
127
+ backgroundColor: isDropDiv ? colors_1.CLEAR_HOVER : colors_1.BACKGROUND,
128
+ }, onDragEnter: onDragEnter, onDragLeave: onDragLeave, children: (0, jsx_runtime_1.jsx)(AssetSelectorItem_1.AssetFolderTree, { item: assetTree, level: 0, parentFolder: null, name: null, tabIndex: tabIndex, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }) })) }));
102
129
  };
103
130
  exports.AssetSelector = AssetSelector;
@@ -7,4 +7,6 @@ export declare const AssetFolderTree: React.FC<{
7
7
  level: number;
8
8
  tabIndex: number;
9
9
  toggleFolder: (folderName: string, parentName: string | null) => void;
10
+ dropLocation: string | null;
11
+ setDropLocation: React.Dispatch<React.SetStateAction<string | null>>;
10
12
  }>;
@@ -22,6 +22,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
25
28
  Object.defineProperty(exports, "__esModule", { value: true });
26
29
  exports.AssetFolderTree = void 0;
27
30
  const jsx_runtime_1 = require("react/jsx-runtime");
@@ -31,6 +34,7 @@ const no_react_1 = require("remotion/no-react");
31
34
  const colors_1 = require("../helpers/colors");
32
35
  const copy_text_1 = require("../helpers/copy-text");
33
36
  const url_state_1 = require("../helpers/url-state");
37
+ const use_asset_drag_events_1 = __importDefault(require("../helpers/use-asset-drag-events"));
34
38
  const clipboard_1 = require("../icons/clipboard");
35
39
  const file_1 = require("../icons/file");
36
40
  const folder_1 = require("../icons/folder");
@@ -75,8 +79,15 @@ const revealIconStyle = {
75
79
  height: 12,
76
80
  color: 'currentColor',
77
81
  };
78
- const AssetFolderItem = ({ tabIndex, item, level, parentFolder, toggleFolder }) => {
82
+ const AssetFolderItem = ({ tabIndex, item, level, parentFolder, toggleFolder, dropLocation, setDropLocation, }) => {
79
83
  const [hovered, setHovered] = (0, react_1.useState)(false);
84
+ const openFolderTimerRef = (0, react_1.useRef)(null);
85
+ const { isDropDiv, onDragEnter, onDragLeave } = (0, use_asset_drag_events_1.default)({
86
+ name: item.name,
87
+ parentFolder,
88
+ dropLocation,
89
+ setDropLocation,
90
+ });
80
91
  const onPointerEnter = (0, react_1.useCallback)(() => {
81
92
  setHovered(true);
82
93
  }, []);
@@ -100,14 +111,26 @@ const AssetFolderItem = ({ tabIndex, item, level, parentFolder, toggleFolder })
100
111
  toggleFolder(item.name, parentFolder);
101
112
  }, [item.name, parentFolder, toggleFolder]);
102
113
  const Icon = item.expanded ? folder_1.ExpandedFolderIcon : folder_1.CollapsedFolderIcon;
103
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: folderStyle, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, title: item.name, onClick: onClick, children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { children: [(0, jsx_runtime_1.jsx)(Icon, { style: iconStyle, color: hovered ? 'white' : colors_1.LIGHT_TEXT }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.name })] }) }), item.expanded ? ((0, jsx_runtime_1.jsx)(exports.AssetFolderTree, { item: item.items, name: item.name, level: level, parentFolder: parentFolder, tabIndex: tabIndex, toggleFolder: toggleFolder }, item.name)) : null] }));
114
+ return ((0, jsx_runtime_1.jsxs)("div", { onDragEnter: onDragEnter, onDragLeave: onDragLeave, style: {
115
+ backgroundColor: isDropDiv ? colors_1.CLEAR_HOVER : colors_1.BACKGROUND,
116
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: folderStyle, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, title: item.name, onClick: onClick, onDragEnter: () => {
117
+ if (!item.expanded) {
118
+ openFolderTimerRef.current = window.setTimeout(() => {
119
+ toggleFolder(item.name, parentFolder);
120
+ }, 1000);
121
+ }
122
+ }, onDragLeave: () => {
123
+ if (openFolderTimerRef.current) {
124
+ clearTimeout(openFolderTimerRef.current);
125
+ }
126
+ }, children: (0, jsx_runtime_1.jsxs)(layout_1.Row, { children: [(0, jsx_runtime_1.jsx)(Icon, { style: iconStyle, color: hovered ? 'white' : colors_1.LIGHT_TEXT }), (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 1 }), (0, jsx_runtime_1.jsx)("div", { style: label, children: item.name })] }) }), item.expanded ? ((0, jsx_runtime_1.jsx)(exports.AssetFolderTree, { item: item.items, name: item.name, level: level, parentFolder: parentFolder, tabIndex: tabIndex, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }, item.name)) : null] }));
104
127
  };
105
- const AssetFolderTree = ({ item, level, name, parentFolder, toggleFolder, tabIndex }) => {
128
+ const AssetFolderTree = ({ item, level, name, parentFolder, toggleFolder, tabIndex, dropLocation, setDropLocation, }) => {
106
129
  const combinedParents = (0, react_1.useMemo)(() => {
107
130
  return [parentFolder, name].filter(no_react_1.NoReactInternals.truthy).join('/');
108
131
  }, [name, parentFolder]);
109
132
  return ((0, jsx_runtime_1.jsxs)("div", { children: [item.folders.map((folder) => {
110
- return ((0, jsx_runtime_1.jsx)(AssetFolderItem, { item: folder, tabIndex: tabIndex, level: level + 1, parentFolder: combinedParents, toggleFolder: toggleFolder }, folder.name));
133
+ return ((0, jsx_runtime_1.jsx)(AssetFolderItem, { item: folder, tabIndex: tabIndex, level: level + 1, parentFolder: combinedParents, toggleFolder: toggleFolder, dropLocation: dropLocation, setDropLocation: setDropLocation }, folder.name));
111
134
  }), item.files.map((file) => {
112
135
  return ((0, jsx_runtime_1.jsx)(AssetSelectorItem, { item: file, tabIndex: tabIndex, level: level, parentFolder: combinedParents }, file.src));
113
136
  })] }));
@@ -3,4 +3,6 @@ export declare const explorerSidebarTabs: import("react").RefObject<{
3
3
  selectAssetsPanel: () => void;
4
4
  selectCompositionPanel: () => void;
5
5
  }>;
6
- export declare const ExplorerPanel: React.FC<{}>;
6
+ export declare const ExplorerPanel: React.FC<{
7
+ readOnlyStudio: boolean;
8
+ }>;
@@ -30,7 +30,7 @@ const persistSelectedOptionsSidebarPanel = (panel) => {
30
30
  localStorage.setItem(localStorageKey, panel);
31
31
  };
32
32
  exports.explorerSidebarTabs = (0, react_1.createRef)();
33
- const ExplorerPanel = () => {
33
+ const ExplorerPanel = ({ readOnlyStudio }) => {
34
34
  const [panel, setPanel] = (0, react_1.useState)(() => getSelectedPanel());
35
35
  const onCompositionsSelected = (0, react_1.useCallback)(() => {
36
36
  setPanel('compositions');
@@ -52,6 +52,6 @@ const ExplorerPanel = () => {
52
52
  },
53
53
  };
54
54
  }, []);
55
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { style: tabsContainer, children: (0, jsx_runtime_1.jsxs)(Tabs_1.Tabs, { children: [(0, jsx_runtime_1.jsx)(Tabs_1.Tab, { selected: panel === 'compositions', onClick: onCompositionsSelected, children: "Compositions" }), (0, jsx_runtime_1.jsx)(Tabs_1.Tab, { selected: panel === 'assets', onClick: onAssetsSelected, children: "Assets" })] }) }), panel === 'compositions' ? (0, jsx_runtime_1.jsx)(CompositionSelector_1.CompositionSelector, {}) : (0, jsx_runtime_1.jsx)(AssetSelector_1.AssetSelector, {})] }));
55
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: "css-reset", children: [(0, jsx_runtime_1.jsx)("div", { style: tabsContainer, children: (0, jsx_runtime_1.jsxs)(Tabs_1.Tabs, { children: [(0, jsx_runtime_1.jsx)(Tabs_1.Tab, { selected: panel === 'compositions', onClick: onCompositionsSelected, children: "Compositions" }), (0, jsx_runtime_1.jsx)(Tabs_1.Tab, { selected: panel === 'assets', onClick: onAssetsSelected, children: "Assets" })] }) }), panel === 'compositions' ? ((0, jsx_runtime_1.jsx)(CompositionSelector_1.CompositionSelector, {})) : ((0, jsx_runtime_1.jsx)(AssetSelector_1.AssetSelector, { readOnlyStudio: readOnlyStudio }))] }));
56
56
  };
57
57
  exports.ExplorerPanel = ExplorerPanel;
@@ -17,7 +17,7 @@ const Modals = ({ readOnlyStudio }) => {
17
17
  const { selectedModal: modalContextType } = (0, react_1.useContext)(modals_1.ModalsContext);
18
18
  const canRender = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx).previewServerState.type ===
19
19
  'connected';
20
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'new-comp' && ((0, jsx_runtime_1.jsx)(NewComposition_1.default, { initialCompType: modalContextType.compType })), modalContextType && canRender && modalContextType.type === 'render' && ((0, jsx_runtime_1.jsx)(RenderModal_1.RenderModalWithLoader, { initialFrame: modalContextType.initialFrame, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialScale: modalContextType.initialScale, initialLogLevel: modalContextType.initialLogLevel, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, 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, defaultProps: modalContextType.defaultProps, inFrameMark: modalContextType.inFrameMark, outFrameMark: modalContextType.outFrameMark, defaultConfigurationAudioCodec: modalContextType.defaultConfigurationAudioCodec, defaultConfigurationVideoCodec: modalContextType.defaultConfigurationVideoCodec })), modalContextType &&
20
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [modalContextType && modalContextType.type === 'new-comp' && ((0, jsx_runtime_1.jsx)(NewComposition_1.default, { initialCompType: modalContextType.compType })), modalContextType && canRender && modalContextType.type === 'render' && ((0, jsx_runtime_1.jsx)(RenderModal_1.RenderModalWithLoader, { initialFrame: modalContextType.initialFrame, compositionId: modalContextType.compositionId, initialVideoImageFormat: modalContextType.initialVideoImageFormat, initialJpegQuality: modalContextType.initialJpegQuality, initialScale: modalContextType.initialScale, initialLogLevel: modalContextType.initialLogLevel, initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes, 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 })), modalContextType &&
21
21
  canRender &&
22
22
  modalContextType.type === 'render-progress' && ((0, jsx_runtime_1.jsx)(RenderStatusModal_1.RenderStatusModal, { jobId: modalContextType.jobId })), modalContextType && modalContextType.type === 'update' && ((0, jsx_runtime_1.jsx)(UpdateModal_1.UpdateModal, { info: modalContextType.info, knownBugs: modalContextType.knownBugs })), modalContextType && modalContextType.type === 'quick-switcher' && ((0, jsx_runtime_1.jsx)(QuickSwitcher_1.default, { readOnlyStudio: readOnlyStudio, invocationTimestamp: modalContextType.invocationTimestamp, initialMode: modalContextType.mode }))] }));
23
23
  };
@@ -12,6 +12,6 @@ export declare const getInputBorderColor: ({ status, isFocused, isHovered, }: {
12
12
  status: 'error' | 'warning' | 'ok';
13
13
  isFocused: boolean;
14
14
  isHovered: boolean;
15
- }) => "hsla(0, 0%, 100%, 0.15)" | "#ff3232" | "#f1c40f" | "rgba(0, 0, 0, 0.6)" | "rgba(255, 255, 255, 0.05)";
15
+ }) => "hsla(0, 0%, 100%, 0.15)" | "rgba(0, 0, 0, 0.6)" | "rgba(255, 255, 255, 0.05)" | "#ff3232" | "#f1c40f";
16
16
  export declare const RemotionInput: React.ForwardRefExoticComponent<Omit<Props, "ref"> & React.RefAttributes<HTMLInputElement>>;
17
17
  export {};
@@ -89,6 +89,7 @@ const RenderButton = () => {
89
89
  initialUserAgent: defaults.userAgent,
90
90
  initialBeep: defaults.beepOnFinish,
91
91
  initialRepro: defaults.repro,
92
+ initialForSeamlessAacConcatenation: defaults.forSeamlessAacConcatenation,
92
93
  });
93
94
  }, [video, setSelectedModal, frame, props, inFrame, outFrame]);
94
95
  if (!video) {
@@ -39,6 +39,7 @@ type RenderModalProps = {
39
39
  initialMultiProcessOnLinux: boolean;
40
40
  defaultConfigurationVideoCodec: Codec | null;
41
41
  defaultConfigurationAudioCodec: AudioCodec | null;
42
+ initialForSeamlessAacConcatenation: boolean;
42
43
  };
43
44
  export declare const RenderModalWithLoader: React.FC<RenderModalProps>;
44
45
  export {};
@@ -34,6 +34,7 @@ const vertical_1 = require("../Tabs/vertical");
34
34
  const CrfSetting_1 = require("./CrfSetting");
35
35
  const DataEditor_1 = require("./DataEditor");
36
36
  const get_default_codecs_1 = require("./get-default-codecs");
37
+ const get_string_before_suffix_1 = require("./get-string-before-suffix");
37
38
  const out_name_checker_1 = require("./out-name-checker");
38
39
  const RenderModalAdvanced_1 = require("./RenderModalAdvanced");
39
40
  const RenderModalAudio_1 = require("./RenderModalAudio");
@@ -117,7 +118,7 @@ const outer = {
117
118
  display: 'flex',
118
119
  flexDirection: 'column',
119
120
  };
120
- const RenderModal = ({ 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, initialUserAgent, defaultProps, inFrameMark, outFrameMark, onClose, resolvedComposition, unresolvedComposition, initialColorSpace, initialMultiProcessOnLinux, defaultConfigurationAudioCodec, defaultConfigurationVideoCodec, initialBeep, initialRepro, }) => {
121
+ const RenderModal = ({ 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, initialUserAgent, defaultProps, inFrameMark, outFrameMark, onClose, resolvedComposition, unresolvedComposition, initialColorSpace, initialMultiProcessOnLinux, defaultConfigurationAudioCodec, defaultConfigurationVideoCodec, initialBeep, initialRepro, initialForSeamlessAacConcatenation, }) => {
121
122
  const isMounted = (0, react_1.useRef)(true);
122
123
  const [isVideo] = (0, react_1.useState)(() => {
123
124
  return typeof resolvedComposition.durationInFrames === 'undefined'
@@ -141,6 +142,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
141
142
  const [concurrency, setConcurrency] = (0, react_1.useState)(() => initialConcurrency);
142
143
  const [videoCodecForVideoTab, setVideoCodecForVideoTab] = (0, react_1.useState)(() => initialVideoCodecForVideoTab);
143
144
  const [userSelectedAudioCodec, setUserSelectedAudioCodec] = (0, react_1.useState)(() => initialAudioCodec);
145
+ const [separateAudioTo, setSeparateAudioTo] = (0, react_1.useState)(null);
144
146
  const [envVariables, setEnvVariables] = (0, react_1.useState)(() => (0, convert_env_variables_1.envVariablesObjectToArray)(initialEnvVariables).filter(([key]) => key !== 'NODE_ENV'));
145
147
  const [initialOutName] = (0, react_1.useState)(() => {
146
148
  return (0, studio_shared_1.getDefaultOutLocation)({
@@ -155,6 +157,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
155
157
  const [mutedState, setMuted] = (0, react_1.useState)(() => initialMuted);
156
158
  const [repro, setRepro] = (0, react_1.useState)(() => initialRepro);
157
159
  const [enforceAudioTrackState, setEnforceAudioTrackState] = (0, react_1.useState)(() => initialEnforceAudioTrack);
160
+ const [forSeamlessAacConcatenation, setForSeamlessAacConcatenation] = (0, react_1.useState)(() => initialForSeamlessAacConcatenation);
158
161
  const [renderMode, setRenderModeState] = (0, react_1.useState)(initialRenderType);
159
162
  const [jpegQuality, setJpegQuality] = (0, react_1.useState)(() => initialJpegQuality);
160
163
  const [scale, setScale] = (0, react_1.useState)(() => initialScale);
@@ -301,14 +304,6 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
301
304
  const parsed = Math.floor(unclampedFrame);
302
305
  return Math.max(0, Math.min(resolvedComposition.durationInFrames - 1, parsed));
303
306
  }, [resolvedComposition.durationInFrames, unclampedFrame]);
304
- const getStringBeforeSuffix = (0, react_1.useCallback)((fileName) => {
305
- const dotPos = fileName.lastIndexOf('.');
306
- if (dotPos === -1) {
307
- return fileName;
308
- }
309
- const bitBeforeDot = fileName.substring(0, dotPos);
310
- return bitBeforeDot;
311
- }, []);
312
307
  const deriveFinalAudioCodec = (0, react_1.useCallback)((passedVideoCodec, passedAudioCodec) => {
313
308
  if (passedAudioCodec !== null &&
314
309
  client_1.BrowserSafeApis.supportedAudioCodecs[passedVideoCodec].includes(passedAudioCodec)) {
@@ -320,24 +315,24 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
320
315
  const setDefaultOutName = (0, react_1.useCallback)((options) => {
321
316
  if (options.type === 'still') {
322
317
  setOutName((prev) => {
323
- const newFileName = getStringBeforeSuffix(prev) + '.' + options.imageFormat;
318
+ const newFileName = (0, get_string_before_suffix_1.getStringBeforeSuffix)(prev) + '.' + options.imageFormat;
324
319
  return newFileName;
325
320
  });
326
321
  }
327
322
  else if (options.type === 'sequence') {
328
323
  setOutName((prev) => {
329
- const folderName = getStringBeforeSuffix(prev);
324
+ const folderName = (0, get_string_before_suffix_1.getStringBeforeSuffix)(prev);
330
325
  return folderName;
331
326
  });
332
327
  }
333
328
  else {
334
329
  setOutName((prev) => {
335
330
  const codecSuffix = client_1.BrowserSafeApis.getFileExtensionFromCodec(options.codec, deriveFinalAudioCodec(options.codec, options.audioCodec));
336
- const newFileName = getStringBeforeSuffix(prev) + '.' + codecSuffix;
331
+ const newFileName = (0, get_string_before_suffix_1.getStringBeforeSuffix)(prev) + '.' + codecSuffix;
337
332
  return newFileName;
338
333
  });
339
334
  }
340
- }, [deriveFinalAudioCodec, getStringBeforeSuffix]);
335
+ }, [deriveFinalAudioCodec]);
341
336
  const setAudioCodec = (0, react_1.useCallback)((newAudioCodec) => {
342
337
  setUserSelectedAudioCodec(newAudioCodec);
343
338
  setDefaultOutName({
@@ -345,6 +340,14 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
345
340
  codec: videoCodecForVideoTab,
346
341
  audioCodec: newAudioCodec,
347
342
  });
343
+ setSeparateAudioTo((prev) => {
344
+ if (prev === null) {
345
+ return null;
346
+ }
347
+ const newExtension = client_1.BrowserSafeApis.getExtensionFromAudioCodec(newAudioCodec);
348
+ const newFileName = (0, get_string_before_suffix_1.getStringBeforeSuffix)(prev) + '.' + newExtension;
349
+ return newFileName;
350
+ });
348
351
  }, [setDefaultOutName, videoCodecForVideoTab]);
349
352
  const setCodec = (0, react_1.useCallback)((newCodec) => {
350
353
  if (renderMode === 'audio') {
@@ -474,6 +477,8 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
474
477
  encodingMaxRate,
475
478
  beepOnFinish,
476
479
  repro,
480
+ forSeamlessAacConcatenation,
481
+ separateAudioTo,
477
482
  })
478
483
  .then(() => {
479
484
  dispatchIfMounted({ type: 'succeed' });
@@ -520,6 +525,8 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
520
525
  encodingMaxRate,
521
526
  beepOnFinish,
522
527
  repro,
528
+ forSeamlessAacConcatenation,
529
+ separateAudioTo,
523
530
  onClose,
524
531
  ]);
525
532
  const onClickSequence = (0, react_1.useCallback)(() => {
@@ -733,6 +740,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
733
740
  audioCodec,
734
741
  renderMode,
735
742
  stillImageFormat,
743
+ separateAudioTo,
736
744
  });
737
745
  const { tab, setTab, shownTabs } = (0, render_modal_sections_1.useRenderModalSections)(renderMode, codec);
738
746
  const { registerKeybinding } = (0, use_keybinding_1.useKeybinding)();
@@ -786,7 +794,7 @@ const RenderModal = ({ initialFrame, initialVideoImageFormat, initialStillImageF
786
794
  return ((0, jsx_runtime_1.jsxs)("div", { style: outer, children: [(0, jsx_runtime_1.jsx)(ModalHeader_1.NewCompHeader, { title: `Render ${resolvedComposition.id}` }), (0, jsx_runtime_1.jsxs)("div", { style: container, children: [(0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: renderTabOptions, needsWrapping: false }), (0, jsx_runtime_1.jsx)("div", { style: flexer }), (0, jsx_runtime_1.jsxs)(Button_1.Button, { autoFocus: true, onClick: trigger, disabled: renderDisabled, style: {
787
795
  ...buttonStyle,
788
796
  backgroundColor: outnameValidation.valid ? colors_1.BLUE : colors_1.BLUE_DISABLED,
789
- }, children: [state.type === 'idle' ? `Render ${renderMode}` : 'Rendering...', (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftSidebar, children: [shownTabs.includes('general') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null, shownTabs.includes('data') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: icon }) }), "Input Props"] })) : null, shownTabs.includes('picture') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null, shownTabs.includes('audio') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null, shownTabs.includes('gif') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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, shownTabs.includes('advanced') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null] }), (0, jsx_runtime_1.jsx)("div", { style: optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, 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, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? ((0, 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 })) : tab === 'audio' ? ((0, 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 })) : tab === 'gif' ? ((0, jsx_runtime_1.jsx)(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { inputProps: inputProps, setInputProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props", saving: saving, setSaving: setSaving, readOnlyStudio: false })) : ((0, jsx_runtime_1.jsx)(RenderModalAdvanced_1.RenderModalAdvanced, { x264Preset: x264Preset, setx264Preset: setx264Preset, concurrency: concurrency, maxConcurrency: maxConcurrency, minConcurrency: minConcurrency, renderMode: renderMode, setConcurrency: setConcurrency, setVerboseLogging: setLogLevel, logLevel: logLevel, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, disallowParallelEncoding: disallowParallelEncoding, setDisallowParallelEncoding: setDisallowParallelEncoding, setDisableWebSecurity: setDisableWebSecurity, setIgnoreCertificateErrors: setIgnoreCertificateErrors, setHeadless: setHeadless, headless: headless, ignoreCertificateErrors: ignoreCertificateErrors, disableWebSecurity: disableWebSecurity, openGlOption: openGlOption, setOpenGlOption: setOpenGlOption, setEnvVariables: setEnvVariables, envVariables: envVariables, offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytes, setOffthreadVideoCacheSizeInBytes: setOffthreadVideoCacheSizeInBytes, enableMultiProcessOnLinux: multiProcessOnLinux, setChromiumMultiProcessOnLinux: setChromiumMultiProcessOnLinux, codec: codec, userAgent: userAgent, setUserAgent: setUserAgent, setBeep: setBeepOnFinish, beep: beepOnFinish, repro: repro, setRepro: setRepro })) })] })] }));
797
+ }, children: [state.type === 'idle' ? `Render ${renderMode}` : 'Rendering...', (0, jsx_runtime_1.jsx)(ShortcutHint_1.ShortcutHint, { keyToPress: "\u21B5", cmdOrCtrl: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: horizontalLayout, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftSidebar, children: [shownTabs.includes('general') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null, shownTabs.includes('data') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { style: horizontalTab, selected: tab === 'data', onClick: () => setTab('data'), children: [(0, jsx_runtime_1.jsx)("div", { style: iconContainer, children: (0, jsx_runtime_1.jsx)(data_1.DataIcon, { style: icon }) }), "Input Props"] })) : null, shownTabs.includes('picture') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null, shownTabs.includes('audio') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null, shownTabs.includes('gif') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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, shownTabs.includes('advanced') ? ((0, jsx_runtime_1.jsxs)(vertical_1.VerticalTab, { 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"] })) : null] }), (0, jsx_runtime_1.jsx)("div", { style: optionsPanel, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: tab === 'general' ? ((0, 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, startFrame: startFrame, validationMessage: outnameValidation.valid ? null : outnameValidation.error.message })) : tab === 'picture' ? ((0, 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 })) : tab === 'audio' ? ((0, 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' ? ((0, jsx_runtime_1.jsx)(RenderModalGif_1.RenderModalGif, { everyNthFrame: everyNthFrame, limitNumberOfGifLoops: limitNumberOfGifLoops, numberOfGifLoopsSetting: numberOfGifLoopsSetting, setEveryNthFrameSetting: setEveryNthFrameSetting, setLimitNumberOfGifLoops: setLimitNumberOfGifLoops, setNumberOfGifLoopsSetting: setNumberOfGifLoopsSetting })) : tab === 'data' ? ((0, jsx_runtime_1.jsx)(DataEditor_1.DataEditor, { inputProps: inputProps, setInputProps: setInputProps, unresolvedComposition: unresolvedComposition, mayShowSaveButton: false, propsEditType: "input-props", saving: saving, setSaving: setSaving, readOnlyStudio: false })) : ((0, jsx_runtime_1.jsx)(RenderModalAdvanced_1.RenderModalAdvanced, { x264Preset: x264Preset, setx264Preset: setx264Preset, concurrency: concurrency, maxConcurrency: maxConcurrency, minConcurrency: minConcurrency, renderMode: renderMode, setConcurrency: setConcurrency, setVerboseLogging: setLogLevel, logLevel: logLevel, delayRenderTimeout: delayRenderTimeout, setDelayRenderTimeout: setDelayRenderTimeout, disallowParallelEncoding: disallowParallelEncoding, setDisallowParallelEncoding: setDisallowParallelEncoding, setDisableWebSecurity: setDisableWebSecurity, setIgnoreCertificateErrors: setIgnoreCertificateErrors, setHeadless: setHeadless, headless: headless, ignoreCertificateErrors: ignoreCertificateErrors, disableWebSecurity: disableWebSecurity, openGlOption: openGlOption, setOpenGlOption: setOpenGlOption, setEnvVariables: setEnvVariables, envVariables: envVariables, offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytes, setOffthreadVideoCacheSizeInBytes: setOffthreadVideoCacheSizeInBytes, enableMultiProcessOnLinux: multiProcessOnLinux, setChromiumMultiProcessOnLinux: setChromiumMultiProcessOnLinux, codec: codec, userAgent: userAgent, setUserAgent: setUserAgent, setBeep: setBeepOnFinish, beep: beepOnFinish, repro: repro, setRepro: setRepro })) })] })] }));
790
798
  };
791
799
  const RenderModalWithLoader = (props) => {
792
800
  const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
@@ -7,6 +7,8 @@ export declare const RenderModalAudio: React.FC<{
7
7
  renderMode: RenderType;
8
8
  enforceAudioTrack: boolean;
9
9
  setEnforceAudioTrackState: React.Dispatch<React.SetStateAction<boolean>>;
10
+ forSeamlessAacConcatenation: boolean;
11
+ setForSeamlessAacConcatenation: React.Dispatch<React.SetStateAction<boolean>>;
10
12
  shouldHaveCustomTargetAudioBitrate: boolean;
11
13
  setShouldHaveCustomTargetAudioBitrate: React.Dispatch<React.SetStateAction<boolean>>;
12
14
  setCustomTargetAudioBitrateValue: React.Dispatch<React.SetStateAction<string>>;
@@ -14,4 +16,7 @@ export declare const RenderModalAudio: React.FC<{
14
16
  audioCodec: AudioCodec;
15
17
  setAudioCodec: (newAudioCodec: AudioCodec) => void;
16
18
  codec: Codec;
19
+ setSeparateAudioTo: React.Dispatch<React.SetStateAction<string | null>>;
20
+ separateAudioTo: string | null;
21
+ outName: string;
17
22
  }>;
@@ -6,24 +6,31 @@ const client_1 = require("@remotion/renderer/client");
6
6
  const react_1 = require("react");
7
7
  const Checkmark_1 = require("../../icons/Checkmark");
8
8
  const Checkbox_1 = require("../Checkbox");
9
+ const layout_1 = require("../layout");
10
+ const is_menu_item_1 = require("../Menu/is-menu-item");
9
11
  const ComboBox_1 = require("../NewComposition/ComboBox");
10
12
  const RemInput_1 = require("../NewComposition/RemInput");
11
13
  const EnforceAudioTrackSetting_1 = require("./EnforceAudioTrackSetting");
12
14
  const human_readable_audio_codecs_1 = require("./human-readable-audio-codecs");
13
- const layout_1 = require("./layout");
15
+ const layout_2 = require("./layout");
14
16
  const MutedSetting_1 = require("./MutedSetting");
15
17
  const OptionExplainerBubble_1 = require("./OptionExplainerBubble");
16
18
  const RenderModalHr_1 = require("./RenderModalHr");
19
+ const SeparateAudioOption_1 = require("./SeparateAudioOption");
17
20
  const container = {
18
21
  flex: 1,
22
+ overflowY: 'auto',
19
23
  };
20
- const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setEnforceAudioTrackState, setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate, setCustomTargetAudioBitrateValue, customTargetAudioBitrate, audioCodec, codec, setAudioCodec, }) => {
24
+ const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setEnforceAudioTrackState, setShouldHaveCustomTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate, setCustomTargetAudioBitrateValue, customTargetAudioBitrate, audioCodec, codec, setAudioCodec, forSeamlessAacConcatenation, setForSeamlessAacConcatenation, separateAudioTo, setSeparateAudioTo, outName, }) => {
21
25
  const onShouldHaveTargetAudioBitrateChanged = (0, react_1.useCallback)((e) => {
22
26
  setShouldHaveCustomTargetAudioBitrate(e.target.checked);
23
27
  }, [setShouldHaveCustomTargetAudioBitrate]);
24
28
  const onTargetAudioBitrateChanged = (0, react_1.useCallback)((e) => {
25
29
  setCustomTargetAudioBitrateValue(e.target.value);
26
30
  }, [setCustomTargetAudioBitrateValue]);
31
+ const onSeamlessAacConcatenationChanges = (0, react_1.useCallback)((e) => {
32
+ setForSeamlessAacConcatenation(e.target.checked);
33
+ }, [setForSeamlessAacConcatenation]);
27
34
  const audioCodecOptions = (0, react_1.useCallback)((currentCodec) => {
28
35
  return client_1.BrowserSafeApis.supportedAudioCodecs[currentCodec].map((audioCodecOption) => {
29
36
  return {
@@ -40,6 +47,10 @@ const RenderModalAudio = ({ muted, setMuted, renderMode, enforceAudioTrack, setE
40
47
  };
41
48
  });
42
49
  }, [codec, setAudioCodec]);
43
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [renderMode === 'video' && audioCodecOptions(codec).length >= 2 ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_1.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_1.label, children: "Audio Codec" }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: audioCodecOptions(codec), selectedId: audioCodec, title: "AudioCodec" }) })] })) : null, renderMode === 'video' ? ((0, jsx_runtime_1.jsx)(MutedSetting_1.MutedSetting, { enforceAudioTrack: enforceAudioTrack, muted: muted, setMuted: setMuted })) : null, (renderMode === 'video' || renderMode === 'audio') && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(EnforceAudioTrackSetting_1.EnforceAudioTrackSetting, { muted: muted, 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.jsxs)("div", { style: layout_1.label, children: ["Custom audio bitrate", ' ', (0, jsx_runtime_1.jsx)(OptionExplainerBubble_1.OptionExplainerBubble, { id: "audioBitrateOption" })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_1.rightRow, children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { checked: shouldHaveCustomTargetAudioBitrate, onChange: onShouldHaveTargetAudioBitrateChanged, name: "custom-audio-bitrate" }) })] })), 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, status: "ok", rightAlign: true }) }) })] })) : null] }));
50
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, className: is_menu_item_1.VERTICAL_SCROLLBAR_CLASSNAME, children: [renderMode === 'video' ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(MutedSetting_1.MutedSetting, { enforceAudioTrack: enforceAudioTrack, muted: muted, setMuted: setMuted }), (0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {})] })) : null, renderMode === 'video' &&
51
+ audioCodecOptions(codec).length >= 2 &&
52
+ !muted ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Audio Codec ", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(OptionExplainerBubble_1.OptionExplainerBubble, { id: "audioCodecOption" })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: audioCodecOptions(codec), selectedId: audioCodec, title: "AudioCodec" }) })] })) : null, (renderMode === 'video' || renderMode === 'audio') && !muted && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(EnforceAudioTrackSetting_1.EnforceAudioTrackSetting, { muted: muted, enforceAudioTrack: enforceAudioTrack, setEnforceAudioTrack: setEnforceAudioTrackState }), (0, jsx_runtime_1.jsx)(RenderModalHr_1.RenderModalHr, {})] })), renderMode === 'video' && !muted ? ((0, jsx_runtime_1.jsx)(SeparateAudioOption_1.SeparateAudioOption, { separateAudioTo: separateAudioTo, setSeparateAudioTo: setSeparateAudioTo, audioCodec: audioCodec, outName: outName })) : null, audioCodec === 'aac' && !muted ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["For seamless AAC concatenation", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(OptionExplainerBubble_1.OptionExplainerBubble, { id: "forSeamlessAacConcatenationOption" })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { disabled: false, checked: forSeamlessAacConcatenation, onChange: onSeamlessAacConcatenationChanges, name: "enforce-audio-track" }) })] })) : null, renderMode === 'still' || muted ? null : ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Custom audio bitrate", ' ', (0, jsx_runtime_1.jsx)(OptionExplainerBubble_1.OptionExplainerBubble, { id: "audioBitrateOption" })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { checked: shouldHaveCustomTargetAudioBitrate, onChange: onShouldHaveTargetAudioBitrateChanged, name: "custom-audio-bitrate" }) })] })), shouldHaveCustomTargetAudioBitrate &&
53
+ renderMode !== 'still' &&
54
+ !muted ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Target audio bitrate" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { style: layout_2.input, value: customTargetAudioBitrate, onChange: onTargetAudioBitrateChanged, status: "ok", rightAlign: true }) }) })] })) : null] }));
44
55
  };
45
56
  exports.RenderModalAudio = RenderModalAudio;
@@ -16,7 +16,7 @@ const FrameRangeSetting_1 = require("./FrameRangeSetting");
16
16
  const human_readable_codec_1 = require("./human-readable-codec");
17
17
  const layout_2 = require("./layout");
18
18
  const OptionExplainerBubble_1 = require("./OptionExplainerBubble");
19
- const RenderModalInput_1 = require("./RenderModalInput");
19
+ const RenderModalOutputName_1 = require("./RenderModalOutputName");
20
20
  const container = {
21
21
  flex: 1,
22
22
  };
@@ -74,6 +74,6 @@ const RenderModalBasic = ({ renderMode, imageFormatOptions, outName, codec, setV
74
74
  const onValueChange = (0, react_1.useCallback)((e) => {
75
75
  setOutName(e.target.value);
76
76
  }, [setOutName]);
77
- return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [renderMode === 'still' || renderMode === 'sequence' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: true }) })] })) : ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Codec", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(OptionExplainerBubble_1.OptionExplainerBubble, { id: "videoCodecOption" })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: videoCodecOptions, selectedId: codec, title: "Codec" }) })] })), renderMode === 'still' && resolvedComposition.durationInFrames > 1 ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Frame" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(RemInput_1.RightAlignInput, { children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: frame, onTextChange: onFrameChanged, placeholder: `0-${resolvedComposition.durationInFrames - 1}`, onValueChange: onFrameSetDirectly, name: "frame", step: 1, min: 0, status: "ok", max: resolvedComposition.durationInFrames - 1, rightAlign: true }) }) })] })) : null, renderMode === 'video' && codec === 'prores' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "ProRes profile" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { title: 'proResProfile', selectedId: proResProfile, values: proResProfileOptions }) })] })) : null, renderMode === 'still' ? null : ((0, jsx_runtime_1.jsx)(FrameRangeSetting_1.FrameRangeSetting, { durationInFrames: resolvedComposition.durationInFrames, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame })), (0, jsx_runtime_1.jsx)(RenderModalInput_1.RenderModalInput, { existence: existence, inputStyle: layout_2.input, outName: outName, onValueChange: onValueChange, validationMessage: validationMessage, renderType: renderMode })] }));
77
+ return ((0, jsx_runtime_1.jsxs)("div", { style: container, children: [renderMode === 'still' || renderMode === 'sequence' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Format" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(SegmentedControl_1.SegmentedControl, { items: imageFormatOptions, needsWrapping: true }) })] })) : ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Codec", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(OptionExplainerBubble_1.OptionExplainerBubble, { id: "videoCodecOption" })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { values: videoCodecOptions, selectedId: codec, title: "Codec" }) })] })), renderMode === 'still' && resolvedComposition.durationInFrames > 1 ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "Frame" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(RemInput_1.RightAlignInput, { children: (0, jsx_runtime_1.jsx)(InputDragger_1.InputDragger, { value: frame, onTextChange: onFrameChanged, placeholder: `0-${resolvedComposition.durationInFrames - 1}`, onValueChange: onFrameSetDirectly, name: "frame", step: 1, min: 0, status: "ok", max: resolvedComposition.durationInFrames - 1, rightAlign: true }) }) })] })) : null, renderMode === 'video' && codec === 'prores' ? ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: "ProRes profile" }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(ComboBox_1.Combobox, { title: 'proResProfile', selectedId: proResProfile, values: proResProfileOptions }) })] })) : null, renderMode === 'still' ? null : ((0, jsx_runtime_1.jsx)(FrameRangeSetting_1.FrameRangeSetting, { durationInFrames: resolvedComposition.durationInFrames, endFrame: endFrame, setEndFrame: setEndFrame, setStartFrame: setStartFrame, startFrame: startFrame })), (0, jsx_runtime_1.jsx)(RenderModalOutputName_1.RenderModalOutputName, { existence: existence, inputStyle: layout_2.input, outName: outName, onValueChange: onValueChange, validationMessage: validationMessage, label: renderMode === 'sequence' ? 'Folder name' : 'Output name' })] }));
78
78
  };
79
79
  exports.RenderModalBasic = RenderModalBasic;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ type Props = {
3
+ existence: boolean;
4
+ inputStyle: React.CSSProperties;
5
+ outName: string;
6
+ onValueChange: React.ChangeEventHandler<HTMLInputElement>;
7
+ validationMessage: string | null;
8
+ label: string;
9
+ };
10
+ export declare const RenderModalOutputName: ({ existence, inputStyle, outName, onValueChange, validationMessage, label: labelText, }: Props) => import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenderModalOutputName = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const layout_1 = require("../layout");
6
+ const RemInput_1 = require("../NewComposition/RemInput");
7
+ const ValidationMessage_1 = require("../NewComposition/ValidationMessage");
8
+ const layout_2 = require("./layout");
9
+ const RenderModalOutputName = ({ existence, inputStyle, outName, onValueChange, validationMessage, label: labelText, }) => {
10
+ return ((0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsx)(layout_1.Column, { children: (0, jsx_runtime_1.jsx)("div", { style: layout_2.label, children: labelText }) }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(RemInput_1.RemotionInput, { status: validationMessage ? 'error' : existence ? 'warning' : 'ok', style: inputStyle, type: "text", value: outName, onChange: onValueChange, rightAlign: true }), validationMessage ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: validationMessage, type: 'error' })] })) : existence ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(layout_1.Spacing, { y: 1, block: true }), (0, jsx_runtime_1.jsx)(ValidationMessage_1.ValidationMessage, { align: "flex-end", message: "Will be overwritten", type: 'warning' })] })) : null] }) })] }));
11
+ };
12
+ exports.RenderModalOutputName = RenderModalOutputName;
@@ -0,0 +1,13 @@
1
+ import type { AudioCodec } from '@remotion/renderer';
2
+ import React from 'react';
3
+ export declare const SeparateAudioOptionInput: React.FC<{
4
+ setSeparateAudioTo: React.Dispatch<React.SetStateAction<string | null>>;
5
+ separateAudioTo: string;
6
+ audioCodec: AudioCodec;
7
+ }>;
8
+ export declare const SeparateAudioOption: React.FC<{
9
+ setSeparateAudioTo: React.Dispatch<React.SetStateAction<string | null>>;
10
+ separateAudioTo: string | null;
11
+ audioCodec: AudioCodec;
12
+ outName: string;
13
+ }>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SeparateAudioOption = exports.SeparateAudioOptionInput = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const client_1 = require("@remotion/renderer/client");
6
+ const react_1 = require("react");
7
+ const use_file_existence_1 = require("../../helpers/use-file-existence");
8
+ const Checkbox_1 = require("../Checkbox");
9
+ const layout_1 = require("../layout");
10
+ const get_string_before_suffix_1 = require("./get-string-before-suffix");
11
+ const layout_2 = require("./layout");
12
+ const OptionExplainerBubble_1 = require("./OptionExplainerBubble");
13
+ const RenderModalOutputName_1 = require("./RenderModalOutputName");
14
+ const SeparateAudioOptionInput = ({ separateAudioTo, setSeparateAudioTo, audioCodec }) => {
15
+ const existence = (0, use_file_existence_1.useFileExistence)(separateAudioTo);
16
+ const onValueChange = (0, react_1.useCallback)((e) => {
17
+ setSeparateAudioTo(e.target.value);
18
+ }, [setSeparateAudioTo]);
19
+ const validationMessage = (0, react_1.useMemo)(() => {
20
+ const expectedExtension = client_1.BrowserSafeApis.getExtensionFromAudioCodec(audioCodec);
21
+ const actualExtension = separateAudioTo.split('.').pop();
22
+ if (actualExtension !== expectedExtension) {
23
+ return `Expected extension: .${expectedExtension}`;
24
+ }
25
+ return null;
26
+ }, [audioCodec, separateAudioTo]);
27
+ return ((0, jsx_runtime_1.jsx)(RenderModalOutputName_1.RenderModalOutputName, { existence: existence, inputStyle: layout_2.input, onValueChange: onValueChange, outName: separateAudioTo, label: 'Separate audio to', validationMessage: validationMessage }));
28
+ };
29
+ exports.SeparateAudioOptionInput = SeparateAudioOptionInput;
30
+ const SeparateAudioOption = ({ separateAudioTo, setSeparateAudioTo, audioCodec, outName }) => {
31
+ const onSeparateAudioChange = (0, react_1.useCallback)((e) => {
32
+ if (e.target.checked) {
33
+ const extension = client_1.BrowserSafeApis.getExtensionFromAudioCodec(audioCodec);
34
+ setSeparateAudioTo(`${(0, get_string_before_suffix_1.getStringBeforeSuffix)(outName)}.${extension}`);
35
+ }
36
+ else {
37
+ setSeparateAudioTo(null);
38
+ }
39
+ }, [audioCodec, outName, setSeparateAudioTo]);
40
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.optionRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: layout_2.label, children: ["Separate audio", (0, jsx_runtime_1.jsx)(layout_1.Spacing, { x: 0.5 }), (0, jsx_runtime_1.jsx)(OptionExplainerBubble_1.OptionExplainerBubble, { id: "separateAudioOption" })] }), (0, jsx_runtime_1.jsx)("div", { style: layout_2.rightRow, children: (0, jsx_runtime_1.jsx)(Checkbox_1.Checkbox, { disabled: false, checked: Boolean(separateAudioTo), onChange: onSeparateAudioChange, name: "separate-audio-to" }) })] }), separateAudioTo === null ? null : ((0, jsx_runtime_1.jsx)(exports.SeparateAudioOptionInput, { separateAudioTo: separateAudioTo, setSeparateAudioTo: setSeparateAudioTo, audioCodec: audioCodec }))] }));
41
+ };
42
+ exports.SeparateAudioOption = SeparateAudioOption;
@@ -0,0 +1 @@
1
+ export declare const getStringBeforeSuffix: (fileName: string) => string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStringBeforeSuffix = void 0;
4
+ const getStringBeforeSuffix = (fileName) => {
5
+ const dotPos = fileName.lastIndexOf('.');
6
+ if (dotPos === -1) {
7
+ return fileName;
8
+ }
9
+ return fileName.substring(0, dotPos);
10
+ };
11
+ exports.getStringBeforeSuffix = getStringBeforeSuffix;
@@ -1,2 +1,2 @@
1
1
  import type { Codec } from '@remotion/renderer';
2
- export declare const humanReadableCodec: (codec: Codec) => "AAC" | "MP3" | "GIF" | "H.264" | "H.264 Matroska" | "H.265" | "ProRes" | "WebM VP8" | "WebM VP9" | "Waveform" | undefined;
2
+ export declare const humanReadableCodec: (codec: Codec) => "AAC" | "MP3" | "GIF" | "H.264" | "H.264 Matroska" | "H.264 Transport Stream" | "H.265" | "ProRes" | "WebM VP8" | "WebM VP9" | "Waveform";