FFmpeg is a bit of an adventure to parse. But anyway, here is what you need to know.
Firstly, FFmpeg does not work well with RedirectOutput parameters
What you need to do is just run ffmpeg directly, run cmd.exe , pass it to ffmpeg as an argument and redirect the output to the “monitor file” via command line output, for example ... note that in a while (!proc.HasExited) you can read this file for FFmpeg status in real time or just read it at the end if it is a quick operation.
FileInfo monitorFile = new FileInfo(Path.Combine(ffMpegExe.Directory.FullName, "FFMpegMonitor_" + Guid.NewGuid().ToString() + ".txt")); string ffmpegpath = Environment.SystemDirectory + "\\cmd.exe"; string ffmpegargs = "/C " + ffMpegExe.FullName + " " + encodeArgs + " 2>" + monitorFile.FullName; string fullTestCmd = ffmpegpath + " " + ffmpegargs; ProcessStartInfo psi = new ProcessStartInfo(ffmpegpath, ffmpegargs); psi.WorkingDirectory = ffMpegExe.Directory.FullName; psi.CreateNoWindow = true; psi.UseShellExecute = false; psi.Verb = "runas"; var proc = Process.Start(psi); while (!proc.HasExited) { System.Threading.Thread.Sleep(1000); } string encodeLog = System.IO.File.ReadAllText(monitorFile.FullName);
Ok, now you have a log of what FFmpeg just spat out. Now to get the duration. The duration line will look something like this:
Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s
Clear the results to List<string> :
var encodingLines = encodeLog.Split(System.Environment.NewLine[0]).Where(line => string.IsNullOrWhiteSpace(line) == false && string.IsNullOrEmpty(line.Trim()) == false).Select(s => s.Trim()).ToList();
... then scroll through them looking for Duration .
foreach (var line in encodingLines) {
Here is the code that can do the parsing for you:
private TimeSpan ParseDurationLine(string line) { var itemsOfData = line.Split(" "[0], "="[0]).Where(s => string.IsNullOrEmpty(s) == false).Select(s => s.Trim().Replace("=", string.Empty).Replace(",", string.Empty)).ToList(); string duration = GetValueFromItemData(itemsOfData, "Duration:"); return TimeSpan.Parse(duration); } private string GetValueFromItemData(List<string> items, string targetKey) { var key = items.FirstOrDefault(i => i.ToUpper() == targetKey.ToUpper()); if (key == null) { return null; } var idx = items.IndexOf(key); var valueIdx = idx + 1; if (valueIdx >= items.Count) { return null; } return items[valueIdx]; }