@remotion/studio 4.0.441 → 4.0.442

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.
@@ -2,18 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AudioWaveform = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const media_utils_1 = require("@remotion/media-utils");
6
5
  const react_1 = require("react");
7
6
  const remotion_1 = require("remotion");
8
7
  const colors_1 = require("../helpers/colors");
9
8
  const timeline_layout_1 = require("../helpers/timeline-layout");
10
- const AudioWaveformBar_1 = require("./AudioWaveformBar");
9
+ const draw_peaks_1 = require("./draw-peaks");
10
+ const load_waveform_peaks_1 = require("./load-waveform-peaks");
11
11
  const container = {
12
12
  display: 'flex',
13
13
  flexDirection: 'row',
14
- alignItems: 'flex-end',
14
+ alignItems: 'center',
15
15
  position: 'absolute',
16
- height: (0, timeline_layout_1.getTimelineLayerHeight)('other'),
16
+ inset: 0,
17
17
  };
18
18
  const errorMessage = {
19
19
  fontSize: 13,
@@ -25,46 +25,87 @@ const errorMessage = {
25
25
  maxWidth: 450,
26
26
  opacity: 0.75,
27
27
  };
28
- const canvasStyle = {
28
+ const waveformCanvasStyle = {
29
+ pointerEvents: 'none',
30
+ };
31
+ const volumeCanvasStyle = {
29
32
  position: 'absolute',
30
33
  };
31
34
  const AudioWaveform = ({ src, startFrom, durationInFrames, visualizationWidth, volume, doesVolumeChange, playbackRate, }) => {
32
- const [metadata, setMetadata] = (0, react_1.useState)(null);
35
+ const [peaks, setPeaks] = (0, react_1.useState)(null);
33
36
  const [error, setError] = (0, react_1.useState)(null);
34
- const mountState = (0, react_1.useRef)({ isMounted: true });
35
37
  const vidConf = remotion_1.Internals.useUnsafeVideoConfig();
36
38
  if (vidConf === null) {
37
39
  throw new Error('Expected video config');
38
40
  }
39
- const canvas = (0, react_1.useRef)(null);
41
+ const containerRef = (0, react_1.useRef)(null);
42
+ const waveformCanvas = (0, react_1.useRef)(null);
43
+ const volumeCanvas = (0, react_1.useRef)(null);
40
44
  (0, react_1.useEffect)(() => {
41
- const { current } = mountState;
42
- current.isMounted = true;
43
- return () => {
44
- current.isMounted = false;
45
- };
46
- }, []);
45
+ const controller = new AbortController();
46
+ setError(null);
47
+ (0, load_waveform_peaks_1.loadWaveformPeaks)(src, controller.signal)
48
+ .then((p) => {
49
+ if (!controller.signal.aborted) {
50
+ setPeaks(p);
51
+ }
52
+ })
53
+ .catch((err) => {
54
+ if (!controller.signal.aborted) {
55
+ setError(err);
56
+ }
57
+ });
58
+ return () => controller.abort();
59
+ }, [src]);
60
+ const portionPeaks = (0, react_1.useMemo)(() => {
61
+ if (!peaks || peaks.length === 0) {
62
+ return null;
63
+ }
64
+ const startTimeInSeconds = startFrom / vidConf.fps;
65
+ const durationInSeconds = (durationInFrames / vidConf.fps) * playbackRate;
66
+ const startPeakIndex = Math.floor(startTimeInSeconds * load_waveform_peaks_1.TARGET_SAMPLE_RATE);
67
+ const endPeakIndex = Math.ceil((startTimeInSeconds + durationInSeconds) * load_waveform_peaks_1.TARGET_SAMPLE_RATE);
68
+ return peaks.slice(Math.max(0, startPeakIndex), Math.min(peaks.length, endPeakIndex));
69
+ }, [peaks, startFrom, durationInFrames, vidConf.fps, playbackRate]);
70
+ (0, react_1.useEffect)(() => {
71
+ const { current: canvasElement } = waveformCanvas;
72
+ const { current: containerElement } = containerRef;
73
+ if (!canvasElement ||
74
+ !containerElement ||
75
+ !portionPeaks ||
76
+ portionPeaks.length === 0) {
77
+ return;
78
+ }
79
+ const h = containerElement.clientHeight;
80
+ const w = Math.ceil(visualizationWidth);
81
+ canvasElement.width = w;
82
+ canvasElement.height = h;
83
+ const vol = typeof volume === 'number' ? volume : 1;
84
+ (0, draw_peaks_1.drawBars)(canvasElement, portionPeaks, 'rgba(255, 255, 255, 0.6)', vol, w);
85
+ }, [portionPeaks, visualizationWidth, volume]);
47
86
  (0, react_1.useEffect)(() => {
48
- if (!canvas.current) {
87
+ const { current: volumeCanvasElement } = volumeCanvas;
88
+ const { current: containerElement } = containerRef;
89
+ if (!volumeCanvasElement || !containerElement) {
49
90
  return;
50
91
  }
51
- const context = canvas.current.getContext('2d');
92
+ const h = containerElement.clientHeight;
93
+ const context = volumeCanvasElement.getContext('2d');
52
94
  if (!context) {
53
95
  return;
54
96
  }
55
- context.clearRect(0, 0, visualizationWidth, (0, timeline_layout_1.getTimelineLayerHeight)('other'));
97
+ volumeCanvasElement.width = Math.ceil(visualizationWidth);
98
+ volumeCanvasElement.height = h;
99
+ context.clearRect(0, 0, visualizationWidth, h);
56
100
  if (!doesVolumeChange || typeof volume === 'number') {
57
- // The volume is a number, meaning it could change on each frame-
58
- // User did not use the (f: number) => number syntax, so we can't draw
59
- // a visualization.
60
101
  return;
61
102
  }
62
103
  const volumes = volume.split(',').map((v) => Number(v));
63
104
  context.beginPath();
64
- context.moveTo(0, (0, timeline_layout_1.getTimelineLayerHeight)('other'));
105
+ context.moveTo(0, h);
65
106
  volumes.forEach((v, index) => {
66
107
  const x = (index / (volumes.length - 1)) * visualizationWidth;
67
- const y = (1 - v) * ((0, timeline_layout_1.getTimelineLayerHeight)('other') - timeline_layout_1.TIMELINE_BORDER * 2) + 1;
108
+ const y = (1 - v) * (h - timeline_layout_1.TIMELINE_BORDER * 2) + 1;
68
109
  if (index === 0) {
69
110
  context.moveTo(x, y);
70
111
  }
@@ -74,50 +115,15 @@ const AudioWaveform = ({ src, startFrom, durationInFrames, visualizationWidth, v
74
115
  });
75
116
  context.strokeStyle = colors_1.LIGHT_TRANSPARENT;
76
117
  context.stroke();
77
- }, [visualizationWidth, metadata, startFrom, volume, doesVolumeChange]);
78
- (0, react_1.useEffect)(() => {
79
- setError(null);
80
- (0, media_utils_1.getAudioData)(src)
81
- .then((data) => {
82
- if (mountState.current.isMounted) {
83
- setMetadata(data);
84
- }
85
- })
86
- .catch((err) => {
87
- if (mountState.current.isMounted) {
88
- setError(err);
89
- }
90
- });
91
- }, [src, vidConf.fps]);
92
- const normalized = (0, react_1.useMemo)(() => {
93
- if (!metadata || metadata.numberOfChannels === 0) {
94
- return [];
95
- }
96
- const numberOfSamples = Math.floor(visualizationWidth / (AudioWaveformBar_1.WAVEFORM_BAR_LENGTH + AudioWaveformBar_1.WAVEFORM_BAR_MARGIN));
97
- return (0, media_utils_1.getWaveformPortion)({
98
- audioData: metadata,
99
- startTimeInSeconds: startFrom / vidConf.fps,
100
- durationInSeconds: Math.min((durationInFrames / vidConf.fps) * playbackRate, metadata.durationInSeconds),
101
- numberOfSamples,
102
- normalize: false,
103
- });
104
- }, [
105
- durationInFrames,
106
- vidConf.fps,
107
- metadata,
108
- playbackRate,
109
- startFrom,
110
- visualizationWidth,
111
- ]);
118
+ }, [visualizationWidth, volume, doesVolumeChange]);
112
119
  if (error) {
113
120
  return (jsx_runtime_1.jsx("div", { style: container, children: jsx_runtime_1.jsx("div", { style: errorMessage, children: "No waveform available. Audio might not support CORS." }) }));
114
121
  }
115
- if (!metadata) {
122
+ if (!peaks) {
116
123
  return null;
117
124
  }
118
- return (jsx_runtime_1.jsxs("div", { style: container, children: [normalized.map((w) => {
119
- return (jsx_runtime_1.jsx(AudioWaveformBar_1.AudioWaveformBar, { amplitude: w.amplitude * (typeof volume === 'number' ? volume : 1) }, w.index));
120
- }), jsx_runtime_1.jsx("canvas", { ref: canvas, style: canvasStyle, width: visualizationWidth, height: (0, timeline_layout_1.getTimelineLayerHeight)('other') })
125
+ return (jsx_runtime_1.jsxs("div", { ref: containerRef, style: container, children: [
126
+ jsx_runtime_1.jsx("canvas", { ref: waveformCanvas, style: waveformCanvasStyle }), jsx_runtime_1.jsx("canvas", { ref: volumeCanvas, style: volumeCanvasStyle })
121
127
  ] }));
122
128
  };
123
129
  exports.AudioWaveform = AudioWaveform;
@@ -44,6 +44,7 @@ const canvas_ref_1 = require("../state/canvas-ref");
44
44
  const timeline_zoom_1 = require("../state/timeline-zoom");
45
45
  const z_index_1 = require("../state/z-index");
46
46
  const EditorContent_1 = require("./EditorContent");
47
+ const ForceSpecificCursor_1 = require("./ForceSpecificCursor");
47
48
  const GlobalKeybindings_1 = require("./GlobalKeybindings");
48
49
  const Modals_1 = require("./Modals");
49
50
  const NotificationCenter_1 = require("./Notifications/NotificationCenter");
@@ -83,10 +84,12 @@ const Editor = ({ Root, readOnlyStudio }) => {
83
84
  return react_1.default.memo(Root);
84
85
  }, [Root]);
85
86
  return (jsx_runtime_1.jsx(z_index_1.HigherZIndex, { onEscape: noop_1.noop, onOutsideClick: noop_1.noop, children: jsx_runtime_1.jsxs(timeline_zoom_1.TimelineZoomContext, { children: [
86
- jsx_runtime_1.jsx(remotion_1.Internals.CurrentScaleContext.Provider, { value: value, children: jsx_runtime_1.jsxs("div", { style: background, children: [canvasMounted ? jsx_runtime_1.jsx(MemoRoot, {}) : null, jsx_runtime_1.jsxs(remotion_1.Internals.CanUseRemotionHooksProvider, { children: [
87
- jsx_runtime_1.jsx(EditorContent_1.EditorContent, { readOnlyStudio: readOnlyStudio, children: jsx_runtime_1.jsx(TopPanel_1.TopPanel, { drawRef: canvas_ref_1.drawRef, bufferStateDelayInMilliseconds: exports.BUFFER_STATE_DELAY_IN_MILLISECONDS, onMounted: onMounted, readOnlyStudio: readOnlyStudio }) }), jsx_runtime_1.jsx(GlobalKeybindings_1.GlobalKeybindings, {})
88
- ] })
89
- ] }) }), jsx_runtime_1.jsx(Modals_1.Modals, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(NotificationCenter_1.NotificationCenter, {})
87
+ jsx_runtime_1.jsxs(remotion_1.Internals.CurrentScaleContext.Provider, { value: value, children: [
88
+ jsx_runtime_1.jsx(ForceSpecificCursor_1.ForceSpecificCursor, {}), jsx_runtime_1.jsxs("div", { style: background, children: [canvasMounted ? jsx_runtime_1.jsx(MemoRoot, {}) : null, jsx_runtime_1.jsxs(remotion_1.Internals.CanUseRemotionHooksProvider, { children: [
89
+ jsx_runtime_1.jsx(EditorContent_1.EditorContent, { readOnlyStudio: readOnlyStudio, children: jsx_runtime_1.jsx(TopPanel_1.TopPanel, { drawRef: canvas_ref_1.drawRef, bufferStateDelayInMilliseconds: exports.BUFFER_STATE_DELAY_IN_MILLISECONDS, onMounted: onMounted, readOnlyStudio: readOnlyStudio }) }), jsx_runtime_1.jsx(GlobalKeybindings_1.GlobalKeybindings, {})
90
+ ] })
91
+ ] })
92
+ ] }), jsx_runtime_1.jsx(Modals_1.Modals, { readOnlyStudio: readOnlyStudio }), jsx_runtime_1.jsx(NotificationCenter_1.NotificationCenter, {})
90
93
  ] }) }));
91
94
  };
92
95
  exports.Editor = Editor;
@@ -7,6 +7,7 @@ const colors_1 = require("../../helpers/colors");
7
7
  const editor_guides_1 = require("../../state/editor-guides");
8
8
  const editor_rulers_1 = require("../../state/editor-rulers");
9
9
  const ContextMenu_1 = require("../ContextMenu");
10
+ const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
10
11
  const PADDING_FOR_EASY_DRAG = 4;
11
12
  const GuideComp = ({ guide, canvasDimensions, scale }) => {
12
13
  const { shouldCreateGuideRef, setGuidesList, setSelectedGuideId, selectedGuideId, setHoveredGuideId, hoveredGuideId, } = (0, react_1.useContext)(editor_guides_1.EditorShowGuidesContext);
@@ -53,7 +54,7 @@ const GuideComp = ({ guide, canvasDimensions, scale }) => {
53
54
  return;
54
55
  }
55
56
  shouldCreateGuideRef.current = true;
56
- document.body.style.cursor = 'no-drop';
57
+ (0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
57
58
  setSelectedGuideId(() => guide.id);
58
59
  }, [shouldCreateGuideRef, setSelectedGuideId, guide.id]);
59
60
  const values = (0, react_1.useMemo)(() => {
@@ -7,6 +7,7 @@ const colors_1 = require("../../helpers/colors");
7
7
  const editor_ruler_1 = require("../../helpers/editor-ruler");
8
8
  const editor_guides_1 = require("../../state/editor-guides");
9
9
  const editor_rulers_1 = require("../../state/editor-rulers");
10
+ const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
10
11
  const makeGuideId = () => {
11
12
  return Math.random().toString(36).substring(7);
12
13
  };
@@ -67,7 +68,7 @@ const Ruler = ({ scale, points, originOffset, startMarking, size, markingGaps, o
67
68
  }
68
69
  e.preventDefault();
69
70
  shouldCreateGuideRef.current = true;
70
- document.body.style.cursor = 'no-drop';
71
+ (0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
71
72
  const guideId = makeGuideId();
72
73
  setEditorShowGuides(() => true);
73
74
  setSelectedGuideId(() => guideId);
@@ -11,6 +11,7 @@ const editor_ruler_1 = require("../../helpers/editor-ruler");
11
11
  const use_studio_canvas_dimensions_1 = require("../../helpers/use-studio-canvas-dimensions");
12
12
  const editor_guides_1 = require("../../state/editor-guides");
13
13
  const editor_rulers_1 = require("../../state/editor-rulers");
14
+ const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
14
15
  const Ruler_1 = __importDefault(require("./Ruler"));
15
16
  const originBlockStyles = {
16
17
  position: 'absolute',
@@ -70,9 +71,7 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
70
71
  if (!shouldDeleteGuideRef.current) {
71
72
  shouldDeleteGuideRef.current = true;
72
73
  }
73
- if (document.body.style.cursor !== 'no-drop') {
74
- document.body.style.cursor = 'no-drop';
75
- }
74
+ (0, ForceSpecificCursor_1.forceSpecificCursor)('no-drop');
76
75
  setGuidesList((prevState) => {
77
76
  const newGuides = prevState.map((guide) => {
78
77
  if (guide.id !== selectedGuideId) {
@@ -103,9 +102,7 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
103
102
  : (mouseY - containerTop) / scale -
104
103
  canvasPosition.top / scale;
105
104
  const desiredCursor = guide.orientation === 'vertical' ? 'ew-resize' : 'ns-resize';
106
- if (document.body.style.cursor !== desiredCursor) {
107
- document.body.style.cursor = desiredCursor;
108
- }
105
+ (0, ForceSpecificCursor_1.forceSpecificCursor)(desiredCursor);
109
106
  return {
110
107
  ...guide,
111
108
  position: Math.floor(position / 1.0),
@@ -136,7 +133,7 @@ const EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerR
136
133
  return newGuides;
137
134
  });
138
135
  shouldDeleteGuideRef.current = false;
139
- document.body.style.cursor = 'auto';
136
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
140
137
  shouldCreateGuideRef.current = false;
141
138
  setSelectedGuideId(() => null);
142
139
  document.removeEventListener('pointerup', onMouseUp);
@@ -0,0 +1,3 @@
1
+ export declare const forceSpecificCursor: (cursor: string) => void;
2
+ export declare const stopForcingSpecificCursor: () => void;
3
+ export declare const ForceSpecificCursor: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ForceSpecificCursor = exports.stopForcingSpecificCursor = exports.forceSpecificCursor = void 0;
37
+ const jsx_runtime_1 = require("react/jsx-runtime");
38
+ const react_1 = __importStar(require("react"));
39
+ const ref = react_1.default.createRef();
40
+ const forceSpecificCursor = (cursor) => {
41
+ if (!ref.current) {
42
+ throw new Error('ForceSpecificCursor is not mounted');
43
+ }
44
+ ref.current.style.cursor = cursor;
45
+ ref.current.style.pointerEvents = 'auto';
46
+ };
47
+ exports.forceSpecificCursor = forceSpecificCursor;
48
+ const stopForcingSpecificCursor = () => {
49
+ if (!ref.current) {
50
+ throw new Error('ForceSpecificCursor is not mounted');
51
+ }
52
+ ref.current.style.cursor = '';
53
+ ref.current.style.pointerEvents = 'none';
54
+ };
55
+ exports.stopForcingSpecificCursor = stopForcingSpecificCursor;
56
+ const Z_INDEX_FORCE_SPECIFIC_CURSOR = 100;
57
+ const ForceSpecificCursor = () => {
58
+ const style = (0, react_1.useMemo)(() => {
59
+ return {
60
+ position: 'fixed',
61
+ inset: 0,
62
+ zIndex: Z_INDEX_FORCE_SPECIFIC_CURSOR,
63
+ pointerEvents: 'none',
64
+ };
65
+ }, []);
66
+ return jsx_runtime_1.jsx("div", { ref: ref, style: style });
67
+ };
68
+ exports.ForceSpecificCursor = ForceSpecificCursor;
@@ -41,6 +41,7 @@ const colors_1 = require("../../helpers/colors");
41
41
  const noop_1 = require("../../helpers/noop");
42
42
  const input_dragger_click_lock_1 = require("../../state/input-dragger-click-lock");
43
43
  const z_index_1 = require("../../state/z-index");
44
+ const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
44
45
  const RemInput_1 = require("./RemInput");
45
46
  const isInt = (num) => {
46
47
  return num % 1 === 0;
@@ -135,6 +136,7 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
135
136
  if (distanceFromStart > 4) {
136
137
  (0, input_dragger_click_lock_1.setClickLock)(true);
137
138
  setDragging(true);
139
+ (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
138
140
  target.blur();
139
141
  }
140
142
  const diff = (0, remotion_1.interpolate)(xDistance, [-5, -4, 0, 4, 5], [-step, 0, 0, 0, step]);
@@ -148,6 +150,7 @@ const InputDraggerForwardRefFn = ({ onValueChange, onValueChangeEnd, min: _min,
148
150
  window.removeEventListener('mousemove', moveListener);
149
151
  pointerDownRef.current = false;
150
152
  setDragging(false);
153
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
151
154
  if (lastDragValue !== null && onValueChangeEnd) {
152
155
  onValueChangeEnd(lastDragValue);
153
156
  }
@@ -103,13 +103,20 @@ const RenderModalJSONPropsEditor = ({ setValue, value, defaultProps, onSave, ser
103
103
  }
104
104
  const { result } = e;
105
105
  if (result.canUpdate) {
106
- setLocalValue(parseJS(result.currentDefaultProps, schema));
106
+ const nextState = parseJS(result.currentDefaultProps, schema);
107
+ setLocalValue(nextState);
107
108
  }
108
109
  });
109
110
  return () => {
110
111
  unsub();
111
112
  };
112
113
  }, [subscribeToEvent, compositionId, schema]);
114
+ (0, react_1.useEffect)(() => {
115
+ if (localValue.validJSON && (0, deep_equal_1.deepEqual)(value, localValue.value)) {
116
+ return;
117
+ }
118
+ setLocalValue(parseJS(value, schema));
119
+ }, [value, schema, localValue]);
113
120
  const onPretty = (0, react_1.useCallback)(() => {
114
121
  if (!localValue.validJSON) {
115
122
  return;
@@ -137,8 +144,8 @@ const RenderModalJSONPropsEditor = ({ setValue, value, defaultProps, onSave, ser
137
144
  }, [hasChanged, hasError, onSave]);
138
145
  // If schema is changed in code
139
146
  (0, react_1.useEffect)(() => {
140
- setLocalValue(parseJSON(localValue.str, schema));
141
- }, [localValue.str, schema]);
147
+ setLocalValue((v) => parseJSON(v.str, schema));
148
+ }, [schema]);
142
149
  const reset = (0, react_1.useCallback)(() => {
143
150
  setValue(defaultProps);
144
151
  setLocalValue(parseJSON(JSON.stringify(defaultProps, null, 2), schema));
@@ -4,6 +4,7 @@ exports.SplitterHandle = exports.SPLITTER_HANDLE_SIZE = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const player_1 = require("@remotion/player");
6
6
  const react_1 = require("react");
7
+ const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
7
8
  const SplitterContext_1 = require("./SplitterContext");
8
9
  exports.SPLITTER_HANDLE_SIZE = 3;
9
10
  const containerRow = {
@@ -58,6 +59,7 @@ const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
58
59
  x: e.clientX,
59
60
  y: e.clientY,
60
61
  };
62
+ (0, ForceSpecificCursor_1.forceSpecificCursor)(context.orientation === 'horizontal' ? 'row-resize' : 'col-resize');
61
63
  (_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.add('remotion-splitter-active');
62
64
  window.addEventListener('pointerup', (ev) => {
63
65
  if (!context.isDragging.current) {
@@ -94,6 +96,7 @@ const SplitterHandle = ({ allowToCollapse, onCollapse }) => {
94
96
  const cleanup = () => {
95
97
  var _a;
96
98
  context.isDragging.current = false;
99
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
97
100
  (_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.remove('remotion-splitter-active');
98
101
  current.removeEventListener('pointerdown', onPointerDown);
99
102
  window.removeEventListener('pointermove', onPointerMove);
@@ -75,15 +75,15 @@ const TimelineInner = () => {
75
75
  const visualModeEnabled = Boolean(process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED) &&
76
76
  previewServerState.type === 'connected';
77
77
  const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
78
+ const videoConfigIsNull = videoConfig === null;
78
79
  const timeline = (0, react_1.useMemo)(() => {
79
- if (!videoConfig) {
80
+ if (videoConfigIsNull) {
80
81
  return [];
81
82
  }
82
83
  return (0, calculate_timeline_1.calculateTimeline)({
83
84
  sequences,
84
- sequenceDuration: videoConfig.durationInFrames,
85
85
  });
86
- }, [sequences, videoConfig]);
86
+ }, [sequences, videoConfigIsNull]);
87
87
  const durationInFrames = (_a = videoConfig === null || videoConfig === void 0 ? void 0 : videoConfig.durationInFrames) !== null && _a !== void 0 ? _a : 0;
88
88
  const filtered = (0, react_1.useMemo)(() => {
89
89
  const withoutHidden = timeline.filter((t) => !(0, is_collapsed_1.isTrackHidden)(t));
@@ -11,6 +11,7 @@ const in_out_1 = require("../../state/in-out");
11
11
  const timeline_zoom_1 = require("../../state/timeline-zoom");
12
12
  const z_index_1 = require("../../state/z-index");
13
13
  const ContextMenu_1 = require("../ContextMenu");
14
+ const ForceSpecificCursor_1 = require("../ForceSpecificCursor");
14
15
  const is_menu_item_1 = require("../Menu/is-menu-item");
15
16
  const TimelineInOutToggle_1 = require("../TimelineInOutToggle");
16
17
  const timeline_refs_1 = require("./timeline-refs");
@@ -115,6 +116,7 @@ const Inner = () => {
115
116
  }
116
117
  const inMarker = get(inFrame);
117
118
  const outMarker = outFrame === null ? Infinity : get(outFrame - 1);
119
+ (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
118
120
  setInOutDragging({
119
121
  dragging: 'in',
120
122
  initialOffset: getClientXWithScroll(e.clientX),
@@ -128,6 +130,7 @@ const Inner = () => {
128
130
  }
129
131
  const outMarker = get(outFrame);
130
132
  const inMarker = inFrame === null ? -Infinity : get(inFrame + 1);
133
+ (0, ForceSpecificCursor_1.forceSpecificCursor)('ew-resize');
131
134
  setInOutDragging({
132
135
  dragging: 'out',
133
136
  initialOffset: getClientXWithScroll(e.clientX),
@@ -311,6 +314,7 @@ const Inner = () => {
311
314
  const onPointerUpInOut = (0, react_1.useCallback)((e) => {
312
315
  document.body.style.userSelect = '';
313
316
  document.body.style.webkitUserSelect = '';
317
+ (0, ForceSpecificCursor_1.stopForcingSpecificCursor)();
314
318
  if (!videoConfig) {
315
319
  return;
316
320
  }
@@ -4,6 +4,7 @@ exports.TimelineWidthProvider = exports.TimelineWidthContext = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const player_1 = require("@remotion/player");
6
6
  const react_1 = require("react");
7
+ const timeline_zoom_1 = require("../../state/timeline-zoom");
7
8
  const timeline_refs_1 = require("./timeline-refs");
8
9
  exports.TimelineWidthContext = (0, react_1.createContext)(null);
9
10
  const TimelineWidthProvider = ({ children }) => {
@@ -12,6 +13,20 @@ const TimelineWidthProvider = ({ children }) => {
12
13
  triggerOnWindowResize: false,
13
14
  shouldApplyCssTransforms: true,
14
15
  });
15
- return (jsx_runtime_1.jsx(exports.TimelineWidthContext.Provider, { value: (_a = size === null || size === void 0 ? void 0 : size.width) !== null && _a !== void 0 ? _a : null, children: children }));
16
+ const { zoom: zoomMap } = (0, react_1.useContext)(timeline_zoom_1.TimelineZoomCtx);
17
+ const [widthOverride, setWidthOverride] = (0, react_1.useState)(null);
18
+ const observedWidth = (_a = size === null || size === void 0 ? void 0 : size.width) !== null && _a !== void 0 ? _a : null;
19
+ (0, react_1.useLayoutEffect)(() => {
20
+ var _a;
21
+ var _b;
22
+ const actual = (_b = (_a = timeline_refs_1.sliderAreaRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _b !== void 0 ? _b : null;
23
+ if (actual !== null && actual !== observedWidth) {
24
+ setWidthOverride(actual);
25
+ }
26
+ else {
27
+ setWidthOverride(null);
28
+ }
29
+ }, [observedWidth, zoomMap]);
30
+ return (jsx_runtime_1.jsx(exports.TimelineWidthContext.Provider, { value: widthOverride !== null && widthOverride !== void 0 ? widthOverride : observedWidth, children: children }));
16
31
  };
17
32
  exports.TimelineWidthProvider = TimelineWidthProvider;
@@ -0,0 +1 @@
1
+ export declare const drawBars: (canvas: HTMLCanvasElement, peaks: Float32Array<ArrayBufferLike>, color: string, volume: number, width: number) => void;
@@ -0,0 +1,61 @@
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
+ ctx.clearRect(0, 0, w, height);
14
+ if (volume === 0)
15
+ return;
16
+ const [r, g, b, a] = (0, parse_color_1.parseColor)(color);
17
+ const [cr, cg, cb, ca] = (0, parse_color_1.parseColor)(CLIPPING_COLOR);
18
+ const imageData = ctx.createImageData(w, height);
19
+ const { data } = imageData;
20
+ const numBars = width;
21
+ for (let barIndex = 0; barIndex < numBars; barIndex++) {
22
+ const x = barIndex;
23
+ if (x >= w)
24
+ break;
25
+ const peakIndex = Math.floor((barIndex / numBars) * peaks.length);
26
+ const peak = peaks[peakIndex] || 0;
27
+ const scaledPeak = peak * volume;
28
+ const halfBar = Math.max(0, Math.min(height / 2, (scaledPeak * height) / 2));
29
+ if (halfBar === 0)
30
+ continue;
31
+ const mid = height / 2;
32
+ const barY = Math.round(mid - halfBar);
33
+ const barEnd = Math.round(mid + halfBar);
34
+ const isClipping = scaledPeak > 1;
35
+ const clipTopEnd = isClipping ? Math.min(barY + 2, barEnd) : barY;
36
+ const clipBotStart = isClipping ? Math.max(barEnd - 2, barY) : barEnd;
37
+ for (let y = barY; y < clipTopEnd; y++) {
38
+ const idx = (y * w + x) * 4;
39
+ data[idx] = cr;
40
+ data[idx + 1] = cg;
41
+ data[idx + 2] = cb;
42
+ data[idx + 3] = ca;
43
+ }
44
+ for (let y = clipTopEnd; y < clipBotStart; y++) {
45
+ const idx = (y * w + x) * 4;
46
+ data[idx] = r;
47
+ data[idx + 1] = g;
48
+ data[idx + 2] = b;
49
+ data[idx + 3] = a;
50
+ }
51
+ for (let y = clipBotStart; y < barEnd; y++) {
52
+ const idx = (y * w + x) * 4;
53
+ data[idx] = cr;
54
+ data[idx + 1] = cg;
55
+ data[idx + 2] = cb;
56
+ data[idx + 3] = ca;
57
+ }
58
+ }
59
+ ctx.putImageData(imageData, 0, 0);
60
+ };
61
+ exports.drawBars = drawBars;
@@ -0,0 +1,3 @@
1
+ declare const TARGET_SAMPLE_RATE = 100;
2
+ export { TARGET_SAMPLE_RATE };
3
+ export declare function loadWaveformPeaks(url: string, signal: AbortSignal): Promise<Float32Array>;