Node.js中使用Axios通过PassThrough流发送FFmpeg处理流报错求助
解决Node.js中axios结合PassThrough流发送FFmpeg转换文件的问题
原代码存在的关键问题
- 未定义变量
file:初始化FFmpeg命令时用了未声明的file,应该使用前面创建的可读流stream - 重复绑定
end事件:同一个FFmpeg实例绑定了两次end回调,造成逻辑冗余 - PassThrough流未正确结束:设置了
{ end: false }但没手动关闭流,导致axios一直等待数据流完成 - 冗余变量:
writeStream和outputFile仅定义未使用,若需要保存转换后的文件,需做分流处理
修正后的完整代码
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path; const FfmpegCommand = require('fluent-ffmpeg'); const fs = require('fs'); const path = require('path'); const streamNode = require('stream'); const FormData = require('form-data'); const axios = require('axios').default; async function audios() { // 读取源视频文件 const inputStream = fs.createReadStream(path.join(__dirname, '../videos/video.mp4')); // 创建PassThrough流,用于中转FFmpeg输出 const passThrough = new streamNode.PassThrough(); // 若需要保存转换后的文件,创建写入流并和PassThrough分流 const outputFilePath = path.join(__dirname, '../response/audios/' + Date.now() + '.wav'); const saveStream = fs.createWriteStream(outputFilePath); try { // 初始化FFmpeg命令,使用正确的输入流 const ffmpeg = new FfmpegCommand(inputStream); ffmpeg .setFfmpegPath(ffmpegPath) .inputFormat('mp4') // 明确指定输入格式,避免自动识别出错 .toFormat('wav') .on('end', () => { console.log('文件转换完成,准备结束流'); // FFmpeg处理完成后,手动结束PassThrough流,告知axios数据发送完毕 passThrough.end(); }) .on('error', (err, stdout, stderr) => { console.error('转换出错:', err.message); console.log('FFmpeg标准输出:', stdout); console.log('FFmpeg错误输出:', stderr); // 出错时也要关闭流,避免axios挂起 passThrough.destroy(err); }) // 将FFmpeg输出同时分流到PassThrough和保存流(如果需要保存文件) .pipe(saveStream) .pipe(passThrough, { end: false }); // 设置end: false,避免FFmpeg结束时直接关闭PassThrough // 构建FormData并添加流 const bodyFormData = new FormData(); // 给流添加文件名,方便后端识别 bodyFormData.append('file', passThrough, { filename: 'converted_audio.wav' }); // 发送请求 const response = await axios.post('http://localhost:4080/video', bodyFormData, { maxContentLength: Infinity, maxBodyLength: Infinity, validateStatus: () => true, headers: { ...bodyFormData.getHeaders() } }); console.log('接口返回:', response.data); } catch (error) { console.error('请求出错:', error.message); } } // 调用函数 audios();
关键修改说明
- 修复未定义变量:将
FfmpegCommand(file)改为FfmpegCommand(inputStream),使用正确的输入流初始化FFmpeg命令 - 合并事件监听:将两个
end事件合并为一个,避免逻辑重复 - 手动管理流结束:在FFmpeg的
end事件中调用passThrough.end(),让axios知道数据流已完成;出错时调用passThrough.destroy(err),及时终止流并传递错误 - 分流处理(可选):如果需要保存转换后的文件,用
.pipe(saveStream)将FFmpeg输出同时写入文件,再通过PassThrough流发送给后端 - 添加文件名:给FormData中的流指定
filename,确保后端能正确识别文件类型 - 明确输入格式:添加
.inputFormat('mp4'),避免FFmpeg自动识别输入格式时出错
内容的提问来源于stack exchange,提问作者Harikrushna Patel
相关产品推荐
相关产品推荐

