@remotion/studio 4.0.121 → 4.0.123

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 (37) 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/RenderButton.js +1 -0
  10. package/dist/components/RenderModal/RenderModal.d.ts +1 -0
  11. package/dist/components/RenderModal/RenderModal.js +22 -14
  12. package/dist/components/RenderModal/RenderModalAudio.d.ts +5 -0
  13. package/dist/components/RenderModal/RenderModalAudio.js +14 -3
  14. package/dist/components/RenderModal/RenderModalBasic.js +2 -2
  15. package/dist/components/RenderModal/RenderModalOutputName.d.ts +11 -0
  16. package/dist/components/RenderModal/RenderModalOutputName.js +12 -0
  17. package/dist/components/RenderModal/SeparateAudioOption.d.ts +13 -0
  18. package/dist/components/RenderModal/SeparateAudioOption.js +42 -0
  19. package/dist/components/RenderModal/get-string-before-suffix.d.ts +1 -0
  20. package/dist/components/RenderModal/get-string-before-suffix.js +11 -0
  21. package/dist/components/RenderModal/human-readable-codec.d.ts +1 -1
  22. package/dist/components/RenderModal/human-readable-codec.js +4 -0
  23. package/dist/components/RenderModal/out-name-checker.d.ts +6 -1
  24. package/dist/components/RenderModal/out-name-checker.js +36 -4
  25. package/dist/components/RenderQueue/actions.d.ts +3 -1
  26. package/dist/components/RenderQueue/actions.js +3 -1
  27. package/dist/components/SidebarRenderButton.js +1 -0
  28. package/dist/components/TopPanel.js +1 -1
  29. package/dist/components/utils.js +8 -6
  30. package/dist/helpers/retry-payload.js +3 -0
  31. package/dist/helpers/use-asset-drag-events.d.ts +12 -0
  32. package/dist/helpers/use-asset-drag-events.js +38 -0
  33. package/dist/state/modals.d.ts +1 -0
  34. package/package.json +7 -7
  35. package/tsconfig.tsbuildinfo +1 -1
  36. package/dist/helpers/use-el-size.d.ts +0 -5
  37. package/dist/helpers/use-el-size.js +0 -44
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @remotion/studio@4.0.120 build /Users/jonathanburger/remotion/packages/studio
3
+ > @remotion/studio@4.0.122 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
  };
@@ -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";
@@ -17,6 +17,9 @@ const humanReadableCodec = (codec) => {
17
17
  if (codec === 'h264-mkv') {
18
18
  return 'H.264 Matroska';
19
19
  }
20
+ if (codec === 'h264-ts') {
21
+ return 'H.264 Transport Stream';
22
+ }
20
23
  if (codec === 'h265') {
21
24
  return 'H.265';
22
25
  }
@@ -32,5 +35,6 @@ const humanReadableCodec = (codec) => {
32
35
  if (codec === 'wav') {
33
36
  return 'Waveform';
34
37
  }
38
+ throw new TypeError(`Got unexpected codec "${codec}"`);
35
39
  };
36
40
  exports.humanReadableCodec = humanReadableCodec;