C#调用FFmpeg需启动ffmpeg.exe进程而非直接引用类库,须确保可执行文件存在、正确重定向标准流、安全拼接参数、解析stderr获取进度,并在服务环境中验证静默运行。

FFmpeg 在 C# 中不是直接调用的类库,而是外部命令行程序
FFmpeg 本身没有官方 C# 绑定,C# 调用它本质是启动 ffmpeg.exe 进程并传参。这意味着你必须确保目标机器上已安装 FFmpeg(或把 ffmpeg.exe 和依赖 DLL 放进项目输出目录),且路径可被正确访问。
常见错误现象:System.ComponentModel.Win32Exception: 系统找不到指定的文件 —— 通常是因为没配环境变量、路径写错,或没把 ffmpeg.exe 放到 bin/Debug 下。
- 推荐做法:把
ffmpeg.exe(含ffprobe.exe)复制进项目根目录,设属性“始终复制”到输出目录 - 调用时用相对路径:
Process.Start("ffmpeg.exe", "-i input.mp4 -vf scale=640:360 out.mp4") - 不要依赖全局
PATH,尤其部署到服务器时容易失效
用 Process.Start 启动 ffmpeg 要注意标准输出和错误流阻塞
FFmpeg 日志量大,如果不对 StandardOutput 和 StandardError 做异步读取或重定向,进程可能卡死(尤其是 Windows 上)——表面看程序没报错,但实际 ffmpeg 没执行完就挂起了。
实操建议:
- 务必设置
StartInfo.RedirectStandardOutput = true和RedirectStandardError = true - 用
BeginOutputReadLine()+OutputDataReceived事件监听日志,避免同步读取阻塞 - 加上
WaitForExit(60000)并检查HasExited,防止无限等待 - 示例关键片段:
var psi = new ProcessStartInfo("ffmpeg.exe", args) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; var p = Process.Start(psi); p.OutputDataReceived += (s, e) => Console.WriteLine($"[OUT] {e.Data}"); p.ErrorDataReceived += (s, e) => Console.WriteLine($"[ERR] {e.Data}"); p.BeginOutputReadLine(); p.BeginErrorReadLine(); p.WaitForExit(60000);
参数拼接容易出错:空格、路径含中文、特殊字符要转义
FFmpeg 命令对参数格式敏感,C# 字符串拼接时若不处理好,会导致解析失败(比如提示 Invalid argument 或跳过某些 filter)。
- 输入/输出路径含空格或中文?必须用双引号包裹:
"-i "C:\视频\测试.mp4"" - 滤镜参数含等号或冒号(如
scale=1280:720),整体应作为单个参数传入,不要拆开 - 推荐用
string.Join(" ", args)拼接,而不是手写空格连接;更稳妥可用第三方库如 FFMpegCore 封装参数逻辑 - 调试技巧:先把生成的完整命令复制到 CMD 手动运行,确认是否有效
需要进度回调或取消操作?得靠解析 stderr 输出的 time= 和 frame= 行
FFmpeg 不提供原生 API 回调,进度只能从 StandardError 实时文本中提取。它的日志默认每秒刷一次 frame=xxx fps=xx q=xx size=xxxkB time=00:00:xx.xx bitrate=xxxkbits/s 这类行。
- 正则匹配
time=(d+:d+:d+.d+)或frame=(d+)是最常用方式 - 注意:FFmpeg 默认日志级别较高,加
-v quiet -stats可减少干扰信息,但-stats仍会输出进度条文本 - 取消任务不能只杀 UI 线程,必须调用
p.Kill(),否则 ffmpeg 子进程继续占用 CPU 和磁盘 - 别依赖
Duration元数据做百分比计算——有些封装格式不带准确时长,ffprobe查到的也可能是估算值
FFmpeg 的 C# 集成难点不在语法,而在进程生命周期管理、I/O 流控制和参数健壮性。真正上线前,至少要在无 GUI 的服务环境(如 Windows Server 无桌面会话)里验证一遍能否静默跑通。










