/** * 音频处理工具 * * 提供音频文件的解析和处理功能 * * @module audio-processor * @created 2025-12-14 */ import { parseBuffer, parseFile } from 'music-metadata' import type { IAudioMetadata } from 'music-metadata' /** * 音频元数据 */ export interface AudioMetadata { duration: number // 时长(秒) durationFormatted: string // 格式化时长 (mm:ss) format: string // 音频格式 bitrate?: number // 比特率 sampleRate?: number // 采样率 channels?: number // 声道数 } /** * 格式化时长为 mm:ss 格式 */ 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')}` } function toAudioMetadata(metadata: IAudioMetadata): AudioMetadata { const duration = metadata.format.duration || 0 return { duration, durationFormatted: formatDuration(duration), format: metadata.format.container || 'unknown', bitrate: metadata.format.bitrate, sampleRate: metadata.format.sampleRate, channels: metadata.format.numberOfChannels, } } /** * 解析音频文件获取元数据 * * @param buffer - 音频文件的 Buffer * @param mimeType - 音频文件的 MIME 类型 * @returns 音频元数据 */ export async function parseAudioMetadata( buffer: Buffer, mimeType?: string ): Promise { try { const metadata = await parseBuffer(buffer, { mimeType }) return toAudioMetadata(metadata) } catch (error) { console.error('[AudioProcessor] Failed to parse audio metadata:', error) return null } } /** * 从本地临时文件解析音频元数据,避免大音频整文件进入内存 */ export async function parseAudioMetadataFromFile( filePath: string ): Promise { try { const metadata = await parseFile(filePath) return toAudioMetadata(metadata) } catch (error) { console.error('[AudioProcessor] Failed to parse audio metadata from file:', error) return null } } /** * 检查文件是否为音频文件 */ export function isAudioFile(mimeType: string): boolean { return mimeType.startsWith('audio/') } /** * 支持的音频格式 */ export const SUPPORTED_AUDIO_FORMATS = [ 'audio/mpeg', // MP3 'audio/wav', // WAV 'audio/x-wav', 'audio/flac', // FLAC 'audio/aac', // AAC 'audio/mp4', // M4A 'audio/x-m4a', 'audio/ogg', // OGG 'audio/webm', // WebM ]