@remotion/studio 4.0.459 → 4.0.461

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 (107) hide show
  1. package/dist/Studio.d.ts +0 -1
  2. package/dist/Studio.js +4 -4
  3. package/dist/components/AudioWaveform.js +21 -13
  4. package/dist/components/Checkbox.d.ts +7 -0
  5. package/dist/components/Checkbox.js +38 -24
  6. package/dist/components/Editor.js +10 -9
  7. package/dist/components/ExpandedTracksProvider.d.ts +9 -4
  8. package/dist/components/ExpandedTracksProvider.js +45 -15
  9. package/dist/components/MenuBuildIndicator.js +1 -2
  10. package/dist/components/MenuCompositionName.js +1 -0
  11. package/dist/components/NewComposition/ComboBox.d.ts +1 -0
  12. package/dist/components/NewComposition/ComboBox.js +14 -5
  13. package/dist/components/RenderButton.js +1 -1
  14. package/dist/components/SequencePropsSubscriptionProvider.d.ts +3 -0
  15. package/dist/components/SequencePropsSubscriptionProvider.js +26 -0
  16. package/dist/components/Timeline/SequencePropsObserver.d.ts +1 -0
  17. package/dist/components/Timeline/SequencePropsObserver.js +24 -0
  18. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +7 -0
  19. package/dist/components/Timeline/SubscribeToNodePaths.js +15 -0
  20. package/dist/components/Timeline/Timeline.js +30 -49
  21. package/dist/components/Timeline/TimelineBooleanField.d.ts +4 -4
  22. package/dist/components/Timeline/TimelineBooleanField.js +5 -5
  23. package/dist/components/Timeline/TimelineDragHandler.js +37 -3
  24. package/dist/components/Timeline/TimelineEnumField.d.ts +5 -5
  25. package/dist/components/Timeline/TimelineEnumField.js +23 -15
  26. package/dist/components/Timeline/TimelineExpandArrowButton.d.ts +1 -0
  27. package/dist/components/Timeline/TimelineExpandArrowButton.js +5 -3
  28. package/dist/components/Timeline/TimelineExpandedRow.d.ts +6 -6
  29. package/dist/components/Timeline/TimelineExpandedRow.js +4 -5
  30. package/dist/components/Timeline/TimelineExpandedSection.d.ts +2 -2
  31. package/dist/components/Timeline/TimelineExpandedSection.js +20 -9
  32. package/dist/components/Timeline/TimelineFieldRow.d.ts +2 -3
  33. package/dist/components/Timeline/TimelineFieldRow.js +66 -30
  34. package/dist/components/Timeline/TimelineHeightContainer.d.ts +7 -0
  35. package/dist/components/Timeline/TimelineHeightContainer.js +51 -0
  36. package/dist/components/Timeline/TimelineList.js +1 -1
  37. package/dist/components/Timeline/TimelineListItem.d.ts +2 -0
  38. package/dist/components/Timeline/TimelineListItem.js +33 -18
  39. package/dist/components/Timeline/TimelineNumberField.d.ts +5 -5
  40. package/dist/components/Timeline/TimelineNumberField.js +12 -10
  41. package/dist/components/Timeline/TimelineRotationField.d.ts +5 -5
  42. package/dist/components/Timeline/TimelineRotationField.js +10 -10
  43. package/dist/components/Timeline/TimelineSchemaField.d.ts +4 -6
  44. package/dist/components/Timeline/TimelineSchemaField.js +11 -11
  45. package/dist/components/Timeline/TimelineSequence.js +2 -2
  46. package/dist/components/Timeline/TimelineSlider.js +2 -2
  47. package/dist/components/Timeline/TimelineStack/get-stack.js +17 -31
  48. package/dist/components/Timeline/TimelineStack/index.js +0 -10
  49. package/dist/components/Timeline/TimelineTimeIndicators.js +2 -2
  50. package/dist/components/Timeline/TimelineTracks.d.ts +1 -1
  51. package/dist/components/Timeline/TimelineTracks.js +53 -12
  52. package/dist/components/Timeline/TimelineTranslateField.d.ts +5 -5
  53. package/dist/components/Timeline/TimelineTranslateField.js +19 -37
  54. package/dist/components/Timeline/TimelineVideoInfo.js +25 -140
  55. package/dist/components/Timeline/sequence-props-subscription-store.d.ts +10 -13
  56. package/dist/components/Timeline/sequence-props-subscription-store.js +56 -123
  57. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +6 -6
  58. package/dist/components/Timeline/use-sequence-props-subscription.js +25 -55
  59. package/dist/components/Timeline/use-timeline-height.d.ts +5 -0
  60. package/dist/components/Timeline/use-timeline-height.js +39 -0
  61. package/dist/error-overlay/react-overlay/utils/get-source-map.d.ts +3 -3
  62. package/dist/error-overlay/react-overlay/utils/get-source-map.js +5 -5
  63. package/dist/error-overlay/react-overlay/utils/unmapper.d.ts +0 -6
  64. package/dist/error-overlay/react-overlay/utils/unmapper.js +8 -1
  65. package/dist/esm/{chunk-0njpenna.js → chunk-yzh34sp0.js} +3026 -3446
  66. package/dist/esm/internals.mjs +3026 -3446
  67. package/dist/esm/previewEntry.mjs +3028 -3449
  68. package/dist/esm/renderEntry.mjs +2 -5
  69. package/dist/helpers/calculate-timeline.d.ts +3 -2
  70. package/dist/helpers/calculate-timeline.js +43 -2
  71. package/dist/helpers/get-timeline-sequence-layout.js +3 -3
  72. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +7 -1
  73. package/dist/helpers/timeline-layout.d.ts +19 -9
  74. package/dist/helpers/timeline-layout.js +50 -20
  75. package/dist/icons/Checkmark.d.ts +4 -1
  76. package/dist/icons/Checkmark.js +1 -5
  77. package/dist/icons/caret.d.ts +3 -1
  78. package/dist/icons/caret.js +5 -2
  79. package/dist/internals.d.ts +0 -1
  80. package/dist/previewEntry.js +1 -1
  81. package/dist/renderEntry.js +3 -3
  82. package/package.json +13 -21
  83. package/dist/audio-waveform-worker.d.ts +0 -1
  84. package/dist/audio-waveform-worker.js +0 -102
  85. package/dist/components/audio-waveform-worker-types.d.ts +0 -28
  86. package/dist/components/audio-waveform-worker-types.js +0 -2
  87. package/dist/components/draw-peaks.d.ts +0 -1
  88. package/dist/components/draw-peaks.js +0 -68
  89. package/dist/components/load-waveform-peaks.d.ts +0 -13
  90. package/dist/components/load-waveform-peaks.js +0 -76
  91. package/dist/components/looped-media-timeline.d.ts +0 -6
  92. package/dist/components/looped-media-timeline.js +0 -14
  93. package/dist/components/parse-color.d.ts +0 -1
  94. package/dist/components/parse-color.js +0 -17
  95. package/dist/components/slice-waveform-peaks.d.ts +0 -7
  96. package/dist/components/slice-waveform-peaks.js +0 -15
  97. package/dist/components/waveform-peak-processor.d.ts +0 -23
  98. package/dist/components/waveform-peak-processor.js +0 -77
  99. package/dist/esm/audio-waveform-worker.mjs +0 -354
  100. package/dist/helpers/extract-frames.d.ts +0 -18
  101. package/dist/helpers/extract-frames.js +0 -87
  102. package/dist/helpers/frame-database.d.ts +0 -16
  103. package/dist/helpers/frame-database.js +0 -65
  104. package/dist/helpers/resize-video-frame.d.ts +0 -4
  105. package/dist/helpers/resize-video-frame.js +0 -39
  106. package/dist/make-audio-waveform-worker.d.ts +0 -1
  107. package/dist/make-audio-waveform-worker.js +0 -10
@@ -166,7 +166,6 @@ var renderContent = (Root) => {
166
166
  logLevel: window.remotion_logLevel ?? "info",
167
167
  numberOfAudioTags: 0,
168
168
  audioLatencyHint: window.remotion_audioLatencyHint ?? "playback",
169
- visualModeEnabled: false,
170
169
  children: /* @__PURE__ */ jsxs(Internals.RenderAssetManagerProvider, {
171
170
  collectAssets: null,
172
171
  children: [
@@ -193,7 +192,6 @@ var renderContent = (Root) => {
193
192
  logLevel: window.remotion_logLevel ?? "info",
194
193
  numberOfAudioTags: 0,
195
194
  audioLatencyHint: window.remotion_audioLatencyHint ?? "playback",
196
- visualModeEnabled: false,
197
195
  children: /* @__PURE__ */ jsx(Internals.RenderAssetManagerProvider, {
198
196
  collectAssets: null,
199
197
  children: /* @__PURE__ */ jsx(Root, {})
@@ -209,14 +207,13 @@ var renderContent = (Root) => {
209
207
  renderToDOM(/* @__PURE__ */ jsx("div", {
210
208
  children: /* @__PURE__ */ jsx(DelayedSpinner, {})
211
209
  }));
212
- import("./chunk-0njpenna.js").then(({ StudioInternals }) => {
210
+ import("./chunk-yzh34sp0.js").then(({ StudioInternals }) => {
213
211
  window.remotion_isStudio = true;
214
212
  window.remotion_isReadOnlyStudio = true;
215
213
  window.remotion_inputProps = "{}";
216
214
  renderToDOM(/* @__PURE__ */ jsx(StudioInternals.Studio, {
217
215
  readOnly: true,
218
- rootComponent: Root,
219
- visualModeEnabled: false
216
+ rootComponent: Root
220
217
  }));
221
218
  }).catch((err) => {
222
219
  renderToDOM(/* @__PURE__ */ jsxs("div", {
@@ -1,5 +1,6 @@
1
- import type { TSequence } from 'remotion';
1
+ import type { OverrideIdToNodePaths, TSequence } from 'remotion';
2
2
  import type { TrackWithHash } from './get-timeline-sequence-sort-key';
3
- export declare const calculateTimeline: ({ sequences, }: {
3
+ export declare const calculateTimeline: ({ sequences, overrideIdsToNodePaths, }: {
4
4
  sequences: TSequence[];
5
+ overrideIdsToNodePaths: OverrideIdToNodePaths;
5
6
  }) => TrackWithHash[];
@@ -19,7 +19,9 @@ const getInheritedLoopDisplay = (sequence, sequences) => {
19
19
  }
20
20
  return getInheritedLoopDisplay(parent, sequences);
21
21
  };
22
- const calculateTimeline = ({ sequences, }) => {
22
+ const calculateTimeline = ({ sequences, overrideIdsToNodePaths, }) => {
23
+ var _a;
24
+ var _b;
23
25
  const sortedSequences = (0, sort_by_nonce_history_1.sortItemsByNonceHistory)(sequences);
24
26
  const tracks = [];
25
27
  if (sortedSequences.length === 0) {
@@ -41,6 +43,8 @@ const calculateTimeline = ({ sequences, }) => {
41
43
  const cascadedStart = (0, get_sequence_visible_range_1.getCascadedStart)(sequence, sortedSequences);
42
44
  const visibleStart = (0, get_sequence_visible_range_1.getTimelineVisibleStart)(sequence, sortedSequences);
43
45
  const visibleDuration = (0, get_sequence_visible_range_1.getTimelineVisibleDuration)(sequence, sortedSequences);
46
+ const overrideId = (_b = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.overrideId) !== null && _b !== void 0 ? _b : null;
47
+ const nodePath = overrideId ? overrideIdsToNodePaths[overrideId] : null;
44
48
  tracks.push({
45
49
  sequence: {
46
50
  ...sequence,
@@ -54,6 +58,9 @@ const calculateTimeline = ({ sequences, }) => {
54
58
  hash: actualHash,
55
59
  cascadedStart,
56
60
  cascadedDuration: sequence.duration,
61
+ nodePathInfo: nodePath
62
+ ? { nodePath, index: 0, numberOfSequencesWithThisNodePath: 0 }
63
+ : null,
57
64
  });
58
65
  }
59
66
  const uniqueTracks = [];
@@ -67,10 +74,44 @@ const calculateTimeline = ({ sequences, }) => {
67
74
  for (let i = 0; i < tracks.length; i++) {
68
75
  nonceRanks.set(tracks[i].sequence.id, i);
69
76
  }
70
- return uniqueTracks.sort((a, b) => {
77
+ const sortedTracks = uniqueTracks.sort((a, b) => {
71
78
  const sortKeyA = (0, get_timeline_sequence_sort_key_1.getTimelineSequenceSequenceSortKey)(a, tracks, sameHashes, nonceRanks);
72
79
  const sortKeyB = (0, get_timeline_sequence_sort_key_1.getTimelineSequenceSequenceSortKey)(b, tracks, sameHashes, nonceRanks);
73
80
  return sortKeyA.localeCompare(sortKeyB);
74
81
  });
82
+ const nodePathIndexCounters = new Map();
83
+ return sortedTracks
84
+ .map((track) => {
85
+ var _a;
86
+ if (track.nodePathInfo === null) {
87
+ return track;
88
+ }
89
+ const key = track.nodePathInfo.nodePath.join('.');
90
+ const index = (_a = nodePathIndexCounters.get(key)) !== null && _a !== void 0 ? _a : 0;
91
+ nodePathIndexCounters.set(key, index + 1);
92
+ return {
93
+ ...track,
94
+ nodePathInfo: {
95
+ nodePath: track.nodePathInfo.nodePath,
96
+ index,
97
+ numberOfSequencesWithThisNodePath: 0,
98
+ },
99
+ };
100
+ })
101
+ .map((track) => {
102
+ var _a;
103
+ if (track.nodePathInfo === null) {
104
+ return track;
105
+ }
106
+ const key = track.nodePathInfo.nodePath.join('.');
107
+ return {
108
+ ...track,
109
+ nodePathInfo: {
110
+ nodePath: track.nodePathInfo.nodePath,
111
+ index: track.nodePathInfo.index,
112
+ numberOfSequencesWithThisNodePath: (_a = nodePathIndexCounters.get(key)) !== null && _a !== void 0 ? _a : 0,
113
+ },
114
+ };
115
+ });
75
116
  };
76
117
  exports.calculateTimeline = calculateTimeline;
@@ -8,15 +8,15 @@ const getWidthOfTrack = ({ durationInFrames, lastFrame, windowWidth, spatialDura
8
8
  const base = durationInFrames === Infinity || lastFrame === 0
9
9
  ? fullWidth
10
10
  : (spatialDuration / lastFrame) * fullWidth;
11
- return base - exports.SEQUENCE_BORDER_WIDTH + nonNegativeMarginLeft;
11
+ return Math.max(0, base - exports.SEQUENCE_BORDER_WIDTH + nonNegativeMarginLeft);
12
12
  };
13
13
  const getTimelineSequenceLayout = ({ durationInFrames, startFrom, maxMediaDuration, startFromMedia, video, windowWidth, premountDisplay, postmountDisplay, }) => {
14
14
  var _a;
15
15
  const maxMediaSequenceDuration = (maxMediaDuration !== null && maxMediaDuration !== void 0 ? maxMediaDuration : Infinity) - startFromMedia;
16
16
  const lastFrame = ((_a = video.durationInFrames) !== null && _a !== void 0 ? _a : 1) - 1;
17
- const spatialDuration = Math.min(maxMediaSequenceDuration, durationInFrames - 1, lastFrame - startFrom);
17
+ const spatialDuration = Math.max(0, Math.min(maxMediaSequenceDuration, durationInFrames - 1, lastFrame - startFrom));
18
18
  // Unclipped spatial duration: without the lastFrame - startFrom constraint
19
- const naturalSpatialDuration = Math.min(maxMediaSequenceDuration, durationInFrames - 1);
19
+ const naturalSpatialDuration = Math.max(0, Math.min(maxMediaSequenceDuration, durationInFrames - 1));
20
20
  const marginLeft = lastFrame === 0
21
21
  ? 0
22
22
  : (startFrom / lastFrame) * (windowWidth - timeline_layout_1.TIMELINE_PADDING * 2);
@@ -1,7 +1,13 @@
1
- import type { TSequence } from 'remotion';
1
+ import type { SequenceNodePath, TSequence } from 'remotion';
2
+ export type SequenceNodePathInfo = {
3
+ nodePath: SequenceNodePath;
4
+ index: number;
5
+ numberOfSequencesWithThisNodePath: number;
6
+ };
2
7
  type Track = {
3
8
  sequence: TSequence;
4
9
  depth: number;
10
+ nodePathInfo: SequenceNodePathInfo | null;
5
11
  };
6
12
  export type TrackWithHash = Track & {
7
13
  hash: string;
@@ -1,5 +1,7 @@
1
1
  import { type CodeValues, type DragOverrides, type SchemaFieldInfo, type SequenceControls } from '@remotion/studio-shared';
2
- import type { EffectDefinitionAndStack, TSequence } from 'remotion';
2
+ import type { EffectDefinitionAndStack, GetCodeValues, GetDragOverrides, TSequence } from 'remotion';
3
+ import type { GetIsExpanded } from '../components/ExpandedTracksProvider';
4
+ import type { SequenceNodePathInfo } from './get-timeline-sequence-sort-key';
3
5
  export type { CodeValues, DragOverrides, SchemaFieldInfo, SequenceControls };
4
6
  export { SCHEMA_FIELD_ROW_HEIGHT, UNSUPPORTED_FIELD_ROW_HEIGHT, getFieldsToShow, } from '@remotion/studio-shared';
5
7
  export declare const TIMELINE_PADDING = 16;
@@ -9,6 +11,8 @@ export declare const TIMELINE_TRACK_EXPANDED_HEIGHT = 100;
9
11
  export declare const TREE_GROUP_ROW_HEIGHT = 22;
10
12
  export declare const EXPANDED_SECTION_PADDING_LEFT = 28;
11
13
  export declare const EXPANDED_SECTION_PADDING_RIGHT = 10;
14
+ export type TimelineFieldOnSave = (value: unknown) => Promise<void>;
15
+ export type TimelineFieldOnDragValueChange = (value: unknown) => void;
12
16
  export type EffectSchemaFieldLabel = {
13
17
  key: string;
14
18
  description: string | undefined;
@@ -16,31 +20,37 @@ export type EffectSchemaFieldLabel = {
16
20
  export declare const getEffectSchemaLabels: (effect: EffectDefinitionAndStack<unknown>) => EffectSchemaFieldLabel[];
17
21
  export type TimelineTreeNode = {
18
22
  readonly kind: 'group';
19
- readonly id: string;
23
+ readonly nodePathInfo: SequenceNodePathInfo;
20
24
  readonly label: string;
21
25
  readonly children: TimelineTreeNode[];
22
26
  } | {
23
27
  readonly kind: 'field';
24
- readonly id: string;
28
+ readonly nodePathInfo: SequenceNodePathInfo;
25
29
  readonly label: string;
26
30
  readonly field: SchemaFieldInfo | null;
27
31
  };
28
- export declare const buildTimelineTree: ({ sequence, dragOverrides, codeValues, }: {
32
+ export declare const buildTimelineTree: ({ sequence, nodePathInfo, getDragOverrides, getCodeValues, }: {
29
33
  sequence: TSequence;
30
- dragOverrides: DragOverrides;
31
- codeValues: CodeValues;
34
+ nodePathInfo: SequenceNodePathInfo;
35
+ getDragOverrides: GetDragOverrides;
36
+ getCodeValues: GetCodeValues;
32
37
  }) => TimelineTreeNode[];
33
38
  export type FlatTreeRow = {
34
39
  readonly node: TimelineTreeNode;
35
40
  readonly depth: number;
36
41
  };
37
- export declare const flattenVisibleTreeNodes: ({ nodes, expandedTracks, depth, }: {
42
+ export declare const flattenVisibleTreeNodes: ({ nodes, getIsExpanded, depth, }: {
38
43
  nodes: TimelineTreeNode[];
39
- expandedTracks: Record<string, boolean>;
44
+ getIsExpanded: GetIsExpanded;
40
45
  depth?: number | undefined;
41
46
  }) => FlatTreeRow[];
42
47
  export declare const getTreeRowHeight: (node: TimelineTreeNode) => number;
43
- export declare const getExpandedTrackHeight: (sequence: TSequence, expandedTracks: Record<string, boolean>, dragOverrides: DragOverrides, codeValues: CodeValues) => number;
48
+ export declare const getExpandedTrackHeight: ({ sequence, nodePathInfo, getIsExpanded, getCodeValues, }: {
49
+ sequence: TSequence;
50
+ nodePathInfo: SequenceNodePathInfo;
51
+ getIsExpanded: GetIsExpanded;
52
+ getCodeValues: GetCodeValues;
53
+ }) => number;
44
54
  export declare const TIMELINE_LAYER_HEIGHT_VIDEO = 75;
45
55
  export declare const TIMELINE_LAYER_HEIGHT_IMAGE = 50;
46
56
  export declare const TIMELINE_LAYER_HEIGHT_AUDIO = 25;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getTimelineLayerHeight = exports.TIMELINE_LAYER_HEIGHT_AUDIO = exports.TIMELINE_LAYER_HEIGHT_IMAGE = exports.TIMELINE_LAYER_HEIGHT_VIDEO = exports.getExpandedTrackHeight = exports.getTreeRowHeight = exports.flattenVisibleTreeNodes = exports.buildTimelineTree = exports.getEffectSchemaLabels = exports.EXPANDED_SECTION_PADDING_RIGHT = exports.EXPANDED_SECTION_PADDING_LEFT = exports.TREE_GROUP_ROW_HEIGHT = exports.TIMELINE_TRACK_EXPANDED_HEIGHT = exports.TIMELINE_ITEM_BORDER_BOTTOM = exports.TIMELINE_BORDER = exports.TIMELINE_PADDING = exports.getFieldsToShow = exports.UNSUPPORTED_FIELD_ROW_HEIGHT = exports.SCHEMA_FIELD_ROW_HEIGHT = void 0;
4
4
  const studio_shared_1 = require("@remotion/studio-shared");
5
+ const no_react_1 = require("remotion/no-react");
5
6
  const studio_shared_2 = require("@remotion/studio-shared");
6
7
  Object.defineProperty(exports, "SCHEMA_FIELD_ROW_HEIGHT", { enumerable: true, get: function () { return studio_shared_2.SCHEMA_FIELD_ROW_HEIGHT; } });
7
8
  Object.defineProperty(exports, "UNSUPPORTED_FIELD_ROW_HEIGHT", { enumerable: true, get: function () { return studio_shared_2.UNSUPPORTED_FIELD_ROW_HEIGHT; } });
@@ -17,31 +18,51 @@ const getEffectSchemaLabels = (effect) => {
17
18
  if (!effect.definition.schema) {
18
19
  return [];
19
20
  }
20
- return Object.entries(effect.definition.schema).map(([key, fieldSchema]) => ({
21
- key,
22
- description: fieldSchema.description,
23
- }));
21
+ return Object.entries(effect.definition.schema)
22
+ .map(([key, fieldSchema]) => {
23
+ if (fieldSchema.type === 'hidden') {
24
+ return null;
25
+ }
26
+ return {
27
+ key,
28
+ description: fieldSchema.description,
29
+ };
30
+ })
31
+ .filter(no_react_1.NoReactInternals.truthy);
24
32
  };
25
33
  exports.getEffectSchemaLabels = getEffectSchemaLabels;
26
- const buildTimelineTree = ({ sequence, dragOverrides, codeValues, }) => {
34
+ const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, getCodeValues, }) => {
27
35
  var _a;
28
36
  const roots = [];
37
+ const { nodePath, index } = nodePathInfo;
29
38
  if (sequence.effects.length > 0) {
30
39
  roots.push({
31
40
  kind: 'group',
32
- id: `${sequence.id}::effects`,
41
+ nodePathInfo: {
42
+ nodePath: [...nodePath, 'effects'],
43
+ index,
44
+ numberOfSequencesWithThisNodePath: 0,
45
+ },
33
46
  label: 'Effects',
34
47
  children: sequence.effects.map((effect, i) => {
35
- const effectId = `${sequence.id}::effects::${i}`;
48
+ const effectNodePath = [...nodePath, 'effects', i];
36
49
  return {
37
50
  kind: 'group',
38
- id: effectId,
51
+ nodePathInfo: {
52
+ nodePath: effectNodePath,
53
+ index,
54
+ numberOfSequencesWithThisNodePath: 0,
55
+ },
39
56
  label: effect.definition.label,
40
57
  children: (0, exports.getEffectSchemaLabels)(effect).map((label) => {
41
58
  var _a;
42
59
  return ({
43
60
  kind: 'field',
44
- id: `${effectId}::${label.key}`,
61
+ nodePathInfo: {
62
+ nodePath: [...effectNodePath, label.key],
63
+ index,
64
+ numberOfSequencesWithThisNodePath: 0,
65
+ },
45
66
  label: (_a = label.description) !== null && _a !== void 0 ? _a : label.key,
46
67
  field: null,
47
68
  });
@@ -53,15 +74,19 @@ const buildTimelineTree = ({ sequence, dragOverrides, codeValues, }) => {
53
74
  const controlFields = (0, studio_shared_1.getFieldsToShow)({
54
75
  schema: sequence.controls.schema,
55
76
  currentRuntimeValueDotNotation: sequence.controls.currentRuntimeValueDotNotation,
56
- dragOverrides,
57
- codeValues,
58
- overrideId: sequence.controls.overrideId,
77
+ getDragOverrides,
78
+ getCodeValues,
79
+ nodePath,
59
80
  });
60
81
  if (controlFields && controlFields.length > 0) {
61
82
  for (const f of controlFields) {
62
83
  roots.push({
63
84
  kind: 'field',
64
- id: `${sequence.id}::controls::${f.key}`,
85
+ nodePathInfo: {
86
+ nodePath: [...nodePath, 'controls', f.key],
87
+ index,
88
+ numberOfSequencesWithThisNodePath: 0,
89
+ },
65
90
  label: (_a = f.description) !== null && _a !== void 0 ? _a : f.key,
66
91
  field: f,
67
92
  });
@@ -70,15 +95,14 @@ const buildTimelineTree = ({ sequence, dragOverrides, codeValues, }) => {
70
95
  return roots;
71
96
  };
72
97
  exports.buildTimelineTree = buildTimelineTree;
73
- const flattenVisibleTreeNodes = ({ nodes, expandedTracks, depth = 0, }) => {
74
- var _a;
98
+ const flattenVisibleTreeNodes = ({ nodes, getIsExpanded, depth = 0, }) => {
75
99
  const out = [];
76
100
  for (const node of nodes) {
77
101
  out.push({ node, depth });
78
- if (node.kind === 'group' && ((_a = expandedTracks[node.id]) !== null && _a !== void 0 ? _a : false)) {
102
+ if (node.kind === 'group' && getIsExpanded(node.nodePathInfo)) {
79
103
  out.push(...(0, exports.flattenVisibleTreeNodes)({
80
104
  nodes: node.children,
81
- expandedTracks,
105
+ getIsExpanded,
82
106
  depth: depth + 1,
83
107
  }));
84
108
  }
@@ -93,9 +117,15 @@ const getTreeRowHeight = (node) => {
93
117
  return exports.TREE_GROUP_ROW_HEIGHT;
94
118
  };
95
119
  exports.getTreeRowHeight = getTreeRowHeight;
96
- const getExpandedTrackHeight = (sequence, expandedTracks, dragOverrides, codeValues) => {
97
- const tree = (0, exports.buildTimelineTree)({ sequence, dragOverrides, codeValues });
98
- const flat = (0, exports.flattenVisibleTreeNodes)({ nodes: tree, expandedTracks });
120
+ const getExpandedTrackHeight = ({ sequence, nodePathInfo, getIsExpanded, getCodeValues, }) => {
121
+ const tree = (0, exports.buildTimelineTree)({
122
+ sequence,
123
+ nodePathInfo,
124
+ // We assume that no drag overrides can change the timeline layout
125
+ getDragOverrides: () => ({}),
126
+ getCodeValues,
127
+ });
128
+ const flat = (0, exports.flattenVisibleTreeNodes)({ nodes: tree, getIsExpanded });
99
129
  if (flat.length === 0) {
100
130
  return exports.TIMELINE_TRACK_EXPANDED_HEIGHT;
101
131
  }
@@ -1 +1,4 @@
1
- export declare const Checkmark: () => import("react/jsx-runtime").JSX.Element;
1
+ import React from 'react';
2
+ export declare const Checkmark: React.FC<{
3
+ readonly size?: number;
4
+ }>;
@@ -2,9 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Checkmark = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const style = {
6
- width: 14,
7
- height: 14,
8
- };
9
- const Checkmark = () => (jsx_runtime_1.jsx("svg", { focusable: "false", role: "img", viewBox: "0 0 512 512", style: style, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z" }) }));
5
+ const Checkmark = ({ size = 14 }) => (jsx_runtime_1.jsx("svg", { focusable: "false", role: "img", viewBox: "0 0 512 512", style: { width: size, height: size }, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z" }) }));
10
6
  exports.Checkmark = Checkmark;
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  export declare const CaretRight: () => import("react/jsx-runtime").JSX.Element;
3
- export declare const CaretDown: () => import("react/jsx-runtime").JSX.Element;
3
+ export declare const CaretDown: React.FC<{
4
+ readonly small?: boolean;
5
+ }>;
4
6
  export declare const AngleDown: React.FC<{
5
7
  readonly down: boolean;
6
8
  }>;
@@ -10,13 +10,16 @@ const caret = {
10
10
  const caretDown = {
11
11
  width: 10,
12
12
  };
13
+ const caretDownSmall = {
14
+ width: 7,
15
+ };
13
16
  const angleDown = {
14
17
  width: 10,
15
18
  };
16
19
  const CaretRight = () => (jsx_runtime_1.jsx("svg", { viewBox: "0 0 192 512", style: caret, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z" }) }));
17
20
  exports.CaretRight = CaretRight;
18
- const CaretDown = () => {
19
- return (jsx_runtime_1.jsx("svg", { viewBox: "0 0 320 512", style: caretDown, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z" }) }));
21
+ const CaretDown = ({ small = false, }) => {
22
+ return (jsx_runtime_1.jsx("svg", { viewBox: "0 0 320 512", style: small ? caretDownSmall : caretDown, children: jsx_runtime_1.jsx("path", { fill: "currentColor", d: "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z" }) }));
20
23
  };
21
24
  exports.CaretDown = CaretDown;
22
25
  const AngleDown = ({ down }) => {
@@ -2,6 +2,5 @@ export declare const StudioInternals: {
2
2
  Studio: import("react").FC<{
3
3
  readonly rootComponent: import("react").FC<{}>;
4
4
  readonly readOnly: boolean;
5
- readonly visualModeEnabled: boolean;
6
5
  }>;
7
6
  };
@@ -44,5 +44,5 @@ const renderToDOM = (content) => {
44
44
  };
45
45
  renderToDOM(jsx_runtime_1.jsx(NoRegisterRoot_1.NoRegisterRoot, {}));
46
46
  remotion_1.Internals.waitForRoot((NewRoot) => {
47
- renderToDOM(jsx_runtime_1.jsx(Studio_1.Studio, { readOnly: false, rootComponent: NewRoot, visualModeEnabled: Boolean(process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED) }));
47
+ renderToDOM(jsx_runtime_1.jsx(Studio_1.Studio, { readOnly: false, rootComponent: NewRoot }));
48
48
  });
@@ -186,13 +186,13 @@ const renderContent = (Root) => {
186
186
  defaultPixelFormat: bundleMode.compositionDefaultPixelFormat,
187
187
  defaultProResProfile: bundleMode.compositionDefaultProResProfile,
188
188
  defaultSampleRate: bundleMode.compositionDefaultSampleRate,
189
- }, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info', numberOfAudioTags: 0, audioLatencyHint: (_b = window.remotion_audioLatencyHint) !== null && _b !== void 0 ? _b : 'playback', visualModeEnabled: false, children: jsx_runtime_1.jsxs(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: [
189
+ }, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info', numberOfAudioTags: 0, audioLatencyHint: (_b = window.remotion_audioLatencyHint) !== null && _b !== void 0 ? _b : 'playback', children: jsx_runtime_1.jsxs(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: [
190
190
  jsx_runtime_1.jsx(Root, {}), jsx_runtime_1.jsx(GetVideoComposition, { state: bundleMode })
191
191
  ] }) }) }));
192
192
  renderToDOM(markup);
193
193
  }
194
194
  if (bundleMode.type === 'evaluation') {
195
- const markup = (jsx_runtime_1.jsx(remotion_1.Internals.CompositionManagerProvider, { initialCanvasContent: null, onlyRenderComposition: null, currentCompositionMetadata: null, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_c = window.remotion_logLevel) !== null && _c !== void 0 ? _c : 'info', numberOfAudioTags: 0, audioLatencyHint: (_d = window.remotion_audioLatencyHint) !== null && _d !== void 0 ? _d : 'playback', visualModeEnabled: false, children: jsx_runtime_1.jsx(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: jsx_runtime_1.jsx(Root, {}) }) }) }));
195
+ const markup = (jsx_runtime_1.jsx(remotion_1.Internals.CompositionManagerProvider, { initialCanvasContent: null, onlyRenderComposition: null, currentCompositionMetadata: null, initialCompositions: [], children: jsx_runtime_1.jsx(remotion_1.Internals.RemotionRootContexts, { frameState: null, audioEnabled: window.remotion_audioEnabled, videoEnabled: window.remotion_videoEnabled, logLevel: (_c = window.remotion_logLevel) !== null && _c !== void 0 ? _c : 'info', numberOfAudioTags: 0, audioLatencyHint: (_d = window.remotion_audioLatencyHint) !== null && _d !== void 0 ? _d : 'playback', children: jsx_runtime_1.jsx(remotion_1.Internals.RenderAssetManagerProvider, { collectAssets: null, children: jsx_runtime_1.jsx(Root, {}) }) }) }));
196
196
  renderToDOM(markup);
197
197
  }
198
198
  if (bundleMode.type === 'index') {
@@ -204,7 +204,7 @@ const renderContent = (Root) => {
204
204
  window.remotion_isStudio = true;
205
205
  window.remotion_isReadOnlyStudio = true;
206
206
  window.remotion_inputProps = '{}';
207
- renderToDOM(jsx_runtime_1.jsx(StudioInternals.Studio, { readOnly: true, rootComponent: Root, visualModeEnabled: false }));
207
+ renderToDOM(jsx_runtime_1.jsx(StudioInternals.Studio, { readOnly: true, rootComponent: Root }));
208
208
  })
209
209
  .catch((err) => {
210
210
  renderToDOM(jsx_runtime_1.jsxs("div", { children: ["Failed to load Remotion Studio: ", err.message] }));
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio"
4
4
  },
5
5
  "name": "@remotion/studio",
6
- "version": "4.0.459",
6
+ "version": "4.0.461",
7
7
  "description": "APIs for interacting with the Remotion Studio",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -26,24 +26,25 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "semver": "7.5.3",
29
- "remotion": "4.0.459",
30
- "@remotion/player": "4.0.459",
31
- "@remotion/media-utils": "4.0.459",
32
- "@remotion/renderer": "4.0.459",
33
- "@remotion/web-renderer": "4.0.459",
34
- "@remotion/studio-shared": "4.0.459",
35
- "@remotion/zod-types": "4.0.459",
29
+ "remotion": "4.0.461",
30
+ "@remotion/player": "4.0.461",
31
+ "@remotion/media-utils": "4.0.461",
32
+ "@remotion/renderer": "4.0.461",
33
+ "@remotion/web-renderer": "4.0.461",
34
+ "@remotion/studio-shared": "4.0.461",
35
+ "@remotion/timeline-utils": "4.0.461",
36
+ "@remotion/zod-types": "4.0.461",
37
+ "@jridgewell/trace-mapping": "0.3.31",
36
38
  "mediabunny": "1.42.0",
37
39
  "memfs": "3.4.3",
38
- "source-map": "0.7.3",
39
- "open": "^8.4.2",
40
+ "open": "8.4.2",
40
41
  "zod": "4.3.6"
41
42
  },
42
43
  "devDependencies": {
43
44
  "react": "19.2.3",
44
45
  "react-dom": "19.2.3",
45
- "@types/semver": "^7.3.4",
46
- "@remotion/eslint-config-internal": "4.0.459",
46
+ "@types/semver": "7.5.3",
47
+ "@remotion/eslint-config-internal": "4.0.461",
47
48
  "eslint": "9.19.0",
48
49
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
49
50
  },
@@ -75,12 +76,6 @@
75
76
  "require": "./dist/previewEntry.js",
76
77
  "module": "./dist/esm/previewEntry.mjs",
77
78
  "import": "./dist/esm/previewEntry.mjs"
78
- },
79
- "./audio-waveform-worker": {
80
- "types": "./dist/audio-waveform-worker.d.ts",
81
- "require": "./dist/audio-waveform-worker.js",
82
- "module": "./dist/esm/audio-waveform-worker.mjs",
83
- "import": "./dist/esm/audio-waveform-worker.mjs"
84
79
  }
85
80
  },
86
81
  "homepage": "https://www.remotion.dev/docs/studio/api",
@@ -94,9 +89,6 @@
94
89
  ],
95
90
  "previewEntry": [
96
91
  "./dist/previewEntry.d.ts"
97
- ],
98
- "audio-waveform-worker": [
99
- "./dist/audio-waveform-worker.d.ts"
100
92
  ]
101
93
  }
102
94
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,102 +0,0 @@
1
- "use strict";
2
- /// <reference lib="webworker" />
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const draw_peaks_1 = require("./components/draw-peaks");
5
- const load_waveform_peaks_1 = require("./components/load-waveform-peaks");
6
- const looped_media_timeline_1 = require("./components/looped-media-timeline");
7
- const slice_waveform_peaks_1 = require("./components/slice-waveform-peaks");
8
- let canvas = null;
9
- let currentController = null;
10
- let latestRequestId = 0;
11
- const postError = (requestId, error) => {
12
- const message = error instanceof Error ? error.message : 'Failed to render waveform';
13
- const payload = {
14
- type: 'error',
15
- requestId,
16
- message,
17
- };
18
- self.postMessage(payload);
19
- };
20
- const drawPartialWaveform = (message, peaks) => {
21
- if (!canvas) {
22
- return;
23
- }
24
- const portionPeaks = (0, slice_waveform_peaks_1.sliceWaveformPeaks)({
25
- durationInFrames: (0, looped_media_timeline_1.shouldTileLoopDisplay)(message.loopDisplay)
26
- ? message.loopDisplay.durationInFrames
27
- : message.durationInFrames,
28
- fps: message.fps,
29
- peaks,
30
- playbackRate: message.playbackRate,
31
- startFrom: message.startFrom,
32
- });
33
- if (!(0, looped_media_timeline_1.shouldTileLoopDisplay)(message.loopDisplay)) {
34
- (0, draw_peaks_1.drawBars)(canvas, portionPeaks, 'rgba(255, 255, 255, 0.6)', message.volume, message.width);
35
- return;
36
- }
37
- const loopWidth = (0, looped_media_timeline_1.getLoopDisplayWidth)({
38
- visualizationWidth: message.width,
39
- loopDisplay: message.loopDisplay,
40
- });
41
- const targetCanvas = new OffscreenCanvas(Math.max(1, Math.ceil(loopWidth)), message.height);
42
- (0, draw_peaks_1.drawBars)(targetCanvas, portionPeaks, 'rgba(255, 255, 255, 0.6)', message.volume, targetCanvas.width);
43
- const ctx = canvas.getContext('2d');
44
- if (!ctx) {
45
- throw new Error('Failed to get canvas context');
46
- }
47
- const pattern = ctx.createPattern(targetCanvas, 'repeat-x');
48
- if (!pattern) {
49
- return;
50
- }
51
- pattern.setTransform(new DOMMatrix().scaleSelf(loopWidth / targetCanvas.width, 1));
52
- ctx.clearRect(0, 0, message.width, message.height);
53
- ctx.fillStyle = pattern;
54
- ctx.fillRect(0, 0, message.width, message.height);
55
- };
56
- const renderWaveform = async (message) => {
57
- if (!canvas) {
58
- postError(message.requestId, new Error('Waveform canvas not initialized'));
59
- return;
60
- }
61
- const controller = new AbortController();
62
- currentController === null || currentController === void 0 ? void 0 : currentController.abort();
63
- currentController = controller;
64
- latestRequestId = message.requestId;
65
- try {
66
- canvas.width = message.width;
67
- canvas.height = message.height;
68
- const peaks = await (0, load_waveform_peaks_1.loadWaveformPeaks)(message.src, controller.signal, {
69
- onProgress: ({ peaks: nextPeaks }) => {
70
- if (controller.signal.aborted ||
71
- latestRequestId !== message.requestId) {
72
- return;
73
- }
74
- drawPartialWaveform(message, nextPeaks);
75
- },
76
- });
77
- if (controller.signal.aborted || latestRequestId !== message.requestId) {
78
- return;
79
- }
80
- drawPartialWaveform(message, peaks);
81
- }
82
- catch (error) {
83
- if (controller.signal.aborted || latestRequestId !== message.requestId) {
84
- return;
85
- }
86
- postError(message.requestId, error);
87
- }
88
- };
89
- self.addEventListener('message', (event) => {
90
- const message = event.data;
91
- if (message.type === 'init') {
92
- canvas = message.canvas;
93
- return;
94
- }
95
- if (message.type === 'dispose') {
96
- currentController === null || currentController === void 0 ? void 0 : currentController.abort();
97
- currentController = null;
98
- canvas = null;
99
- return;
100
- }
101
- renderWaveform(message);
102
- });
@@ -1,28 +0,0 @@
1
- import type { LoopDisplay } from 'remotion';
2
- export type AudioWaveformWorkerInitMessage = {
3
- readonly type: 'init';
4
- readonly canvas: OffscreenCanvas;
5
- };
6
- export type AudioWaveformWorkerRenderMessage = {
7
- readonly type: 'render';
8
- readonly requestId: number;
9
- readonly src: string;
10
- readonly width: number;
11
- readonly height: number;
12
- readonly volume: number;
13
- readonly startFrom: number;
14
- readonly durationInFrames: number;
15
- readonly fps: number;
16
- readonly playbackRate: number;
17
- readonly loopDisplay: LoopDisplay | undefined;
18
- };
19
- export type AudioWaveformWorkerDisposeMessage = {
20
- readonly type: 'dispose';
21
- };
22
- export type AudioWaveformWorkerIncomingMessage = AudioWaveformWorkerInitMessage | AudioWaveformWorkerRenderMessage | AudioWaveformWorkerDisposeMessage;
23
- export type AudioWaveformWorkerErrorMessage = {
24
- readonly type: 'error';
25
- readonly requestId: number;
26
- readonly message: string;
27
- };
28
- export type AudioWaveformWorkerOutgoingMessage = AudioWaveformWorkerErrorMessage;
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });