基于Node实现音频格式转换并保存
基于Node实现音频格式转换并保存
前言:
事情的起因是在工作时,需要实现一个功能,在前端上录制音频转发给Unity,中间的渠道通过服务器,本来是很简单的一个事,但Unity需要使用wav格式,而录制音频受游览器限制不支持录制wav格式,只支持默认的webm格式,麻烦点就在这了,需要手动抓换一下格式,在前端尝试一番无果后,就去找服务器一顿拉扯,服务器是GO开发的,是一个游戏服务框架,一番拉扯后他仍然坚持只做转发不做处理,没办法了,还能怎么搞只能自己动手上了。
插件预装:
npm i @ffmpeg-installer/ffmpeg express fluent-ffmpeg multer -D- @ffmpeg-installer/ffmpeg 提供了FFmpeg的安装工具,自动下载并安装适配的FFmpeg
- fluent-ffmpeg 基于FFmpeg封装的库,提供了更简洁的APi,用于视频转码、合并、裁剪、提取、音频转换、处理等
- multer 用于处理表单类型数据的中间件,通常用来处理文件上传
- express 轻量级的Web框架,用于创建web服务器处理HTTP请求和响应
项目结构:
--- web-aduio
--- audio 存储音频文件
--- app.js 业务代码
实现代码:
const express = require('express');
const multer = require('multer');
const fluentFFmpeg = require('fluent-ffmpeg');
const fs = require('fs');
const path = require('path');
const { Readable } = require('stream');
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
// 设置 ffmpeg 路径
fluentFFmpeg.setFfmpegPath(ffmpegPath);
const app = express();
// 建立一个静态资源,用于外部访问音频文件
app.use('/audio', express.static(path.join(__dirname, 'audio')));
// 处理上传文件
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
app.post('/upload-audio', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
const audioBuffer = req.file.buffer;
// 设置音频文件名和存储路径
const fileName = `${new Date().getTime()}.wav`
const audioPath = path.join(__dirname, `/audio/${fileName}`);
// 音频转换
fluentFFmpeg()
.input(Readable.from(audioBuffer))
.inputFormat('webm') // 输入格式
.audioCodec('pcm_s16le')
.format('wav') // 输出格式
.on('end', () => {
// 转换成功,响应客户端
res.json({ state: 0, audioUrl: `http://127.0.0.1:5000/audio/${fileName}` });
})
.on('error', (err) => {
res.status(500).json({state: -1, error: 'Error during conversion', message: err.message });
})
.pipe(fs.createWriteStream(audioPath));
});
app.listen(5000, '0.0.0.0', () => {
console.log(`Server running on port 5000`);
});