37 lines
984 B
TypeScript
37 lines
984 B
TypeScript
const BARS = 48;
|
|
const MIN_BAR = 0.08;
|
|
|
|
export async function computeWaveform(
|
|
url: string,
|
|
bars = BARS
|
|
): Promise<number[]> {
|
|
const response = await fetch(url);
|
|
const buffer = await response.arrayBuffer();
|
|
const ctx = new AudioContext();
|
|
try {
|
|
const audio = await ctx.decodeAudioData(buffer);
|
|
const data = audio.getChannelData(0);
|
|
const block = Math.max(1, Math.floor(data.length / bars));
|
|
const peaks: number[] = [];
|
|
for (let i = 0; i < bars; i++) {
|
|
const start = i * block;
|
|
let max = 0;
|
|
for (let j = 0; j < block; j++) {
|
|
const value = Math.abs(data[start + j] ?? 0);
|
|
if (value > max) {
|
|
max = value;
|
|
}
|
|
}
|
|
peaks.push(max);
|
|
}
|
|
const norm = Math.max(...peaks, 0.0001);
|
|
return peaks.map((peak) => Math.max(MIN_BAR, peak / norm));
|
|
} finally {
|
|
await ctx.close();
|
|
}
|
|
}
|
|
|
|
export function flatWaveform(bars = BARS): number[] {
|
|
return Array.from({ length: bars }, () => 0.3);
|
|
}
|