mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-12-17 09:46:02 +00:00
feat: add AAC to MP3 audio converter tool
This commit is contained in:
parent
fc18dc0dc0
commit
8fc9081487
@ -57,5 +57,11 @@
|
||||
"title": "What is {{title}}?"
|
||||
},
|
||||
"trimmingAudio": "Trimming Audio"
|
||||
},
|
||||
"AACMP3": {
|
||||
"title": "AAC to MP3",
|
||||
"description": "convert AAC audio files to MP3 format.Which is a common audio format used for music and other audio files.",
|
||||
"shortDescription": "convert AAC audio files to MP3 format.",
|
||||
"longDescription": "convert AAC audio files to MP3 format. MP3 is a widely used audio format that provides good sound quality and is compatible with most devices and platforms. This tool allows you to convert your AAC files to MP3 easily, making it convenient for playback on various devices."
|
||||
}
|
||||
}
|
||||
|
||||
44
src/pages/tools/audio/AAC-MP3/AAC-MP3.service.test.ts
Normal file
44
src/pages/tools/audio/AAC-MP3/AAC-MP3.service.test.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
|
||||
// Mock FFmpeg and fetchFile
|
||||
vi.mock('@ffmpeg/ffmpeg', () => ({
|
||||
FFmpeg: vi.fn().mockImplementation(() => ({
|
||||
load: vi.fn().mockResolvedValue(undefined),
|
||||
writeFile: vi.fn().mockResolvedValue(undefined),
|
||||
exec: vi.fn().mockResolvedValue(undefined),
|
||||
readFile: vi.fn().mockReturnValue(new Uint8Array([1, 2, 3, 4, 5])),
|
||||
unlink: vi.fn().mockResolvedValue(undefined)
|
||||
}))
|
||||
}));
|
||||
|
||||
vi.mock('@ffmpeg/util', () => ({
|
||||
fetchFile: vi.fn().mockResolvedValue(new Uint8Array([1, 2, 3, 4, 5]))
|
||||
}));
|
||||
|
||||
// Import service
|
||||
import { AACtoMp3 } from './service';
|
||||
|
||||
describe('convertAACtoMP3', () => {
|
||||
it('should return a new MP3 File when given a valid AAC file', async () => {
|
||||
const mockAACData = new Uint8Array([0, 1, 2, 3, 4, 5]);
|
||||
const mockFile = new File([mockAACData], 'sample.aac', {
|
||||
type: 'audio/aac'
|
||||
});
|
||||
|
||||
const result = await AACtoMp3(mockFile);
|
||||
|
||||
expect(result).toBeInstanceOf(File);
|
||||
expect(result.name).toBe('sample.mp3');
|
||||
expect(result.type).toBe('audio/mpeg');
|
||||
});
|
||||
|
||||
it('should throw error if file type is not AAC', async () => {
|
||||
const mockFile = new File(['dummy'], 'song.wav', {
|
||||
type: 'audio/wav'
|
||||
});
|
||||
|
||||
await expect(() => AACtoMp3(mockFile)).rejects.toThrowError(
|
||||
'Only .aac files are allowed.' // FIXED to match actual error
|
||||
);
|
||||
});
|
||||
});
|
||||
59
src/pages/tools/audio/AAC-MP3/index.tsx
Normal file
59
src/pages/tools/audio/AAC-MP3/index.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import React, { useState } from 'react';
|
||||
import ToolContent from '@components/ToolContent';
|
||||
import { ToolComponentProps } from '@tools/defineTool';
|
||||
import ToolAudioInput from '@components/input/ToolAudioInput';
|
||||
import ToolFileResult from '@components/result/ToolFileResult';
|
||||
|
||||
import { AACtoMp3 } from './service';
|
||||
|
||||
export default function AACMP3({ title, longDescription }: ToolComponentProps) {
|
||||
const [input, setInput] = useState<File | null>(null);
|
||||
const [result, setResult] = useState<File | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const compute = async (
|
||||
_optionsValues: {},
|
||||
input: File | null
|
||||
): Promise<void> => {
|
||||
if (!input) return;
|
||||
|
||||
try {
|
||||
if (!input.name.toLowerCase().endsWith('.aac')) {
|
||||
setInput(null);
|
||||
alert('please upload .aac files are allowed.');
|
||||
setResult(null);
|
||||
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
const resultFile = await AACtoMp3(input);
|
||||
setResult(resultFile);
|
||||
} catch (error) {
|
||||
console.error('Conversion failed:', error);
|
||||
setResult(null);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<ToolContent
|
||||
title={title}
|
||||
input={input}
|
||||
inputComponent={
|
||||
<ToolAudioInput
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
title={'Upload Your AAC File'}
|
||||
/>
|
||||
}
|
||||
resultComponent={
|
||||
<ToolFileResult value={result} title={'Mp3 Output'} loading={loading} />
|
||||
}
|
||||
initialValues={{}}
|
||||
getGroups={null}
|
||||
setInput={setInput}
|
||||
compute={compute}
|
||||
toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/audio/AAC-MP3/meta.ts
Normal file
15
src/pages/tools/audio/AAC-MP3/meta.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('audio', {
|
||||
i18n: {
|
||||
name: 'audio:AACMP3.title',
|
||||
description: 'audio:AACMP3.description',
|
||||
shortDescription: 'audio:AACMP3.shortDescription',
|
||||
longDescription: 'audio:AACMP3.longDescription'
|
||||
},
|
||||
path: 'AAC-MP3',
|
||||
icon: 'bi:filetype-mp3',
|
||||
keywords: ['AAC', 'MP3', 'convert', 'audio', 'file conversion'],
|
||||
component: lazy(() => import('./index'))
|
||||
});
|
||||
35
src/pages/tools/audio/AAC-MP3/service.ts
Normal file
35
src/pages/tools/audio/AAC-MP3/service.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { FFmpeg } from '@ffmpeg/ffmpeg';
|
||||
import { fetchFile } from '@ffmpeg/util';
|
||||
|
||||
const ffmpeg = new FFmpeg();
|
||||
let isLoaded = false;
|
||||
|
||||
export async function AACtoMp3(input: File): Promise<File> {
|
||||
if (!isLoaded) {
|
||||
await ffmpeg.load();
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
const inName = 'input.aac';
|
||||
const outName = 'output.mp3';
|
||||
|
||||
await ffmpeg.writeFile(inName, await fetchFile(input));
|
||||
|
||||
await ffmpeg.exec([
|
||||
'-i',
|
||||
inName,
|
||||
'-c:a',
|
||||
'libmp3lame',
|
||||
'-b:a',
|
||||
'192k',
|
||||
outName
|
||||
]);
|
||||
|
||||
const data = await ffmpeg.readFile(outName);
|
||||
|
||||
const mp3 = new File([data], input.name.replace(/\.aac$/i, '.mp3'), {
|
||||
type: 'audio/mpeg'
|
||||
});
|
||||
|
||||
return mp3;
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
import { tool as audioAACMP3 } from './AAC-MP3/meta';
|
||||
import { tool as audioMergeAudio } from './merge-audio/meta';
|
||||
import { tool as audioTrim } from './trim/meta';
|
||||
import { tool as audioChangeSpeed } from './change-speed/meta';
|
||||
@ -7,5 +8,6 @@ export const audioTools = [
|
||||
audioExtractAudio,
|
||||
audioChangeSpeed,
|
||||
audioTrim,
|
||||
audioMergeAudio
|
||||
audioMergeAudio,
|
||||
audioAACMP3
|
||||
];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user