99 lines
2.4 KiB
TypeScript
99 lines
2.4 KiB
TypeScript
/**
|
|
* 音频处理工具
|
|
*
|
|
* 提供音频文件的解析和处理功能,包括元数据提取和封面图提取
|
|
*/
|
|
|
|
import { parseBuffer } from 'music-metadata'
|
|
|
|
/**
|
|
* 音频元数据
|
|
*/
|
|
export interface AudioMetadata {
|
|
duration: number // 时长(秒)
|
|
durationFormatted: string // 格式化时长 (mm:ss)
|
|
format: string // 音频格式
|
|
bitrate?: number // 比特率
|
|
sampleRate?: number // 采样率
|
|
channels?: number // 声道数
|
|
picture?: {
|
|
data: Buffer
|
|
format: string
|
|
description?: string
|
|
} // 封面图数据
|
|
}
|
|
|
|
/**
|
|
* 格式化时长为 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')}`
|
|
}
|
|
|
|
/**
|
|
* 解析音频文件获取元数据(包括封面图)
|
|
*
|
|
* @param buffer - 音频文件的 Buffer
|
|
* @param mimeType - 音频文件的 MIME 类型
|
|
* @returns 音频元数据(包含封面图数据)
|
|
*/
|
|
export async function parseAudioMetadata(
|
|
buffer: Buffer,
|
|
mimeType?: string
|
|
): Promise<AudioMetadata | null> {
|
|
try {
|
|
const metadata = await parseBuffer(buffer, { mimeType })
|
|
|
|
const duration = metadata.format.duration || 0
|
|
|
|
// 提取封面图(如果存在)
|
|
let picture = undefined
|
|
if (metadata.common.picture && metadata.common.picture.length > 0) {
|
|
const pic = metadata.common.picture[0]
|
|
picture = {
|
|
data: Buffer.from(pic.data), // 将 Uint8Array 转换为 Buffer
|
|
format: pic.format || 'image/jpeg',
|
|
description: pic.description,
|
|
}
|
|
}
|
|
|
|
return {
|
|
duration,
|
|
durationFormatted: formatDuration(duration),
|
|
format: metadata.format.container || 'unknown',
|
|
bitrate: metadata.format.bitrate,
|
|
sampleRate: metadata.format.sampleRate,
|
|
channels: metadata.format.numberOfChannels,
|
|
picture,
|
|
}
|
|
} catch (error) {
|
|
console.error('[AudioProcessor] Failed to parse audio metadata:', 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
|
|
]
|
|
|