- use of InitialValuesType
- cleaning up added after conversion
This commit is contained in:
Chesterkxng 2025-12-10 16:47:51 +01:00
parent cfc0ba3b41
commit 09456bf6ed

View File

@ -1,6 +1,12 @@
import { FFmpeg } from '@ffmpeg/ffmpeg'; import { FFmpeg } from '@ffmpeg/ffmpeg';
import { fetchFile } from '@ffmpeg/util'; import { fetchFile } from '@ffmpeg/util';
import { InitialValuesType, AUDIO_FORMATS } from './types';
import { getFileExtension } from 'utils/file';
/**
* optimzed call for FFmpeg instance creation,
* avoiding to download required FFmpeg binaries on every reload
*/
const ffmpeg = new FFmpeg(); const ffmpeg = new FFmpeg();
let isLoaded = false; let isLoaded = false;
@ -21,80 +27,50 @@ async function loadFFmpeg() {
*/ */
export async function convertAudio( export async function convertAudio(
input: File, input: File,
outputFormat: 'mp3' | 'aac' | 'wav' options: InitialValuesType
): Promise<File> { ): Promise<File> {
await loadFFmpeg(); await loadFFmpeg();
// Use the original input extension for input filename // Use the original input extension for input filename
const inputExtMatch = input.name.match(/\.[^.]+$/); const inputExt = getFileExtension(input.name);
const inputExt = inputExtMatch ? inputExtMatch[0] : '.audio';
const inputFileName = `input${inputExt}`; if (inputExt === options.outputFormat) return input;
const outputFileName = `output.${outputFormat}`;
const inputFileName = inputExt ? `input.${inputExt}` : 'input';
const outputFileName = `output.${options.outputFormat}`;
// Write the input file to FFmpeg FS // Write the input file to FFmpeg FS
await ffmpeg.writeFile(inputFileName, await fetchFile(input)); await ffmpeg.writeFile(inputFileName, await fetchFile(input));
// Build the FFmpeg args depending on the output format // Build the FFmpeg args depending on the output format
// You can customize the codec and bitrate options per format here // You can customize the codec and bitrate options per format here
let args: string[];
switch (outputFormat) { const format = AUDIO_FORMATS[options.outputFormat];
case 'mp3': const { codec, bitrate, mimeType } = format;
args = [
'-i',
inputFileName,
'-c:a',
'libmp3lame',
'-b:a',
'192k',
outputFileName
];
break;
case 'aac': const args = bitrate
args = [ ? ['-i', inputFileName, '-c:a', codec, '-b:a', bitrate, outputFileName]
'-i', : ['-i', inputFileName, '-c:a', codec, outputFileName];
inputFileName,
'-c:a',
'aac',
'-b:a',
'192k',
outputFileName
];
break;
case 'wav':
args = ['-i', inputFileName, '-c:a', 'pcm_s16le', outputFileName];
break;
default:
throw new Error(`Unsupported output format: ${outputFormat}`);
}
// Execute ffmpeg with arguments // Execute ffmpeg with arguments
try {
await ffmpeg.exec(args); await ffmpeg.exec(args);
// Read the output file from FFmpeg FS // Read the output file from FFmpeg FS
const data = await ffmpeg.readFile(outputFileName); const data = await ffmpeg.readFile(outputFileName);
// Determine MIME type by outputFormat
let mimeType = '';
switch (outputFormat) {
case 'mp3':
mimeType = 'audio/mpeg';
break;
case 'aac':
mimeType = 'audio/aac';
break;
case 'wav':
mimeType = 'audio/wav';
break;
}
// Create a new File with the original name but new extension // Create a new File with the original name but new extension
const baseName = input.name.replace(/\.[^.]+$/, ''); const baseName = input.name.replace(/\.[^.]+$/, '');
const convertedFileName = `${baseName}.${outputFormat}`; const convertedFileName = `${baseName}.${options.outputFormat}`;
return new File([data], convertedFileName, { type: mimeType }); return new File([data], convertedFileName, { type: mimeType });
} finally {
// Clean up FFmpeg virtual filesystem
try {
await ffmpeg.deleteFile(inputFileName);
await ffmpeg.deleteFile(outputFileName);
} catch (e) {
// Ignore cleanup errors
}
}
} }