@remotion/timeline-utils 4.0.462 → 4.0.463

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.
@@ -5,6 +5,7 @@ exports.loadWaveformPeaks = loadWaveformPeaks;
5
5
  const mediabunny_1 = require("mediabunny");
6
6
  const constants_1 = require("./constants");
7
7
  Object.defineProperty(exports, "TARGET_SAMPLE_RATE", { enumerable: true, get: function () { return constants_1.TARGET_SAMPLE_RATE; } });
8
+ const trim_audio_sample_before_zero_1 = require("./trim-audio-sample-before-zero");
8
9
  const waveform_peak_processor_1 = require("./waveform-peak-processor");
9
10
  const DEFAULT_PROGRESS_INTERVAL_IN_MS = 50;
10
11
  const peaksCache = new Map();
@@ -55,12 +56,29 @@ async function loadWaveformPeaks(url, signal, options) {
55
56
  sample.close();
56
57
  return new Float32Array(0);
57
58
  }
59
+ const startFrame = (0, trim_audio_sample_before_zero_1.getAudioSampleStartFrameAtTimelineZero)(sample);
60
+ if (startFrame === null) {
61
+ sample.close();
62
+ continue;
63
+ }
64
+ const frameCount = sample.numberOfFrames - startFrame;
65
+ if (frameCount <= 0) {
66
+ sample.close();
67
+ continue;
68
+ }
58
69
  const bytesNeeded = sample.allocationSize({
59
70
  format: 'f32',
60
71
  planeIndex: 0,
72
+ frameOffset: startFrame,
73
+ frameCount,
61
74
  });
62
75
  const floats = new Float32Array(bytesNeeded / 4);
63
- sample.copyTo(floats, { format: 'f32', planeIndex: 0 });
76
+ sample.copyTo(floats, {
77
+ format: 'f32',
78
+ planeIndex: 0,
79
+ frameOffset: startFrame,
80
+ frameCount,
81
+ });
64
82
  const channels = Math.max(1, sample.numberOfChannels);
65
83
  sample.close();
66
84
  processor.processSampleChunk(floats, channels);
@@ -0,0 +1,11 @@
1
+ export type AudioSampleTiming = {
2
+ readonly timestamp: number;
3
+ readonly numberOfFrames: number;
4
+ readonly duration: number;
5
+ readonly sampleRate: number;
6
+ };
7
+ /**
8
+ * Returns the first frame index to include when building a timeline-aligned waveform.
9
+ * Returns null when the entire sample ends before timeline t=0.
10
+ */
11
+ export declare const getAudioSampleStartFrameAtTimelineZero: (sample: AudioSampleTiming) => number | null;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAudioSampleStartFrameAtTimelineZero = void 0;
4
+ /**
5
+ * Returns the first frame index to include when building a timeline-aligned waveform.
6
+ * Returns null when the entire sample ends before timeline t=0.
7
+ */
8
+ const getAudioSampleStartFrameAtTimelineZero = (sample) => {
9
+ if (sample.timestamp + sample.duration <= 0) {
10
+ return null;
11
+ }
12
+ if (sample.timestamp >= 0) {
13
+ return 0;
14
+ }
15
+ return Math.min(sample.numberOfFrames, Math.ceil(-sample.timestamp * sample.sampleRate));
16
+ };
17
+ exports.getAudioSampleStartFrameAtTimelineZero = getAudioSampleStartFrameAtTimelineZero;
@@ -86,6 +86,17 @@ import { ALL_FORMATS, AudioSampleSink, Input, UrlSource } from "mediabunny";
86
86
  // src/audio-waveform/constants.ts
87
87
  var TARGET_SAMPLE_RATE = 100;
88
88
 
89
+ // src/audio-waveform/trim-audio-sample-before-zero.ts
90
+ var getAudioSampleStartFrameAtTimelineZero = (sample) => {
91
+ if (sample.timestamp + sample.duration <= 0) {
92
+ return null;
93
+ }
94
+ if (sample.timestamp >= 0) {
95
+ return 0;
96
+ }
97
+ return Math.min(sample.numberOfFrames, Math.ceil(-sample.timestamp * sample.sampleRate));
98
+ };
99
+
89
100
  // src/audio-waveform/waveform-peak-processor.ts
90
101
  var emitWaveformProgress = ({
91
102
  completedPeaks,
@@ -217,12 +228,29 @@ async function loadWaveformPeaks(url, signal, options) {
217
228
  sample.close();
218
229
  return new Float32Array(0);
219
230
  }
231
+ const startFrame = getAudioSampleStartFrameAtTimelineZero(sample);
232
+ if (startFrame === null) {
233
+ sample.close();
234
+ continue;
235
+ }
236
+ const frameCount = sample.numberOfFrames - startFrame;
237
+ if (frameCount <= 0) {
238
+ sample.close();
239
+ continue;
240
+ }
220
241
  const bytesNeeded = sample.allocationSize({
221
242
  format: "f32",
222
- planeIndex: 0
243
+ planeIndex: 0,
244
+ frameOffset: startFrame,
245
+ frameCount
223
246
  });
224
247
  const floats = new Float32Array(bytesNeeded / 4);
225
- sample.copyTo(floats, { format: "f32", planeIndex: 0 });
248
+ sample.copyTo(floats, {
249
+ format: "f32",
250
+ planeIndex: 0,
251
+ frameOffset: startFrame,
252
+ frameCount
253
+ });
226
254
  const channels = Math.max(1, sample.numberOfChannels);
227
255
  sample.close();
228
256
  processor.processSampleChunk(floats, channels);
@@ -84,6 +84,17 @@ var drawBars = ({
84
84
  // src/audio-waveform/load-waveform-peaks.ts
85
85
  import { ALL_FORMATS, AudioSampleSink, Input, UrlSource } from "mediabunny";
86
86
 
87
+ // src/audio-waveform/trim-audio-sample-before-zero.ts
88
+ var getAudioSampleStartFrameAtTimelineZero = (sample) => {
89
+ if (sample.timestamp + sample.duration <= 0) {
90
+ return null;
91
+ }
92
+ if (sample.timestamp >= 0) {
93
+ return 0;
94
+ }
95
+ return Math.min(sample.numberOfFrames, Math.ceil(-sample.timestamp * sample.sampleRate));
96
+ };
97
+
87
98
  // src/audio-waveform/waveform-peak-processor.ts
88
99
  var emitWaveformProgress = ({
89
100
  completedPeaks,
@@ -215,12 +226,29 @@ async function loadWaveformPeaks(url, signal, options) {
215
226
  sample.close();
216
227
  return new Float32Array(0);
217
228
  }
229
+ const startFrame = getAudioSampleStartFrameAtTimelineZero(sample);
230
+ if (startFrame === null) {
231
+ sample.close();
232
+ continue;
233
+ }
234
+ const frameCount = sample.numberOfFrames - startFrame;
235
+ if (frameCount <= 0) {
236
+ sample.close();
237
+ continue;
238
+ }
218
239
  const bytesNeeded = sample.allocationSize({
219
240
  format: "f32",
220
- planeIndex: 0
241
+ planeIndex: 0,
242
+ frameOffset: startFrame,
243
+ frameCount
221
244
  });
222
245
  const floats = new Float32Array(bytesNeeded / 4);
223
- sample.copyTo(floats, { format: "f32", planeIndex: 0 });
246
+ sample.copyTo(floats, {
247
+ format: "f32",
248
+ planeIndex: 0,
249
+ frameOffset: startFrame,
250
+ frameCount
251
+ });
224
252
  const channels = Math.max(1, sample.numberOfChannels);
225
253
  sample.close();
226
254
  processor.processSampleChunk(floats, channels);
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.462",
6
+ "version": "4.0.463",
7
7
  "description": "Internal utilities for rendering Remotion timelines",
8
8
  "main": "dist/index.js",
9
9
  "scripts": {
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "@mediabunny/server": "1.45.0",
28
- "@remotion/eslint-config-internal": "4.0.462",
28
+ "@remotion/eslint-config-internal": "4.0.463",
29
29
  "eslint": "9.19.0",
30
30
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
31
31
  },