feat: add MP3 and FLAC export formats

Implemented Phase 11.1 export format support:
- Added MP3 export using lamejs library
- Added FLAC export using fflate DEFLATE compression
- Updated ExportDialog with format selector and format-specific options
  - MP3: bitrate selector (128/192/256/320 kbps)
  - FLAC: compression quality slider (0-9)
  - WAV: bit depth selector (16/24/32-bit)
- Updated AudioEditor to route export based on selected format
- Created TypeScript declarations for lamejs
- Fixed AudioStatistics to use audioBuffer instead of buffer property

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-19 02:14:32 +01:00
parent 1c56e596b5
commit 6577d9f27b
7 changed files with 265 additions and 44 deletions

View File

@@ -34,7 +34,7 @@ import {
} from '@/lib/history/commands/multi-track-edit-command';
import { extractBufferSegment } from '@/lib/audio/buffer-utils';
import { mixTracks, getMaxTrackDuration } from '@/lib/audio/track-utils';
import { audioBufferToWav, downloadArrayBuffer } from '@/lib/audio/export';
import { audioBufferToWav, audioBufferToMp3, audioBufferToFlac, downloadArrayBuffer } from '@/lib/audio/export';
export function AudioEditor() {
const [importDialogOpen, setImportDialogOpen] = React.useState(false);
@@ -737,16 +737,42 @@ export function AudioEditor() {
// Mix all tracks into a single buffer
const mixedBuffer = mixTracks(tracks, sampleRate, maxDuration);
// Convert to WAV
const wavBuffer = audioBufferToWav(mixedBuffer, {
format: settings.format,
bitDepth: settings.bitDepth,
normalize: settings.normalize,
});
// Convert based on format
let exportedBuffer: ArrayBuffer;
let mimeType: string;
let fileExtension: string;
if (settings.format === 'mp3') {
exportedBuffer = await audioBufferToMp3(mixedBuffer, {
format: 'mp3',
bitrate: settings.bitrate,
normalize: settings.normalize,
});
mimeType = 'audio/mpeg';
fileExtension = 'mp3';
} else if (settings.format === 'flac') {
exportedBuffer = await audioBufferToFlac(mixedBuffer, {
format: 'flac',
bitDepth: settings.bitDepth,
quality: settings.quality,
normalize: settings.normalize,
});
mimeType = 'application/octet-stream'; // FLAC MIME type
fileExtension = 'flac';
} else {
// WAV (default)
exportedBuffer = audioBufferToWav(mixedBuffer, {
format: 'wav',
bitDepth: settings.bitDepth,
normalize: settings.normalize,
});
mimeType = 'audio/wav';
fileExtension = 'wav';
}
// Download
const filename = `${settings.filename}.wav`;
downloadArrayBuffer(wavBuffer, filename);
const filename = `${settings.filename}.${fileExtension}`;
downloadArrayBuffer(exportedBuffer, filename, mimeType);
addToast({
title: 'Export Complete',