@remotion/timeline-utils 4.0.527 → 4.0.529
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.
- package/dist/audio-waveform/get-visible-waveform-volume.d.ts +1 -3
- package/dist/audio-waveform/get-visible-waveform-volume.js +6 -24
- package/dist/audio-waveform/slice-visible-waveform-peaks.js +1 -2
- package/dist/audio-waveform/slice-waveform-peaks.js +12 -2
- package/dist/esm/index.mjs +51 -66
- package/package.json +3 -3
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { type TimelineLoopDisplay } from '../loop-display';
|
|
2
1
|
import type { WaveformVolume } from './draw-peaks';
|
|
3
|
-
export declare const getVisibleWaveformVolume: ({ displayDurationInFrames, displayOffsetInFrames,
|
|
2
|
+
export declare const getVisibleWaveformVolume: ({ displayDurationInFrames, displayOffsetInFrames, volume, }: {
|
|
4
3
|
readonly displayDurationInFrames: number;
|
|
5
4
|
readonly displayOffsetInFrames: number;
|
|
6
|
-
readonly loopDisplay: TimelineLoopDisplay | undefined;
|
|
7
5
|
readonly volume: WaveformVolume;
|
|
8
6
|
}) => WaveformVolume;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getVisibleWaveformVolume = void 0;
|
|
4
|
-
const
|
|
5
|
-
const getVisibleWaveformVolume = ({ displayDurationInFrames, displayOffsetInFrames, loopDisplay, volume, }) => {
|
|
4
|
+
const getVisibleWaveformVolume = ({ displayDurationInFrames, displayOffsetInFrames, volume, }) => {
|
|
6
5
|
if (!Array.isArray(volume)) {
|
|
7
6
|
return volume;
|
|
8
7
|
}
|
|
@@ -10,27 +9,10 @@ const getVisibleWaveformVolume = ({ displayDurationInFrames, displayOffsetInFram
|
|
|
10
9
|
displayDurationInFrames <= 0) {
|
|
11
10
|
return [];
|
|
12
11
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
const segments = (0, loop_display_1.getLoopDisplaySegments)({
|
|
20
|
-
displayDurationInFrames,
|
|
21
|
-
displayOffsetInFrames,
|
|
22
|
-
loopDurationInFrames: loopDisplay.durationInFrames,
|
|
23
|
-
});
|
|
24
|
-
const result = [];
|
|
25
|
-
for (const segment of segments) {
|
|
26
|
-
const start = Math.max(0, Math.floor(segment.loopOffsetInFrames));
|
|
27
|
-
const end = Math.min(volume.length, Math.ceil(segment.loopOffsetInFrames + segment.durationInFrames));
|
|
28
|
-
// Do not `push(...slice)`: Chrome throws RangeError: Invalid array length
|
|
29
|
-
// once a loop segment is longer than ~65k frames.
|
|
30
|
-
for (let index = start; index < end; index++) {
|
|
31
|
-
result.push(volume[index]);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return result;
|
|
12
|
+
// Registered curves already cover the visible composition timeline, including
|
|
13
|
+
// repeat/extend behavior and partial loops introduced by ancestor trimming.
|
|
14
|
+
const start = Math.max(0, Math.floor(displayOffsetInFrames));
|
|
15
|
+
const end = Math.min(volume.length, Math.ceil(displayOffsetInFrames + displayDurationInFrames));
|
|
16
|
+
return volume.slice(start, end);
|
|
35
17
|
};
|
|
36
18
|
exports.getVisibleWaveformVolume = getVisibleWaveformVolume;
|
|
@@ -4,8 +4,7 @@ exports.sliceVisibleWaveformPeaks = void 0;
|
|
|
4
4
|
const loop_display_1 = require("../loop-display");
|
|
5
5
|
const slice_waveform_peaks_1 = require("./slice-waveform-peaks");
|
|
6
6
|
const sliceVisibleWaveformPeaks = ({ displayDurationInFrames, displayOffsetInFrames, durationInFrames, fps, loopDisplay, peaks, playbackRate, startFrom, waveformSampleRate, }) => {
|
|
7
|
-
if (!
|
|
8
|
-
loopDisplay.durationInFrames <= 0) {
|
|
7
|
+
if (!loopDisplay || loopDisplay.durationInFrames <= 0) {
|
|
9
8
|
return (0, slice_waveform_peaks_1.sliceWaveformPeaks)({
|
|
10
9
|
durationInFrames: Math.min(displayDurationInFrames, Math.max(0, durationInFrames - displayOffsetInFrames)),
|
|
11
10
|
fps,
|
|
@@ -8,8 +8,18 @@ const sliceWaveformPeaks = ({ durationInFrames, fps, peaks, playbackRate, startF
|
|
|
8
8
|
}
|
|
9
9
|
const startTimeInSeconds = startFrom / fps;
|
|
10
10
|
const durationInSeconds = (durationInFrames / fps) * playbackRate;
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const start = startTimeInSeconds * waveformSampleRate;
|
|
12
|
+
const end = (startTimeInSeconds + durationInSeconds) * waveformSampleRate;
|
|
13
|
+
// Fractional loop periods can round an exact trim boundary a few ULPs past
|
|
14
|
+
// the next sample. Do not include a peak from outside the trimmed source.
|
|
15
|
+
const startPeakIndex = Math.floor(start +
|
|
16
|
+
(Number.isFinite(start)
|
|
17
|
+
? Number.EPSILON * Math.max(1, Math.abs(start)) * 4
|
|
18
|
+
: 0));
|
|
19
|
+
const endPeakIndex = Math.ceil(end -
|
|
20
|
+
(Number.isFinite(end)
|
|
21
|
+
? Number.EPSILON * Math.max(1, Math.abs(end)) * 4
|
|
22
|
+
: 0));
|
|
13
23
|
if (!Number.isFinite(startPeakIndex) || !Number.isFinite(endPeakIndex)) {
|
|
14
24
|
return peaks.subarray(Math.max(0, startPeakIndex), Math.min(peaks.length, endPeakIndex));
|
|
15
25
|
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -99,54 +99,10 @@ var drawBars = ({
|
|
|
99
99
|
}
|
|
100
100
|
ctx.putImageData(imageData, 0, 0);
|
|
101
101
|
};
|
|
102
|
-
// src/loop-display.ts
|
|
103
|
-
var shouldTileLoopDisplay = (loopDisplay) => {
|
|
104
|
-
return loopDisplay !== undefined && loopDisplay.numberOfTimes > 1;
|
|
105
|
-
};
|
|
106
|
-
var getLoopDisplaySegments = ({
|
|
107
|
-
displayDurationInFrames,
|
|
108
|
-
displayOffsetInFrames,
|
|
109
|
-
loopDurationInFrames
|
|
110
|
-
}) => {
|
|
111
|
-
if (!Number.isFinite(displayDurationInFrames) || displayDurationInFrames <= 0 || !Number.isFinite(displayOffsetInFrames) || !Number.isFinite(loopDurationInFrames) || loopDurationInFrames <= 0) {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
const displayEndInFrames = displayOffsetInFrames + displayDurationInFrames;
|
|
115
|
-
const firstLoopIndex = Math.floor(displayOffsetInFrames / loopDurationInFrames);
|
|
116
|
-
const lastLoopIndex = Math.floor(displayEndInFrames / loopDurationInFrames);
|
|
117
|
-
const segments = [];
|
|
118
|
-
for (let loopIndex = firstLoopIndex;loopIndex <= lastLoopIndex; loopIndex++) {
|
|
119
|
-
const loopStartInFrames = loopIndex * loopDurationInFrames;
|
|
120
|
-
const segmentStart = Math.max(displayOffsetInFrames, loopStartInFrames);
|
|
121
|
-
const segmentEnd = Math.min(displayEndInFrames, loopStartInFrames + loopDurationInFrames);
|
|
122
|
-
const durationInFrames = segmentEnd - segmentStart;
|
|
123
|
-
if (durationInFrames <= 0) {
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
segments.push({
|
|
127
|
-
loopIndex,
|
|
128
|
-
absoluteOffsetInFrames: segmentStart,
|
|
129
|
-
loopOffsetInFrames: segmentStart - loopStartInFrames,
|
|
130
|
-
durationInFrames
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
return segments;
|
|
134
|
-
};
|
|
135
|
-
var getLoopDisplayWidth = ({
|
|
136
|
-
visualizationWidth,
|
|
137
|
-
loopDisplay
|
|
138
|
-
}) => {
|
|
139
|
-
if (!shouldTileLoopDisplay(loopDisplay)) {
|
|
140
|
-
return visualizationWidth;
|
|
141
|
-
}
|
|
142
|
-
return visualizationWidth / loopDisplay.numberOfTimes;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
102
|
// src/audio-waveform/get-visible-waveform-volume.ts
|
|
146
103
|
var getVisibleWaveformVolume = ({
|
|
147
104
|
displayDurationInFrames,
|
|
148
105
|
displayOffsetInFrames,
|
|
149
|
-
loopDisplay,
|
|
150
106
|
volume
|
|
151
107
|
}) => {
|
|
152
108
|
if (!Array.isArray(volume)) {
|
|
@@ -155,25 +111,9 @@ var getVisibleWaveformVolume = ({
|
|
|
155
111
|
if (!Number.isFinite(displayDurationInFrames) || displayDurationInFrames <= 0) {
|
|
156
112
|
return [];
|
|
157
113
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return volume.slice(start, end);
|
|
162
|
-
}
|
|
163
|
-
const segments = getLoopDisplaySegments({
|
|
164
|
-
displayDurationInFrames,
|
|
165
|
-
displayOffsetInFrames,
|
|
166
|
-
loopDurationInFrames: loopDisplay.durationInFrames
|
|
167
|
-
});
|
|
168
|
-
const result = [];
|
|
169
|
-
for (const segment of segments) {
|
|
170
|
-
const start = Math.max(0, Math.floor(segment.loopOffsetInFrames));
|
|
171
|
-
const end = Math.min(volume.length, Math.ceil(segment.loopOffsetInFrames + segment.durationInFrames));
|
|
172
|
-
for (let index = start;index < end; index++) {
|
|
173
|
-
result.push(volume[index]);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
return result;
|
|
114
|
+
const start = Math.max(0, Math.floor(displayOffsetInFrames));
|
|
115
|
+
const end = Math.min(volume.length, Math.ceil(displayOffsetInFrames + displayDurationInFrames));
|
|
116
|
+
return volume.slice(start, end);
|
|
177
117
|
};
|
|
178
118
|
// src/audio-waveform/load-waveform-peaks.ts
|
|
179
119
|
import { ALL_FORMATS, AudioSampleSink, Input, UrlSource } from "mediabunny";
|
|
@@ -389,6 +329,49 @@ async function loadWaveformPeaks(src, signal, options) {
|
|
|
389
329
|
input?.dispose();
|
|
390
330
|
}
|
|
391
331
|
}
|
|
332
|
+
// src/loop-display.ts
|
|
333
|
+
var shouldTileLoopDisplay = (loopDisplay) => {
|
|
334
|
+
return loopDisplay !== undefined && loopDisplay.numberOfTimes > 1;
|
|
335
|
+
};
|
|
336
|
+
var getLoopDisplaySegments = ({
|
|
337
|
+
displayDurationInFrames,
|
|
338
|
+
displayOffsetInFrames,
|
|
339
|
+
loopDurationInFrames
|
|
340
|
+
}) => {
|
|
341
|
+
if (!Number.isFinite(displayDurationInFrames) || displayDurationInFrames <= 0 || !Number.isFinite(displayOffsetInFrames) || !Number.isFinite(loopDurationInFrames) || loopDurationInFrames <= 0) {
|
|
342
|
+
return [];
|
|
343
|
+
}
|
|
344
|
+
const displayEndInFrames = displayOffsetInFrames + displayDurationInFrames;
|
|
345
|
+
const firstLoopIndex = Math.floor(displayOffsetInFrames / loopDurationInFrames);
|
|
346
|
+
const lastLoopIndex = Math.floor(displayEndInFrames / loopDurationInFrames);
|
|
347
|
+
const segments = [];
|
|
348
|
+
for (let loopIndex = firstLoopIndex;loopIndex <= lastLoopIndex; loopIndex++) {
|
|
349
|
+
const loopStartInFrames = loopIndex * loopDurationInFrames;
|
|
350
|
+
const segmentStart = Math.max(displayOffsetInFrames, loopStartInFrames);
|
|
351
|
+
const segmentEnd = Math.min(displayEndInFrames, loopStartInFrames + loopDurationInFrames);
|
|
352
|
+
const durationInFrames = segmentEnd - segmentStart;
|
|
353
|
+
if (durationInFrames <= 0) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
segments.push({
|
|
357
|
+
loopIndex,
|
|
358
|
+
absoluteOffsetInFrames: segmentStart,
|
|
359
|
+
loopOffsetInFrames: segmentStart - loopStartInFrames,
|
|
360
|
+
durationInFrames
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
return segments;
|
|
364
|
+
};
|
|
365
|
+
var getLoopDisplayWidth = ({
|
|
366
|
+
visualizationWidth,
|
|
367
|
+
loopDisplay
|
|
368
|
+
}) => {
|
|
369
|
+
if (!shouldTileLoopDisplay(loopDisplay)) {
|
|
370
|
+
return visualizationWidth;
|
|
371
|
+
}
|
|
372
|
+
return visualizationWidth / loopDisplay.numberOfTimes;
|
|
373
|
+
};
|
|
374
|
+
|
|
392
375
|
// src/audio-waveform/slice-waveform-peaks.ts
|
|
393
376
|
var sliceWaveformPeaks = ({
|
|
394
377
|
durationInFrames,
|
|
@@ -403,8 +386,10 @@ var sliceWaveformPeaks = ({
|
|
|
403
386
|
}
|
|
404
387
|
const startTimeInSeconds = startFrom / fps;
|
|
405
388
|
const durationInSeconds = durationInFrames / fps * playbackRate;
|
|
406
|
-
const
|
|
407
|
-
const
|
|
389
|
+
const start = startTimeInSeconds * waveformSampleRate;
|
|
390
|
+
const end = (startTimeInSeconds + durationInSeconds) * waveformSampleRate;
|
|
391
|
+
const startPeakIndex = Math.floor(start + (Number.isFinite(start) ? Number.EPSILON * Math.max(1, Math.abs(start)) * 4 : 0));
|
|
392
|
+
const endPeakIndex = Math.ceil(end - (Number.isFinite(end) ? Number.EPSILON * Math.max(1, Math.abs(end)) * 4 : 0));
|
|
408
393
|
if (!Number.isFinite(startPeakIndex) || !Number.isFinite(endPeakIndex)) {
|
|
409
394
|
return peaks.subarray(Math.max(0, startPeakIndex), Math.min(peaks.length, endPeakIndex));
|
|
410
395
|
}
|
|
@@ -432,7 +417,7 @@ var sliceVisibleWaveformPeaks = ({
|
|
|
432
417
|
startFrom,
|
|
433
418
|
waveformSampleRate
|
|
434
419
|
}) => {
|
|
435
|
-
if (!
|
|
420
|
+
if (!loopDisplay || loopDisplay.durationInFrames <= 0) {
|
|
436
421
|
return sliceWaveformPeaks({
|
|
437
422
|
durationInFrames: Math.min(displayDurationInFrames, Math.max(0, durationInFrames - displayOffsetInFrames)),
|
|
438
423
|
fps,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/timeline-utils"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/timeline-utils",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.529",
|
|
7
7
|
"description": "Internal utilities for rendering Remotion timelines",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"scripts": {
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"mediabunny": "1.56.1",
|
|
25
|
-
"remotion": "4.0.
|
|
25
|
+
"remotion": "4.0.529"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@mediabunny/server": "1.56.1",
|
|
29
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
29
|
+
"@remotion/eslint-config-internal": "4.0.529",
|
|
30
30
|
"eslint": "9.19.0",
|
|
31
31
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
32
32
|
},
|