UNPKG

@remotion/studio

Version:

APIs for interacting with the Remotion Studio

68 lines (67 loc) 2.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TARGET_SAMPLE_RATE = void 0; exports.loadWaveformPeaks = loadWaveformPeaks; const mediabunny_1 = require("mediabunny"); const TARGET_SAMPLE_RATE = 100; exports.TARGET_SAMPLE_RATE = TARGET_SAMPLE_RATE; const peaksCache = new Map(); async function loadWaveformPeaks(url, signal) { const cached = peaksCache.get(url); if (cached) return cached; const input = new mediabunny_1.Input({ formats: mediabunny_1.ALL_FORMATS, source: new mediabunny_1.UrlSource(url), }); try { const audioTrack = await input.getPrimaryAudioTrack(); if (!audioTrack) { return new Float32Array(0); } const { sampleRate } = audioTrack; const durationInSeconds = await audioTrack.computeDuration(); const totalPeaks = Math.ceil(durationInSeconds * TARGET_SAMPLE_RATE); const samplesPerPeak = Math.floor(sampleRate / TARGET_SAMPLE_RATE); const peaks = new Float32Array(totalPeaks); let peakIndex = 0; let peakMax = 0; let sampleInPeak = 0; const sink = new mediabunny_1.AudioSampleSink(audioTrack); for await (const sample of sink.samples()) { if (signal.aborted) { sample.close(); return new Float32Array(0); } const bytesNeeded = sample.allocationSize({ format: 'f32', planeIndex: 0, }); const floats = new Float32Array(bytesNeeded / 4); sample.copyTo(floats, { format: 'f32', planeIndex: 0 }); sample.close(); for (let i = 0; i < floats.length; i++) { const abs = Math.abs(floats[i]); if (abs > peakMax) peakMax = abs; sampleInPeak++; if (sampleInPeak >= samplesPerPeak) { if (peakIndex < totalPeaks) { peaks[peakIndex] = peakMax; } peakIndex++; peakMax = 0; sampleInPeak = 0; } } } if (sampleInPeak > 0 && peakIndex < totalPeaks) { peaks[peakIndex] = peakMax; } peaksCache.set(url, peaks); return peaks; } finally { input.dispose(); } }