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

使用child_process.exec调用ffmpeg时出现无限挂起问题如何解决

问题原因
  • 核心触发点是ffmpeg的默认交互逻辑:当输出路径的output.gif文件已存在时,ffmpeg会在标准错误流输出「是否覆盖文件」的确认提示,等待用户输入y/n确认。你使用的promisify封装后的exec没有配置标准输入的交互能力,也没有自动处理这个确认逻辑,同时ffmpeg的输出内容会占满exec的默认缓冲区,最终导致进程永久挂起。
  • 额外的触发场景:如果转换的mp4文件体积较大,ffmpeg输出的进度、编码日志总大小超过exec默认的100KB缓冲区上限,也会直接触发缓冲区溢出,导致子进程阻塞挂起。
修复方案

方案1:添加ffmpeg覆盖参数(推荐优先使用)

给ffmpeg命令加上-y参数,强制自动覆盖已存在的输出文件,不需要等待交互确认,修改后的代码如下:

const pathToFfmpeg = require('ffmpeg-static');
const { promisify } = require('util');
const exec = promisify(require('child_process').exec)

(async function() {
  console.log("Starting.");
  // 添加-y参数,强制覆盖输出文件
  let outputLogs = await exec(`${pathToFfmpeg} -y -i input.mp4 output.gif`);
  console.log("Finished:", outputLogs);
})();

如果不需要覆盖已有文件,可以把-y替换为-n,遇到同名文件时ffmpeg会直接退出,不会触发交互逻辑。

方案2:调整exec缓冲区配置

如果转换过程中日志量过大,需要同步调大exec的缓冲区上限,避免缓冲区溢出挂起:

let outputLogs = await exec(`${pathToFfmpeg} -y -i input.mp4 output.gif`, {
  maxBuffer: 10 * 1024 * 1024 // 将缓冲区上限调整为10MB,可按需修改
});

方案3:改用spawn调用(适合大文件转换场景)

spawn没有固定的缓冲区大小限制,支持实时流处理,更适合调用ffmpeg这类可能长时间运行、输出日志量大的子进程:

const pathToFfmpeg = require('ffmpeg-static');
const { spawn } = require('child_process');

(async function() {
  console.log("Starting.");
  const ffmpegProcess = spawn(pathToFfmpeg, ['-y', '-i', 'input.mp4', 'output.gif']);
  
  // 实时接收输出日志
  ffmpegProcess.stdout.on('data', data => console.log('输出日志:', data.toString()));
  ffmpegProcess.stderr.on('data', data => console.log('错误日志:', data.toString()));

  // 监听进程结束
  ffmpegProcess.on('close', code => {
    console.log(`转换完成,子进程退出码:${code}`);
  });
})();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:24:01