You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();

关键修改说明

  1. 修复未定义变量:将FfmpegCommand(file)改为FfmpegCommand(inputStream),使用正确的输入流初始化FFmpeg命令
  2. 合并事件监听:将两个end事件合并为一个,避免逻辑重复
  3. 手动管理流结束:在FFmpeg的end事件中调用passThrough.end(),让axios知道数据流已完成;出错时调用passThrough.destroy(err),及时终止流并传递错误
  4. 分流处理(可选):如果需要保存转换后的文件,用.pipe(saveStream)将FFmpeg输出同时写入文件,再通过PassThrough流发送给后端
  5. 添加文件名:给FormData中的流指定filename,确保后端能正确识别文件类型
  6. 明确输入格式:添加.inputFormat('mp4'),避免FFmpeg自动识别输入格式时出错

内容的提问来源于stack exchange,提问作者Harikrushna Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 06:09:50