How to get video duration using FFMPEG in c # asp.net

I want to get the duration of a video file in a string using C #. I searched on the internet and all I get is:

ffmpeg -i inputfile.avi 

And everyone will say that parsing is inferred for duration.

Here is my code that

 string filargs = "-y -i " + inputavi + " -ar 22050 " + outputflv; Process proc; proc = new Process(); proc.StartInfo.FileName = spath; proc.StartInfo.Arguments = filargs; proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = false; proc.StartInfo.RedirectStandardOutput = false; try { proc.Start(); } catch (Exception ex) { Response.Write(ex.Message); } try { proc.WaitForExit(50 * 1000); } catch (Exception ex) { } finally { proc.Close(); } 

Now please tell me how I can save the output line and analyze it for the duration of the video.

Thank you and welcome

+6
source share
3 answers

There is another option to get the length of the video using the Media Info DLL

Using ffmpeg:

 proc.StartInfo.RedirectErrorOutput = true; string message = proc.ErrorOutput.ReadToEnd(); 

Filtering should not be a problem, so do it yourself.

PS: using ffmpeg you should not read StandardOutput, but ErrorOutput I don’t know why, but it only works like that.

+4
source

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) { // Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s if (line.StartsWith("Duration")) { var duration = ParseDurationLine(line); } } 

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]; } 
+4
source

Just check:

  //Create varriables string ffMPEG = System.IO.Path.Combine(Application.StartupPath, "ffMPEG.exe"); system.Diagnostics.Process mProcess = null; System.IO.StreamReader SROutput = null; string outPut = ""; string filepath = "D:\\source.mp4"; string param = string.Format("-i \"{0}\"", filepath); System.Diagnostics.ProcessStartInfo oInfo = null; System.Text.RegularExpressions.Regex re = null; System.Text.RegularExpressions.Match m = null; TimeSpan Duration = null; //Get ready with ProcessStartInfo oInfo = new System.Diagnostics.ProcessStartInfo(ffMPEG, param); oInfo.CreateNoWindow = true; //ffMPEG uses StandardError for its output. oInfo.RedirectStandardError = true; oInfo.WindowStyle = ProcessWindowStyle.Hidden; oInfo.UseShellExecute = false; // Lets start the process mProcess = System.Diagnostics.Process.Start(oInfo); // Divert output SROutput = mProcess.StandardError; // Read all outPut = SROutput.ReadToEnd(); // Please donot forget to call WaitForExit() after calling SROutput.ReadToEnd mProcess.WaitForExit(); mProcess.Close(); mProcess.Dispose(); SROutput.Close(); SROutput.Dispose(); //get duration re = new System.Text.RegularExpressions.Regex("[D|d]uration:.((\\d|:|\\.)*)"); m = re.Match(outPut); if (m.Success) { //Means the output has cantained the string "Duration" string temp = m.Groups(1).Value; string[] timepieces = temp.Split(new char[] {':', '.'}); if (timepieces.Length == 4) { // Store duration Duration = new TimeSpan(0, Convert.ToInt16(timepieces[0]), Convert.ToInt16(timepieces[1]), Convert.ToInt16(timepieces[2]), Convert.ToInt16(timepieces[3])); } } 

Thanks, Guranga Das.

+1
source

Source: https://habr.com/ru/post/891233/


All Articles