@remotion/studio 4.0.460 → 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 (70) hide show
  1. package/dist/Studio.d.ts +0 -1
  2. package/dist/Studio.js +4 -4
  3. package/dist/components/AudioWaveform.js +17 -9
  4. package/dist/components/MenuBuildIndicator.js +1 -1
  5. package/dist/components/MenuCompositionName.js +1 -0
  6. package/dist/components/RenderButton.js +1 -1
  7. package/dist/components/Timeline/SequencePropsObserver.js +1 -1
  8. package/dist/components/Timeline/Timeline.js +11 -10
  9. package/dist/components/Timeline/TimelineBooleanField.d.ts +4 -4
  10. package/dist/components/Timeline/TimelineBooleanField.js +5 -5
  11. package/dist/components/Timeline/TimelineDragHandler.js +37 -3
  12. package/dist/components/Timeline/TimelineEnumField.d.ts +5 -5
  13. package/dist/components/Timeline/TimelineEnumField.js +7 -7
  14. package/dist/components/Timeline/TimelineExpandArrowButton.js +1 -1
  15. package/dist/components/Timeline/TimelineExpandedSection.js +3 -3
  16. package/dist/components/Timeline/TimelineFieldRow.js +49 -16
  17. package/dist/components/Timeline/TimelineHeightContainer.d.ts +1 -1
  18. package/dist/components/Timeline/TimelineHeightContainer.js +36 -3
  19. package/dist/components/Timeline/TimelineListItem.js +15 -14
  20. package/dist/components/Timeline/TimelineNumberField.d.ts +5 -5
  21. package/dist/components/Timeline/TimelineNumberField.js +12 -10
  22. package/dist/components/Timeline/TimelineRotationField.d.ts +5 -5
  23. package/dist/components/Timeline/TimelineRotationField.js +10 -10
  24. package/dist/components/Timeline/TimelineSchemaField.d.ts +4 -6
  25. package/dist/components/Timeline/TimelineSchemaField.js +8 -11
  26. package/dist/components/Timeline/TimelineSequence.js +2 -2
  27. package/dist/components/Timeline/TimelineSlider.js +2 -2
  28. package/dist/components/Timeline/TimelineStack/get-stack.js +17 -31
  29. package/dist/components/Timeline/TimelineStack/index.js +0 -10
  30. package/dist/components/Timeline/TimelineTimeIndicators.js +2 -2
  31. package/dist/components/Timeline/TimelineTracks.d.ts +1 -1
  32. package/dist/components/Timeline/TimelineTracks.js +40 -10
  33. package/dist/components/Timeline/TimelineTranslateField.d.ts +5 -5
  34. package/dist/components/Timeline/TimelineTranslateField.js +19 -37
  35. package/dist/components/Timeline/sequence-props-subscription-store.js +1 -1
  36. package/dist/components/Timeline/use-sequence-props-subscription.js +3 -3
  37. package/dist/components/Timeline/use-timeline-height.js +4 -13
  38. package/dist/error-overlay/react-overlay/utils/get-source-map.d.ts +3 -3
  39. package/dist/error-overlay/react-overlay/utils/get-source-map.js +5 -5
  40. package/dist/error-overlay/react-overlay/utils/unmapper.d.ts +0 -6
  41. package/dist/error-overlay/react-overlay/utils/unmapper.js +8 -1
  42. package/dist/esm/{chunk-nrgs0ad5.js → chunk-yzh34sp0.js} +286 -538
  43. package/dist/esm/internals.mjs +286 -538
  44. package/dist/esm/previewEntry.mjs +289 -542
  45. package/dist/esm/renderEntry.mjs +2 -5
  46. package/dist/helpers/calculate-timeline.js +26 -4
  47. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +1 -0
  48. package/dist/helpers/timeline-layout.d.ts +3 -2
  49. package/dist/helpers/timeline-layout.js +31 -9
  50. package/dist/internals.d.ts +0 -1
  51. package/dist/previewEntry.js +1 -1
  52. package/dist/renderEntry.js +3 -3
  53. package/package.json +13 -22
  54. package/dist/audio-waveform-worker.d.ts +0 -1
  55. package/dist/audio-waveform-worker.js +0 -102
  56. package/dist/components/audio-waveform-worker-types.d.ts +0 -28
  57. package/dist/components/audio-waveform-worker-types.js +0 -2
  58. package/dist/components/draw-peaks.d.ts +0 -1
  59. package/dist/components/draw-peaks.js +0 -68
  60. package/dist/components/load-waveform-peaks.d.ts +0 -13
  61. package/dist/components/load-waveform-peaks.js +0 -76
  62. package/dist/components/parse-color.d.ts +0 -1
  63. package/dist/components/parse-color.js +0 -17
  64. package/dist/components/slice-waveform-peaks.d.ts +0 -7
  65. package/dist/components/slice-waveform-peaks.js +0 -15
  66. package/dist/components/waveform-peak-processor.d.ts +0 -23
  67. package/dist/components/waveform-peak-processor.js +0 -77
  68. package/dist/esm/audio-waveform-worker.mjs +0 -346
  69. package/dist/make-audio-waveform-worker.d.ts +0 -1
  70. 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-nrgs0ad5.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", {
@@ -58,7 +58,9 @@ const calculateTimeline = ({ sequences, overrideIdsToNodePaths, }) => {
58
58
  hash: actualHash,
59
59
  cascadedStart,
60
60
  cascadedDuration: sequence.duration,
61
- nodePathInfo: nodePath ? { nodePath, index: 0 } : null,
61
+ nodePathInfo: nodePath
62
+ ? { nodePath, index: 0, numberOfSequencesWithThisNodePath: 0 }
63
+ : null,
62
64
  });
63
65
  }
64
66
  const uniqueTracks = [];
@@ -78,17 +80,37 @@ const calculateTimeline = ({ sequences, overrideIdsToNodePaths, }) => {
78
80
  return sortKeyA.localeCompare(sortKeyB);
79
81
  });
80
82
  const nodePathIndexCounters = new Map();
81
- return sortedTracks.map((track) => {
83
+ return sortedTracks
84
+ .map((track) => {
82
85
  var _a;
83
86
  if (track.nodePathInfo === null) {
84
87
  return track;
85
88
  }
86
- const key = JSON.stringify(track.nodePathInfo.nodePath);
89
+ const key = track.nodePathInfo.nodePath.join('.');
87
90
  const index = (_a = nodePathIndexCounters.get(key)) !== null && _a !== void 0 ? _a : 0;
88
91
  nodePathIndexCounters.set(key, index + 1);
89
92
  return {
90
93
  ...track,
91
- nodePathInfo: { nodePath: track.nodePathInfo.nodePath, index },
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
+ },
92
114
  };
93
115
  });
94
116
  };
@@ -2,6 +2,7 @@ import type { SequenceNodePath, TSequence } from 'remotion';
2
2
  export type SequenceNodePathInfo = {
3
3
  nodePath: SequenceNodePath;
4
4
  index: number;
5
+ numberOfSequencesWithThisNodePath: number;
5
6
  };
6
7
  type Track = {
7
8
  sequence: TSequence;
@@ -11,6 +11,8 @@ export declare const TIMELINE_TRACK_EXPANDED_HEIGHT = 100;
11
11
  export declare const TREE_GROUP_ROW_HEIGHT = 22;
12
12
  export declare const EXPANDED_SECTION_PADDING_LEFT = 28;
13
13
  export declare const EXPANDED_SECTION_PADDING_RIGHT = 10;
14
+ export type TimelineFieldOnSave = (value: unknown) => Promise<void>;
15
+ export type TimelineFieldOnDragValueChange = (value: unknown) => void;
14
16
  export type EffectSchemaFieldLabel = {
15
17
  key: string;
16
18
  description: string | undefined;
@@ -43,11 +45,10 @@ export declare const flattenVisibleTreeNodes: ({ nodes, getIsExpanded, depth, }:
43
45
  depth?: number | undefined;
44
46
  }) => FlatTreeRow[];
45
47
  export declare const getTreeRowHeight: (node: TimelineTreeNode) => number;
46
- export declare const getExpandedTrackHeight: ({ sequence, nodePathInfo, getIsExpanded, getDragOverrides, getCodeValues, }: {
48
+ export declare const getExpandedTrackHeight: ({ sequence, nodePathInfo, getIsExpanded, getCodeValues, }: {
47
49
  sequence: TSequence;
48
50
  nodePathInfo: SequenceNodePathInfo;
49
51
  getIsExpanded: GetIsExpanded;
50
- getDragOverrides: GetDragOverrides;
51
52
  getCodeValues: GetCodeValues;
52
53
  }) => number;
53
54
  export declare const TIMELINE_LAYER_HEIGHT_VIDEO = 75;
@@ -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,10 +18,17 @@ 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
34
  const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, getCodeValues, }) => {
@@ -30,13 +38,21 @@ const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, getCodeVa
30
38
  if (sequence.effects.length > 0) {
31
39
  roots.push({
32
40
  kind: 'group',
33
- nodePathInfo: { nodePath: [...nodePath, 'effects'], index },
41
+ nodePathInfo: {
42
+ nodePath: [...nodePath, 'effects'],
43
+ index,
44
+ numberOfSequencesWithThisNodePath: 0,
45
+ },
34
46
  label: 'Effects',
35
47
  children: sequence.effects.map((effect, i) => {
36
48
  const effectNodePath = [...nodePath, 'effects', i];
37
49
  return {
38
50
  kind: 'group',
39
- nodePathInfo: { nodePath: effectNodePath, index },
51
+ nodePathInfo: {
52
+ nodePath: effectNodePath,
53
+ index,
54
+ numberOfSequencesWithThisNodePath: 0,
55
+ },
40
56
  label: effect.definition.label,
41
57
  children: (0, exports.getEffectSchemaLabels)(effect).map((label) => {
42
58
  var _a;
@@ -45,6 +61,7 @@ const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, getCodeVa
45
61
  nodePathInfo: {
46
62
  nodePath: [...effectNodePath, label.key],
47
63
  index,
64
+ numberOfSequencesWithThisNodePath: 0,
48
65
  },
49
66
  label: (_a = label.description) !== null && _a !== void 0 ? _a : label.key,
50
67
  field: null,
@@ -65,7 +82,11 @@ const buildTimelineTree = ({ sequence, nodePathInfo, getDragOverrides, getCodeVa
65
82
  for (const f of controlFields) {
66
83
  roots.push({
67
84
  kind: 'field',
68
- nodePathInfo: { nodePath: [...nodePath, 'controls', f.key], index },
85
+ nodePathInfo: {
86
+ nodePath: [...nodePath, 'controls', f.key],
87
+ index,
88
+ numberOfSequencesWithThisNodePath: 0,
89
+ },
69
90
  label: (_a = f.description) !== null && _a !== void 0 ? _a : f.key,
70
91
  field: f,
71
92
  });
@@ -96,11 +117,12 @@ const getTreeRowHeight = (node) => {
96
117
  return exports.TREE_GROUP_ROW_HEIGHT;
97
118
  };
98
119
  exports.getTreeRowHeight = getTreeRowHeight;
99
- const getExpandedTrackHeight = ({ sequence, nodePathInfo, getIsExpanded, getDragOverrides, getCodeValues, }) => {
120
+ const getExpandedTrackHeight = ({ sequence, nodePathInfo, getIsExpanded, getCodeValues, }) => {
100
121
  const tree = (0, exports.buildTimelineTree)({
101
122
  sequence,
102
123
  nodePathInfo,
103
- getDragOverrides,
124
+ // We assume that no drag overrides can change the timeline layout
125
+ getDragOverrides: () => ({}),
104
126
  getCodeValues,
105
127
  });
106
128
  const flat = (0, exports.flattenVisibleTreeNodes)({ nodes: tree, getIsExpanded });
@@ -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.460",
6
+ "version": "4.0.461",
7
7
  "description": "APIs for interacting with the Remotion Studio",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -26,25 +26,25 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "semver": "7.5.3",
29
- "remotion": "4.0.460",
30
- "@remotion/player": "4.0.460",
31
- "@remotion/media-utils": "4.0.460",
32
- "@remotion/renderer": "4.0.460",
33
- "@remotion/web-renderer": "4.0.460",
34
- "@remotion/studio-shared": "4.0.460",
35
- "@remotion/timeline-utils": "4.0.460",
36
- "@remotion/zod-types": "4.0.460",
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",
37
38
  "mediabunny": "1.42.0",
38
39
  "memfs": "3.4.3",
39
- "source-map": "0.7.3",
40
- "open": "^8.4.2",
40
+ "open": "8.4.2",
41
41
  "zod": "4.3.6"
42
42
  },
43
43
  "devDependencies": {
44
44
  "react": "19.2.3",
45
45
  "react-dom": "19.2.3",
46
- "@types/semver": "^7.3.4",
47
- "@remotion/eslint-config-internal": "4.0.460",
46
+ "@types/semver": "7.5.3",
47
+ "@remotion/eslint-config-internal": "4.0.461",
48
48
  "eslint": "9.19.0",
49
49
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
50
50
  },
@@ -76,12 +76,6 @@
76
76
  "require": "./dist/previewEntry.js",
77
77
  "module": "./dist/esm/previewEntry.mjs",
78
78
  "import": "./dist/esm/previewEntry.mjs"
79
- },
80
- "./audio-waveform-worker": {
81
- "types": "./dist/audio-waveform-worker.d.ts",
82
- "require": "./dist/audio-waveform-worker.js",
83
- "module": "./dist/esm/audio-waveform-worker.mjs",
84
- "import": "./dist/esm/audio-waveform-worker.mjs"
85
79
  }
86
80
  },
87
81
  "homepage": "https://www.remotion.dev/docs/studio/api",
@@ -95,9 +89,6 @@
95
89
  ],
96
90
  "previewEntry": [
97
91
  "./dist/previewEntry.d.ts"
98
- ],
99
- "audio-waveform-worker": [
100
- "./dist/audio-waveform-worker.d.ts"
101
92
  ]
102
93
  }
103
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 timeline_utils_1 = require("@remotion/timeline-utils");
5
- const draw_peaks_1 = require("./components/draw-peaks");
6
- const load_waveform_peaks_1 = require("./components/load-waveform-peaks");
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, timeline_utils_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, timeline_utils_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, timeline_utils_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 });
@@ -1 +0,0 @@
1
- export declare const drawBars: (canvas: HTMLCanvasElement | OffscreenCanvas, peaks: Float32Array<ArrayBufferLike>, color: string, volume: number, width: number) => void;
@@ -1,68 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.drawBars = void 0;
4
- const parse_color_1 = require("./parse-color");
5
- const CLIPPING_COLOR = '#FF7F50';
6
- const drawBars = (canvas, peaks, color, volume, width) => {
7
- const ctx = canvas.getContext('2d');
8
- if (!ctx) {
9
- throw new Error('Failed to get canvas context');
10
- }
11
- const { height } = canvas;
12
- const w = canvas.width;
13
- // Skip drawing when the target canvas has not been laid out yet.
14
- // `createImageData(0, h)` / `(w, 0)` throws a DOMException, which
15
- // surfaces in Studio's console for compositions with many audio
16
- // sequences — some segments are 0 px wide at certain zoom levels.
17
- if (w === 0 || height === 0) {
18
- return;
19
- }
20
- ctx.clearRect(0, 0, w, height);
21
- if (volume === 0)
22
- return;
23
- const [r, g, b, a] = (0, parse_color_1.parseColor)(color);
24
- const [cr, cg, cb, ca] = (0, parse_color_1.parseColor)(CLIPPING_COLOR);
25
- const imageData = ctx.createImageData(w, height);
26
- const { data } = imageData;
27
- const numBars = width;
28
- for (let barIndex = 0; barIndex < numBars; barIndex++) {
29
- const x = barIndex;
30
- if (x >= w)
31
- break;
32
- const peakIndex = Math.floor((barIndex / numBars) * peaks.length);
33
- const peak = peaks[peakIndex] || 0;
34
- const scaledPeak = peak * volume;
35
- const halfBar = Math.max(0, Math.min(height / 2, (scaledPeak * height) / 2));
36
- if (halfBar === 0)
37
- continue;
38
- const mid = height / 2;
39
- const barY = Math.round(mid - halfBar);
40
- const barEnd = Math.round(mid + halfBar);
41
- const isClipping = scaledPeak > 1;
42
- const clipTopEnd = isClipping ? Math.min(barY + 2, barEnd) : barY;
43
- const clipBotStart = isClipping ? Math.max(barEnd - 2, barY) : barEnd;
44
- for (let y = barY; y < clipTopEnd; y++) {
45
- const idx = (y * w + x) * 4;
46
- data[idx] = cr;
47
- data[idx + 1] = cg;
48
- data[idx + 2] = cb;
49
- data[idx + 3] = ca;
50
- }
51
- for (let y = clipTopEnd; y < clipBotStart; y++) {
52
- const idx = (y * w + x) * 4;
53
- data[idx] = r;
54
- data[idx + 1] = g;
55
- data[idx + 2] = b;
56
- data[idx + 3] = a;
57
- }
58
- for (let y = clipBotStart; y < barEnd; y++) {
59
- const idx = (y * w + x) * 4;
60
- data[idx] = cr;
61
- data[idx + 1] = cg;
62
- data[idx + 2] = cb;
63
- data[idx + 3] = ca;
64
- }
65
- }
66
- ctx.putImageData(imageData, 0, 0);
67
- };
68
- exports.drawBars = drawBars;
@@ -1,13 +0,0 @@
1
- declare const TARGET_SAMPLE_RATE = 100;
2
- export { TARGET_SAMPLE_RATE };
3
- type Progress = {
4
- readonly peaks: Float32Array;
5
- readonly completedPeaks: number;
6
- readonly totalPeaks: number;
7
- readonly final: boolean;
8
- };
9
- type LoadWaveformPeaksOptions = {
10
- readonly onProgress?: (progress: Progress) => void;
11
- readonly progressIntervalInMs?: number;
12
- };
13
- export declare function loadWaveformPeaks(url: string, signal: AbortSignal, options?: LoadWaveformPeaksOptions): Promise<Float32Array>;
@@ -1,76 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TARGET_SAMPLE_RATE = void 0;
4
- exports.loadWaveformPeaks = loadWaveformPeaks;
5
- const mediabunny_1 = require("mediabunny");
6
- const waveform_peak_processor_1 = require("./waveform-peak-processor");
7
- const TARGET_SAMPLE_RATE = 100;
8
- exports.TARGET_SAMPLE_RATE = TARGET_SAMPLE_RATE;
9
- const DEFAULT_PROGRESS_INTERVAL_IN_MS = 50;
10
- const peaksCache = new Map();
11
- async function loadWaveformPeaks(url, signal, options) {
12
- var _a, _b;
13
- const cached = peaksCache.get(url);
14
- if (cached) {
15
- (0, waveform_peak_processor_1.emitWaveformProgress)({
16
- peaks: cached,
17
- completedPeaks: cached.length,
18
- totalPeaks: cached.length,
19
- final: true,
20
- onProgress: options === null || options === void 0 ? void 0 : options.onProgress,
21
- });
22
- return cached;
23
- }
24
- const input = new mediabunny_1.Input({
25
- formats: mediabunny_1.ALL_FORMATS,
26
- source: new mediabunny_1.UrlSource(url),
27
- });
28
- try {
29
- const audioTrack = await input.getPrimaryAudioTrack();
30
- if (!audioTrack) {
31
- return new Float32Array(0);
32
- }
33
- if (await audioTrack.isLive()) {
34
- throw new Error('Live streams are not currently supported by Remotion. Sorry! Source: ' +
35
- url);
36
- }
37
- if (await audioTrack.isRelativeToUnixEpoch()) {
38
- throw new Error('Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: ' +
39
- url);
40
- }
41
- const sampleRate = await audioTrack.getSampleRate();
42
- const durationInSeconds = (_a = (await audioTrack.getDurationFromMetadata({ skipLiveWait: true }))) !== null && _a !== void 0 ? _a : (await audioTrack.computeDuration({ skipLiveWait: true }));
43
- const totalPeaks = Math.ceil(durationInSeconds * TARGET_SAMPLE_RATE);
44
- const samplesPerPeak = Math.max(1, Math.floor(sampleRate / TARGET_SAMPLE_RATE));
45
- const sink = new mediabunny_1.AudioSampleSink(audioTrack);
46
- const processor = (0, waveform_peak_processor_1.createWaveformPeakProcessor)({
47
- totalPeaks,
48
- samplesPerPeak,
49
- onProgress: options === null || options === void 0 ? void 0 : options.onProgress,
50
- progressIntervalInMs: (_b = options === null || options === void 0 ? void 0 : options.progressIntervalInMs) !== null && _b !== void 0 ? _b : DEFAULT_PROGRESS_INTERVAL_IN_MS,
51
- now: () => Date.now(),
52
- });
53
- for await (const sample of sink.samples()) {
54
- if (signal.aborted) {
55
- sample.close();
56
- return new Float32Array(0);
57
- }
58
- const bytesNeeded = sample.allocationSize({
59
- format: 'f32',
60
- planeIndex: 0,
61
- });
62
- const floats = new Float32Array(bytesNeeded / 4);
63
- sample.copyTo(floats, { format: 'f32', planeIndex: 0 });
64
- const channels = Math.max(1, sample.numberOfChannels);
65
- sample.close();
66
- processor.processSampleChunk(floats, channels);
67
- }
68
- processor.finalize();
69
- const { peaks } = processor;
70
- peaksCache.set(url, peaks);
71
- return peaks;
72
- }
73
- finally {
74
- input.dispose();
75
- }
76
- }
@@ -1 +0,0 @@
1
- export declare const parseColor: (color: string) => [number, number, number, number];
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseColor = void 0;
4
- const colorCache = new Map();
5
- const parseColor = (color) => {
6
- const cached = colorCache.get(color);
7
- if (cached)
8
- return cached;
9
- const ctx = new OffscreenCanvas(1, 1).getContext('2d');
10
- ctx.fillStyle = color;
11
- ctx.fillRect(0, 0, 1, 1);
12
- const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
13
- const result = [r, g, b, a];
14
- colorCache.set(color, result);
15
- return result;
16
- };
17
- exports.parseColor = parseColor;
@@ -1,7 +0,0 @@
1
- export declare const sliceWaveformPeaks: ({ durationInFrames, fps, peaks, playbackRate, startFrom, }: {
2
- readonly peaks: Float32Array<ArrayBufferLike>;
3
- readonly startFrom: number;
4
- readonly durationInFrames: number;
5
- readonly fps: number;
6
- readonly playbackRate: number;
7
- }) => Float32Array<ArrayBufferLike>;