clapper / src /lib /ffmpeg /convertAudioToMp3.ts
jbilcke-hf's picture
jbilcke-hf HF staff
add linter and prettifier
c1f12bf
raw
history blame
No virus
1.65 kB
import ffmpeg from 'fluent-ffmpeg'
import * as fs from 'fs'
import * as path from 'path'
import * as crypto from 'crypto'
// Define a map from media type to file extension
const EXTENSIONS: { [type: string]: string } = {
'audio/x-wav': 'wav',
'audio/wav': 'wav',
'audio/mp3': 'mp3',
'audio/mpeg': 'mp3',
'audio/webm': 'webm',
// add more if needed
}
export async function convertAudioToMp3(dataUri: string): Promise<string> {
const match = dataUri.match(/^data:(.*?);base64,(.*)$/)
if (!match) throw new Error('Invalid data URI')
const mediaType = match[1]
const base64Audio = match[2]
const format = EXTENSIONS[mediaType]
if (!format) throw new Error('Unsupported media type: ' + mediaType)
if (format === 'mp3') return dataUri // If it's already a mp3, then do nothing
const randomName = crypto.randomBytes(15).toString('hex')
const inputPath = path.join(__dirname, `${randomName}.${format}`)
const outputPath = path.join(__dirname, `${randomName}.mp3`)
// Decode base64 and write to an audio file
const audioBuffer = Buffer.from(base64Audio, 'base64')
await fs.promises.writeFile(inputPath, audioBuffer)
return new Promise<string>((resolve, reject) => {
ffmpeg(inputPath)
.output(outputPath)
.on('end', async () => {
const mp3File = await fs.promises.readFile(outputPath)
await fs.promises.unlink(inputPath)
await fs.promises.unlink(outputPath)
resolve('data:audio/mp3;base64,' + mp3File.toString('base64'))
})
.on('error', async (err) => {
await fs.promises.unlink(inputPath)
reject(err)
})
.run()
})
}