背景
在Electron项目中需要实现所有用户上传的音频转码为wav格式,为方便后续的操作。
方案
通过调研,目前市场上能很好地支持音频互相转码的工具只有ffmpeg,其他的大多是只支持部分固定格式的转化。由于是Electron项目,所以能够很方便地使用node的能力,那么控制台能做的事我也能通过node实现了。所以我不必费尽心思把ffmpeg集成到页面内,直接很粗暴地
通过child_process的exec调用ffmpeg.exe的能力,实现音频转码。
具体实现
直接上代码
/**
* 主进程接收需要转码的音频绝对路径
*/
ipcMain.on('transcode', (event, { inputPath, audioId }) => {
const audioDir = path.join(process.cwd(), 'download/audio')
const ffmpegPath = path.join(process.cwd(), 'ffmpeg/ffmpeg.exe')
const command = `${ffmpegPath} -i ${inputPath} -ac 1 -ar 16000 -y ${audioDir}/${audioId}.wav`
if (!fs.existsSync(audioDir)) {
fs.mkdirSync(audioDir, { recursive: true })
}
exec(command, error => {
if (error) {
log.error(`ffmpeg error: ${error}`)
}
})
})
拼接好的ffmpeg命令是
ffmpeg.exe -i my_audio.m4a -ac 1 -ar 16000 -y my_audio.wav
等同于直接在控制台执行如上命令:
执行完成:
其中-i 参数表示输入文件,-ac 1 表示输出的音频将是单声道的,-ar 参数用于设置音频采样率,即每秒采集声音信号的次数,这里设置为 16000 Hz,-y 这个选项告诉 FFmpeg 在覆盖现有文件时无需提示用户确认,my_audio.wav这是输出文件的名称和路径。
整个命令的意思是:使用 FFmpeg 将名为 my_audio.m4a 的 M4A 音频文件转换为单声道、16kHz 采样率的 WAV 格式,并且覆盖任何现有的同名输出文件。运行这个命令后,你会在相同的目录下得到一个名为 my_audio.wav 的文件,它已经是经过处理的音频文件了。
更多的参数及解释
| 参数 | 作用 |
|---|---|
-i <input> | 指定输入文件名(音频或视频)。 |
-acodec <codec> 或 -c:a <codec> | 设置音频编码器。例如:-acodec libmp3lame 表示使用 MP3 编码器。 |
-ab <bitrate> 或 -b:a <bitrate> | 设置音频比特率(kbps),控制音频质量与文件大小的关系。例如:-ab 128k 表示设置为 128 千比特每秒。 |
-ac <channels> 或 -c:a:0 channels=<num> | 设置音频通道数(单声道或立体声)。例如:-ac 2 表示输出为立体声,-ac 1 表示输出为单声道。 |
-ar <rate> 或 -c:sr <rate> | 设置音频采样率(Hz)。例如:-ar 44100 表示设置为 CD 质量的 44.1kHz。 |
-y | 直接覆盖输出文件,无需提示用户确认。 |
-vn | 只转换音频,忽略视频部分(如果输入文件包含视频)。 |
<output> | 输出文件名和路径。 |
总结
ffmpeg很强大,能做的远远不止于此。需要ffmpeg.exe可执行文件的评论区留言吧,有人需要我再打给包丢到云上。