Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 6x 3x 3x 1x 2x 2x 2x 2x 3x 3x 3x 5x 5x 10x 10x 10x 4x 4x 4x 4x 6x 5x 4x | import fs from "fs";
import path from "path";
export interface AudioFileData {
data: Uint8Array;
fileName: string;
duration?: number;
}
export class AudioUtils {
static async load(filePath: string): Promise<AudioFileData> {
let data: Uint8Array;
let fileName: string;
if (filePath.startsWith("http")) {
const response = await fetch(filePath);
if (!response.ok) {
throw new Error(`Failed to fetch remote audio file: ${response.statusText}`);
}
const arrayBuffer = await response.arrayBuffer();
data = new Uint8Array(arrayBuffer);
const urlPath = new URL(filePath).pathname;
fileName = path.basename(urlPath) || "audio.mp3";
} else {
const buffer = await fs.promises.readFile(filePath);
data = new Uint8Array(buffer);
fileName = path.basename(filePath);
}
const duration = this.estimateDuration(data, fileName);
return { data, fileName, duration };
}
static estimateDuration(data: Uint8Array, fileName: string): number | undefined {
try {
const ext = path.extname(fileName).toLowerCase();
if (ext === ".wav") {
// Simple WAV duration: (DataSize / ByteRate)
const view = new DataView(data.buffer, data.byteOffset, data.length);
const byteRate = view.getUint32(28, true);
const dataSize = view.getUint32(40, true);
if (byteRate > 0) return dataSize / byteRate;
} else if (ext === ".mp3") {
// Very rough MP3 estimate (assume 128kbps)
return data.length / (128000 / 8);
}
} catch {
// Ignore estimation errors
}
return undefined;
}
}
|