FFmpeg es un poco difícil de analizar. Pero en cualquier caso, esto es lo que necesita saber.
En primer lugar, FFmpeg no juega bien con opciones RedirectOutput
Lo que usted tiene que hacer es en lugar de lanzar directamente ffmpeg, lanzar cmd.exe
, pasando en ffmpeg como un argumento, y redirigiendo la salida a un "archivo de monitor" a través de una salida de línea de comando como tal ... tenga en cuenta que en el lazo while (!proc.HasExited)
puede leer este archivo para el estado de FFmpeg en tiempo real, o simplemente leerlo al final si se trata de una operación rápida.
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);
Genial, ahora usted tiene el registro de lo que FFmpeg acaba de escupir. Ahora para obtener la duración. La línea de duración se verá algo como esto:
Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s
limpiar los resultados en un 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();
... a continuación, recorrer ellos en busca deDuration
.
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);
}
}
Aquí hay un código que puede hacer el análisis sintáctico para usted:
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];
}
Eche un vistazo aquí: http: // stackoverflow.com/questions/186822/capturing-the-console-output-in-net-c –