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

C#启动FFmpeg进程时如何让工作目录/参数错误触发try/catch异常

问题根因

Process.Start() 仅在操作系统无法定位、拉起指定可执行文件(即你配置的ffmpeg.exe路径)时会立刻抛出原生异常。只要ffmpeg.exe可执行文件本身能被系统找到并启动,哪怕启动瞬间因非法参数、无效工作目录触发崩溃退出,Start() 方法都会正常执行返回,不会触发异常——这就是你现有try/catch逻辑只能捕获ffmpeg路径错误,抓不到工作目录、参数错误的核心原因。
另外你当前代码只重定向了标准输入流,没有重定向标准错误流,完全拿不到ffmpeg启动后输出的报错信息,自然没法判断启动是否真的成功。

修复步骤

1. 启动前增加手动参数校验

在调用进程启动逻辑前,先对关键配置做合法性校验,不符合要求直接抛出异常,即可被外层现有catch逻辑捕获:

  • ffmpeg路径:必须非空,且对应文件真实存在
  • 工作目录:如果配置了非空值,必须是真实存在的目录路径
  • 启动参数:不能为纯空白字符串(可根据业务需要增加更细的参数规则校验)

2. 启动后捕获进程早期错误

对于前置校验无法覆盖的错误(如参数指向的文件不存在、ffmpeg不识别的参数格式等),需要重定向ffmpeg的标准错误流,检测进程启动后的短时间内是否异常退出,若退出则读取错误信息抛出异常。

修改后的完整代码

FFmpeg_Capture类的Start方法调整如下:

public void Start()
{
    // 前置参数校验
    if (string.IsNullOrWhiteSpace(outputDirectory))
        throw new ArgumentNullException(nameof(outputDirectory), "ffmpeg.exe路径不能为空");
    if (!File.Exists(outputDirectory))
        throw new FileNotFoundException("指定的ffmpeg.exe路径不存在", outputDirectory);
    
    if (!string.IsNullOrWhiteSpace(workingDirectory) && !Directory.Exists(workingDirectory))
        throw new DirectoryNotFoundException($"指定的工作目录不存在: {workingDirectory}");
    
    if (string.IsNullOrWhiteSpace(arguments))
        throw new ArgumentException("启动参数不能为空", nameof(arguments));

    process = new Process();
    process.StartInfo.FileName = outputDirectory;
    process.StartInfo.WorkingDirectory = workingDirectory;
    process.StartInfo.Arguments = arguments;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardInput = true;
    // 重定向标准错误流,读取ffmpeg报错
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.CreateNoWindow = true;
    process.EnableRaisingEvents = false;
    
    // 异步采集错误输出,避免缓冲区满导致进程卡死
    string errorOutput = string.Empty;
    process.ErrorDataReceived += (sender, e) =>
    {
        if (!string.IsNullOrEmpty(e.Data))
            errorOutput += e.Data + Environment.NewLine;
    };

    process.Start();
    // 启动错误流异步读取
    process.BeginErrorReadLine();

    // 等待最多500毫秒,检测进程是否因参数/配置错误早期退出
    if (process.WaitForExit(500))
    {
        process.Dispose();
        throw new InvalidOperationException($"ffmpeg启动失败,错误信息: {errorOutput.Trim()}");
    }

    errorMessage = false;
    startRecord = true;
}

Form层的事件逻辑不需要大幅修改,现有catch块已经覆盖了异常捕获后的状态回滚、弹窗提示逻辑,Start()抛出的异常可以直接被现有逻辑捕获处理。

注:500毫秒的超时时间足够覆盖绝大多数参数错误、配置错误导致的ffmpeg即时退出场景,不会造成UI明显卡顿;正常启动的ffmpeg进程会在500毫秒超时后继续往下执行,不会被误判。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:30:10