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

Node.js调用FFmpeg子进程报Error: Write EOF的原因及修复

问题原因
  • 处理大视频时,FFmpeg仅需读取视频开头少量数据就能生成缩略图,会提前关闭stdin管道。但你的代码中Readable流仍在持续向已关闭的stdin写入数据,触发write EOF错误。
  • 代码未监听ffmpeg.stdin和ffmpeg进程的error事件,导致错误未被捕获,最终引发程序崩溃。
修复方案

1. 捕获未处理的错误事件

给ffmpeg.stdin和ffmpeg进程添加错误监听,避免未捕获错误导致程序崩溃:

// 监听stdin写入错误
ffmpeg.stdin.on('error', (err) => {
  callback(err);
});

// 监听FFmpeg进程错误
ffmpeg.on('error', (err) => {
  callback(err);
});

2. 停止向已关闭的管道写入数据

当FFmpeg进程退出时,销毁可读流,防止继续向已关闭的stdin写入:

ffmpeg.on('exit', () => {
  readable.destroy(); // 终止可读流,停止写入操作
});

3. 优化为Promise风格(推荐)

原代码标记了async但未利用Promise特性,改成Promise风格更易维护和调用:

const { Readable } = require('stream');
const child_process = require('node:child_process');

function generate_thumbnail(videoFile) {
  return new Promise((resolve, reject) => {
    const readable = new Readable();
    readable._read = () => {};
    readable.push(videoFile.data);
    readable.push(null);

    const ffmpeg = child_process.spawn('C:\\FFmpeg\\bin\\ffmpeg', [
      '-i', 'pipe:0',
      '-vframes', '1',
      '-vf', 'scale=iw*.5:ih*0.5',
      '-f', 'mjpeg',
      'pipe:1'
    ], { stdio: ['pipe', 'pipe', 'ignore'] });

    // 处理各类错误
    ffmpeg.stdin.on('error', (err) => {
      reject(err);
      readable.destroy();
    });

    ffmpeg.on('error', (err) => {
      reject(err);
      readable.destroy();
    });

    ffmpeg.on('exit', (code) => {
      if (code !== 0) {
        reject(new Error(`FFmpeg执行失败,退出码:${code}`));
      }
      readable.destroy();
    });

    const buffer = [];
    ffmpeg.stdout.on('data', (data) => {
      buffer.push(data);
    });

    ffmpeg.stdout.on('end', () => {
      const buf = Buffer.concat(buffer);
      resolve(buf);
    });

    readable.pipe(ffmpeg.stdin);
  });
}

module.exports = { generate_thumbnail };

额外优化

添加-ss参数让FFmpeg快速定位到目标帧,减少读取的数据量,提升处理效率:

const ffmpeg = child_process.spawn('C:\\FFmpeg\\bin\\ffmpeg', [
  '-ss', '00:00:01', // 从视频第1秒处取帧
  '-i', 'pipe:0',
  '-vframes', '1',
  '-vf', 'scale=iw*.5:ih*0.5',
  '-f', 'mjpeg',
  'pipe:1'
], { stdio: ['pipe', 'pipe', 'ignore'] });

内容的提问来源于stack exchange,提问作者Prithivin Lakshminarayanan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:20:28