FFmpeg to odrobina przygody do przeanalizowania. Ale w każdym razie, oto, co powinieneś wiedzieć.
pierwsze, FFmpeg nie gra dobrze z opcji RedirectOutput
Co trzeba zrobić, to zamiast uruchamiania ffmpeg bezpośrednio uruchomić cmd.exe
, przekazując ffmpeg jako argument, a przekierowanie wyjścia do "plik monitora" poprzez wyjście z wiersza poleceń, tak jak ... pamiętaj, że w pętli while (!proc.HasExited)
możesz odczytać ten plik dla stanu FFmpeg w czasie rzeczywistym lub po prostu przeczytać go na końcu, jeśli jest to szybka operacja.
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);
Świetnie, teraz masz log tego, co FFmpeg po prostu wypluwa. Teraz, aby uzyskać czas trwania. Linia czas trwania będzie wyglądać mniej więcej tak:
Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s
oczyścić wyniki do 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();
... wtedy pętla przez nich szukaDuration
.
foreach (var line in encodingLines)
{
// Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s
if (line.StartsWith("Duration"))
{
var duration = ParseDurationLine(line);
}
}
Oto niektóre kod, który może zrobić dla ciebie parse:
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];
}
Zobacz tutaj: http: // stackoverflow.com/questions/186822/capture-the-console-output-in-net-c –