直接调用 FFmpeg 命令行是最可靠、最灵活的方式;C# 没有官方 FFmpeg 封装库,所谓“封装库”基本是命令行包装器或不维护的 P/Invoke 绑定,生产环境建议绕过它们,自己安全拼接并执行
ffmpeg进程。
为什么别碰 FFMpegCore
、Xabe.FFmpeg
这类“高级封装”
这些库本质只是帮你拼字符串 + 启动进程,但隐藏了错误码判断、流重定向、超时控制和 Windows/Linux/macOS 路径/编码差异。实际项目中常见问题包括:
Process.Start启动失败却没抛异常(比如路径含空格、ffmpeg 不在 PATH) stderr 输出被截断或乱码(尤其中文路径/日志),导致截图失败却查不到原因 转码中途崩溃,进程残留(
ffmpeg卡住不退出),后续调用被阻塞 不支持自定义
-vf复杂滤镜链,一加就报
Unrecognized option
安全调用 ffmpeg
的 4 个实操要点
用
System.Diagnostics.Process直接调用,但必须补足封装库默认忽略的关键控制点: 显式指定
ffmpeg完整路径(如
"C:\tools\ffmpeg.exe"),避免依赖系统 PATH 设置
StartInfo.UseShellExecute = false,否则无法重定向 stdout/stderr 给
Process.WaitForExit(60000)加超时,防止卡死;超时后调用
Process.Kill()读取
StandardError全量文本(用
ReadToEnd()而非逐行),再检查是否含
"Invalid data found when processing input"或
"No such file"等关键错误提示
截图与转码的最小可行命令模板
别追求“一行代码搞定”,先确保命令本身在终端能跑通,再移植到 C#:
截图(第 10 秒帧):
ffmpeg -ss 10 -i "input.mp4" -vframes 1 -q:v 2 "output.jpg"
转码为 H.264/AAC MP4:
ffmpeg -i "input.avi" -c:v libx264 -crf 23 -c:a aac -b:a 128k "output.mp4"
注意:
-ss放在
-i前是快进(快),放在后是解码后裁剪(准但慢);批量截图时务必用前者。
Windows 下中文路径和特殊字符的坑
即使设置了
StartInfo.StandardOutputEncoding = Encoding.UTF8,Windows 控制台默认仍是 GBK。最稳方案是: 输入路径全部用短路径(
GetShortPathNameAPI 或
cmd /c for %I in ("长路径") do @echo %~sI 预处理)
或改用 ffmpeg的
-f image2批量截图时,输出名用纯英文数字(如
thumb_%03d.jpg) 绝对不要在参数里拼接用户原始文件名——先校验、再重命名、再传入
真正麻烦的从来不是语法,而是 ffmpeg 进程的生命周期管理、错误上下文捕获和跨平台路径归一化。这些细节没兜住,任何“高级封装”都会在压测或用户上传异常文件时崩掉。
