2011-06-23 35 views
6

我想使用C#获取视频文件的持续时间。我搜查了互联网,我得到的全部是:如何在C#asp.net中使用FFMPEG获取视频持续时间

ffmpeg -i inputfile.avi 

而every1表示解析输出持续时间。

这里是我的代码是

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(); 
    } 

现在请告诉我,我怎么能保存输出字符串和解析它的视频时长。

感谢和问候,

+0

看看这里:http:// stackoverflow。com/questions/186822/capture-the-console-output-in-net-c –

回答

4

还有另一种选择,以获得视频时长,使用的媒体信息DLL

使用ffmpeg的:

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

过滤不应该是一个问题,所以做它是你自己。 PS:使用ffmpeg你不应该读StandardOutput,但ErrorOutput我不知道为什么,但它的工作只是这样。

+0

感谢您的代码没有工作,而我使用以下代码: 'proc.StartInfo.RedirectStandardError = true; string message = proc.StandardError.ReadToEnd();' 但是,无论如何,您已经向我展示了第一步,这对我来说最终会很好。 保持祝福! – Hamad

4

FFmpeg是一个有点冒险的解析。但无论如何,这是你需要知道的。

首先,FFmpeg的不RedirectOutput选项发挥好

什么你需要做的是,而不是直接启动的ffmpeg,推出cmd.exe,传递的ffmpeg作为参数,输出重定向到一个“监视器文件”通过命令行输出,就像这样...注意,在while (!proc.HasExited)循环中,您可以读取该文件以获得实时的FFmpeg状态,或者如果这是一个快速操作,则只需在最后读取该文件即可。

 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); 

太棒了,现在你已经得到了FFmpeg刚刚吐出的日志。现在获得持续时间。 持续时间线将是这个样子:

Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s

清理结果为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(); 

......然后通过他们循环寻找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); 
      } 
     } 

下面是一些代码,可以为您做解析:

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

对不起老兄!我无法理解你的代码。我的inputavi文件将放在哪里,我想找到持续时间?还解释你使用的变量,例如“encodeArgs”是什么。 – Hamad

+0

你的代码工作正常,当使用ffmpeg作为输入时,它显示关于ffmpeg的信息。我怎样才能使用这个来发送我的avi文件作为输入并获取它的信息?不管怎么说,多谢拉。 Yu正在做的很棒 – Hamad

+0

encodeArgs应该是你的“-i somefile.avi” – Brandon

1

刚检查出来::

//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])); 
     } 
    } 

与感谢, Gouranga达斯。

+0

真的,我爱你的答案,谢谢:) –

相关问题