根本原因是C#进程未找到ffmpeg.exe,需用绝对路径调用并校验文件存在;字幕推荐UTF-8无BOM的SRT格式,参数中显式指定-sub_charenc UTF-8,路径用双引号包裹,样式通过force_style控制。

FFmpeg 命令行调用失败:找不到 ffmpeg.exe 或报错“不是内部或外部命令”
根本原因是 C# 进程没找到 ffmpeg.exe,不是代码写错了,而是路径没配对。常见于直接写 "ffmpeg" 却没把 FFmpeg 加入系统 PATH,或用了相对路径但当前工作目录不对。
实操建议:
- 优先用绝对路径调用,比如
"C:\tools\ffmpeg\bin\ffmpeg.exe",避免依赖 PATH - 检查
ProcessStartInfo.WorkingDirectory是否设为 FFmpeg 所在目录(尤其当它依赖同目录下的ffprobe.exe或 DLL 时) - 别用
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)拼路径——用户可能装在 D 盘或自定义路径 - 启动前先用
File.Exists(@"C:path ofmpeg.exe")主动校验,比等报错更早发现问题
字幕文件格式选 SRT 还是 ASS?编码和路径怎么处理才不乱码
Windows 下最稳的是 UTF-8 编码的 .srt;.ass 虽功能强,但 C# 启动 FFmpeg 时若路径含中文、或字幕本身有 BOM/非 UTF-8 编码,极易触发乱码或解析失败。
实操建议:
- 字幕文件保存为无 BOM 的 UTF-8(VS Code 或 Notepad++ 可设),扩展名用
.srt - 路径传给 FFmpeg 前,用
Uri.EscapeDataString(filePath)不起作用——FFmpeg 不吃这个;正确做法是确保路径字符串本身不含空格或特殊符号,或用双引号包裹:"-i "C:\字幕\demo.srt"" - FFmpeg 参数里必须显式指定字幕编码:
-sub_charenc UTF-8,否则默认按系统 ANSI 解码,中文 Win10 就是 GBK,一读就崩 - 别用
File.WriteAllText直接写字符串进 .srt——它默认写 UTF-8 with BOM;改用File.WriteAllText(path, content, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false))
C# 启动 FFmpeg 添加字幕的最小可靠命令模板
不是所有参数组合都兼容,尤其硬件加速(如 -c:v h264_nvenc)和字幕叠加(-vf subtitles=...)一起用时容易冲突。纯 CPU 处理最可控。
实操建议(生成带内嵌字幕的 MP4):
- 基础命令结构:
ffmpeg.exe -i "input.mp4" -vf "subtitles="C:\sub.srt"" -c:a copy -c:v libx264 -crf 23 output.mp4 -
-vf subtitles=...路径里的反斜杠要双写,且整个值用英文双引号包住;Windows 下不能用正斜杠替代 - 音频用
-c:a copy快,但输入音频格式必须被目标容器支持(MP4 通常 OK);不放心就改用-c:a aac - 别加
-y到参数末尾——它必须紧挨ffmpeg.exe后,否则 FFmpeg 可能误判为输入文件名 - 用
Process.WaitForExit()前,务必先读StandardError流——很多错误(如字幕时间格式错)只打到 stderr,不读就卡死又没提示
字幕时间轴偏移、字体太小、位置不对怎么办
FFmpeg 默认用 libass 渲染字幕,但没指定样式时,会套用极简内置样式:小字号、居中、无阴影、黑底半透明——实际效果常被吐槽“看不清”。时间轴问题则多因 SRT 时间戳格式非法(如毫秒位不是三位、结束时间早于开始时间)。
实操建议:
- 用
-vf "subtitles=sub.srt:force_style='FontSize=24,PrimaryColour=&HFFFFFF&,BackColour=&H80000000&'"控制样式;颜色值是 BBGGRR 格式,&HFFFFFF&是白字,&H80000000&是半透黑底 - SRT 时间行必须是
00:00:01,000 --> 00:00:04,500格式(逗号分隔毫秒),不能用句点;可用正则预检:Regex.IsMatch(line, @"^d{2}:d{2}:d{2},d{3} --> d{2}:d{2}:d{2},d{3}$") - 整体时间偏移用
-itsoffset +2.5(提前 2.5 秒)或-itsoffset -1.0(延后 1 秒),但它作用于整个输入流,慎用;更准的做法是改 SRT 文件里每行的时间戳 - 如果视频本身有时间戳漂移(如手机录的 MOV),先用
ffprobe -v quiet -show_entries format=duration input.mp4校验时长是否合理,再决定要不要加-avoid_negative_ts make_zero
真正麻烦的不是命令怎么写,而是字幕文件那一行时间戳少了个零、路径里多了一个不可见的全角空格、或者 UTF-8 BOM 在你没注意的时候悄悄塞进了文件头。










