80 lines
1.8 KiB
TypeScript
80 lines
1.8 KiB
TypeScript
|
|
/**
|
||
|
|
* Audio file decoding utilities
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { getAudioContext } from './context';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Decode an audio file to AudioBuffer
|
||
|
|
*/
|
||
|
|
export async function decodeAudioFile(file: File): Promise<AudioBuffer> {
|
||
|
|
const arrayBuffer = await file.arrayBuffer();
|
||
|
|
const audioContext = getAudioContext();
|
||
|
|
|
||
|
|
try {
|
||
|
|
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
||
|
|
return audioBuffer;
|
||
|
|
} catch (error) {
|
||
|
|
throw new Error(`Failed to decode audio file: ${error}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get audio file metadata without decoding the entire file
|
||
|
|
*/
|
||
|
|
export async function getAudioFileMetadata(file: File): Promise<{
|
||
|
|
name: string;
|
||
|
|
size: number;
|
||
|
|
type: string;
|
||
|
|
}> {
|
||
|
|
return {
|
||
|
|
name: file.name,
|
||
|
|
size: file.size,
|
||
|
|
type: file.type,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if a file is a supported audio format
|
||
|
|
*/
|
||
|
|
export function isSupportedAudioFormat(file: File): boolean {
|
||
|
|
const supportedFormats = [
|
||
|
|
'audio/wav',
|
||
|
|
'audio/wave',
|
||
|
|
'audio/x-wav',
|
||
|
|
'audio/mpeg',
|
||
|
|
'audio/mp3',
|
||
|
|
'audio/ogg',
|
||
|
|
'audio/webm',
|
||
|
|
'audio/flac',
|
||
|
|
'audio/aac',
|
||
|
|
'audio/m4a',
|
||
|
|
'audio/x-m4a',
|
||
|
|
];
|
||
|
|
|
||
|
|
return supportedFormats.includes(file.type) ||
|
||
|
|
/\.(wav|mp3|ogg|webm|flac|aac|m4a)$/i.test(file.name);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Format duration in seconds to MM:SS format
|
||
|
|
*/
|
||
|
|
export function formatDuration(seconds: number): string {
|
||
|
|
const mins = Math.floor(seconds / 60);
|
||
|
|
const secs = Math.floor(seconds % 60);
|
||
|
|
return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Format file size to human-readable format
|
||
|
|
*/
|
||
|
|
export function formatFileSize(bytes: number): string {
|
||
|
|
if (bytes === 0) return '0 B';
|
||
|
|
|
||
|
|
const k = 1024;
|
||
|
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
||
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||
|
|
|
||
|
|
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
||
|
|
}
|