FFmpeg là một chút phiêu lưu để phân tích cú pháp. Nhưng trong mọi trường hợp, đây là những gì bạn cần biết.
Thứ nhất, FFmpeg không chơi tốt với các tùy chọn RedirectOutput
Những gì bạn sẽ cần phải làm là thay vì tung ra ffmpeg trực tiếp, khởi động cmd.exe
, đi qua trong ffmpeg như một cuộc tranh cãi, và chuyển hướng đầu ra để một "tập tin giám sát" thông qua một đầu ra dòng lệnh như vậy ... lưu ý rằng trong vòng lặp while (!proc.HasExited)
bạn có thể đọc tệp này cho trạng thái FFmpeg thời gian thực, hoặc chỉ đọc nó ở cuối nếu đây là một thao tác nhanh.
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);
Tuyệt vời, bây giờ bạn đã có nhật ký về những gì FFmpeg chỉ nhổ ra. Bây giờ để có được thời gian. Dòng thời gian sẽ giống như thế này:
Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s
Dọn dẹp các kết quả vào một 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();
... sau đó vòng qua chúng tìm kiếmDuration
.
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);
}
}
Dưới đây là một số mã có thể thực hiện phân tích cú pháp cho bạn:
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];
}
Hãy xem tại đây: http: // stackoverflow.com/questions/186822/capturing-the-console-output-in-net-c –