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

Windows下调用ffmpeg时Process.WaitForExitAsync无限阻塞问题

问题分析与解决方案

问题根源

你的代码在WaitForExitAsync处无限阻塞,核心原因是重定向了ffmpeg的标准输出/错误流,但未主动读取这些流的内容。

命令行执行时,控制台会自动处理ffmpeg的输出缓冲区,因此进程能正常退出;但在C#中手动开启RedirectStandardOutput和RedirectStandardError后,如果不读取流内容,操作系统的输出缓冲区会被填满,导致ffmpeg进程无法继续执行,也无法触发退出信号,最终让WaitForExitAsync一直等待。

解决方法

1. 异步读取输出流,避免缓冲区阻塞

启动进程后,必须同时异步读取StandardOutput和StandardError的内容,不能仅依赖WaitForExitAsync。可以用Task.WhenAll并行处理两个流的读取:

var ffmpegProcess = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = _config.FfmpegExecutablePath,
        Arguments = CreateArgumentsForFfmpegProcessToRun(videoTempFilePath, thumbnailTempFilePath),
        RedirectStandardError = true,
        RedirectStandardOutput = true,
        // 无需给ffmpeg输入数据,关闭输入重定向
        RedirectStandardInput = false,
        UseShellExecute = false,
        CreateNoWindow = true
    },
    EnableRaisingEvents = true
};

ffmpegProcess.Start();

// 并行读取两个输出流,释放缓冲区
var readTasks = new[]
{
    ffmpegProcess.StandardOutput.ReadToEndAsync(),
    ffmpegProcess.StandardError.ReadToEndAsync()
};

await Task.WhenAll(readTasks);
await ffmpegProcess.WaitForExitAsync();

// 可选:读取输出内容用于日志排查
var outputLog = await readTasks[0];
var errorLog = await readTasks[1];

2. 优化ffmpeg命令消除警告

你命令行中出现的警告可以通过添加-update 1参数解决,该参数明确告诉ffmpeg输出单张图片而非序列,减少不必要的输出内容:

修改后的ffmpeg参数应为:

-i .\input.mp4 -ss 00:00:01.000 -vframes:v 1 -update 1 output.png

3. 关闭不必要的输入重定向

你的场景不需要向ffmpeg输入数据,因此将RedirectStandardInput设为false,减少资源占用,同时避免潜在的流阻塞风险。

补充说明

省略WaitForExitAsync时进程能生成文件,是因为短时间内输出缓冲区未被填满,进程能完成任务后退出,但这种方式不可靠——如果ffmpeg输出内容较多,依然会出现进程挂起的情况,必须通过主动读取流来彻底解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:15:47