使用FFmpeg在C#中重封装视频文件遇到问题求助
问题分析与修复方案
代码中的核心问题
变量
i作用域错误
你把i定义在foreach循环外部,处理多个文件时i会持续累加。比如第一个文件在目录A生成了2.mp4,第二个文件在目录B时,会直接从3开始查找可用文件名,逻辑不符合预期。应该把i的初始化放到foreach内部,每个文件单独从0开始计数。FFmpeg路径可能未正确指定
代码中直接写"ffmpeg.exe",如果FFmpeg不在当前程序的工作目录或系统环境变量PATH中,系统会找不到可执行文件,导致进程静默失败,但WaitForExit()依然会执行完成,触发MessageBox。必须指定FFmpeg的完整路径,比如@"C:\Program Files\ffmpeg\bin\ffmpeg.exe"。未检查FFmpeg执行状态与错误日志
进程退出不代表执行成功,FFmpeg执行失败时会返回非0的退出码,但你没有检查process.ExitCode,也没有捕获FFmpeg的错误输出,根本不知道失败原因(比如输入文件格式不支持、权限不足等)。目录处理冗余
Path.GetDirectoryName(file)是输入文件的目录,既然输入文件存在,这个目录必然存在,Directory.CreateDirectory(outputDirectory)属于冗余操作,但如果后续要改输出到其他目录,这步需要保留。
修正后的完整代码
using System.IO; using System.Diagnostics; using System.Windows.Forms; private void RemuxVideos(string[] files) { // 替换为你的FFmpeg完整路径 string ffmpegPath = @"C:\Program Files\ffmpeg\bin\ffmpeg.exe"; foreach (string file in files) { // 每个文件单独从0开始计数,避免跨目录累计 int i = 0; string outputDirectory = Path.GetDirectoryName(file); string outputFilePath; // 找到当前目录下第一个未被占用的文件名 do { outputFilePath = Path.Combine(outputDirectory, $"{i}.mp4"); i++; } while (File.Exists(outputFilePath)); // 如果输出目录是自定义路径(非输入文件目录),取消注释下面的代码确保目录存在 // Directory.CreateDirectory(outputDirectory); using (Process process = new Process()) { process.StartInfo.FileName = ffmpegPath; // 使用Path.GetFullPath确保路径解析正确,避免空格/特殊字符问题 process.StartInfo.Arguments = $"-i \"{Path.GetFullPath(file)}\" -c:v copy -c:a copy \"{Path.GetFullPath(outputFilePath)}\""; process.StartInfo.CreateNoWindow = true; // 重定向输出与错误流,用于排查问题 process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.UseShellExecute = false; process.Start(); // 异步读取输出与错误信息避免死锁 string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(); // 检查执行结果 if (process.ExitCode == 0) { MessageBox.Show($"文件 {Path.GetFileName(file)} 重封装完成,输出路径:{outputFilePath}"); } else { // 显示错误信息,方便排查 MessageBox.Show($"重封装失败!\n退出码:{process.ExitCode}\n错误日志:{error}"); } } } }
额外注意事项
- 容器格式兼容性:如果你的需求是更改容器格式(比如从MKV转MP4),要确保音视频编码是目标容器支持的,比如MP4不支持VP9视频/Opus音频,这种情况即使
-c copy也会失败,需要调整参数或重新编码。 - 权限问题:确保程序对输出目录有读写权限,避免因权限不足导致文件无法生成。
- 路径特殊字符:使用
Path.GetFullPath可以避免路径中的空格、特殊字符被FFmpeg解析错误。
内容的提问来源于stack exchange,提问作者sadra hoseini
相关产品推荐
相关产品推荐

