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:
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user