2011-06-23 80 views
6

Tôi muốn lấy thời lượng tệp video bằng chuỗi bằng C#. Tôi đã tìm kiếm trên internet và tất cả những gì tôi nhận được là:Cách lấy thời lượng video bằng cách sử dụng FFMPEG trong C# asp.net

ffmpeg -i inputfile.avi 

Và mọi người nói rằng phân tích đầu ra trong thời gian.

Đây là mã của tôi mà là

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

Bây giờ hãy cho tôi biết làm thế nào tôi có thể lưu các chuỗi sản lượng và phân tích nó trong suốt thời gian video.

Trân trọng cảm ơn,

+0

Hãy xem tại đây: http: // stackoverflow.com/questions/186822/capturing-the-console-output-in-net-c –

Trả lời

4

Có một lựa chọn để cài đặt video Chiều dài, bằng cách sử dụng phương tiện thông tin DLL

Sử dụng Ffmpeg:

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

lọc không phải là một vấn đề, vì vậy làm nó là bạn.

PS: sử dụng ffmpeg bạn không nên đọc StandardOutput nhưng ErrorOutput tôi không biết tại sao, nhưng nó chỉ hoạt động như thế.

+0

Cảm ơn người đàn ông mã của bạn đã không hoạt động thay vì tôi đã sử dụng mã sau đây: 'proc.StartInfo.RedirectStandardError = true; thông báo chuỗi = proc.StandardError.ReadToEnd(); ' Nhưng dù sao đi nữa, bạn đã cho tôi thấy bước đầu tiên, cuối cùng cũng trở nên tốt đẹp cho tôi. Hãy ở lại Blesses !!! – Hamad

4

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

Xin lỗi anh bạn! Tôi không thể hiểu mã của bạn. Tệp inputavi của tôi sẽ ở đâu trong đó tôi muốn tìm thời lượng ??? Cũng giải thích các biến u hav được sử dụng, ví dụ: "encodeArgs" Nó là gì. – Hamad

+0

mã của bạn hoạt động tốt, hiển thị thông tin về ffmpeg khi sử dụng ffmpeg làm đầu vào. Làm thế nào tôi có thể sử dụng để gửi tập tin avi của tôi như là đầu vào và nhận được thông tin của nó? Dù sao cũng cảm ơn. Yu đang làm tuyệt vời – Hamad

+0

encodeArgs nên là "-i somefile.avi" – Brandon

1

Chỉ cần check it out ::

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

Với cảm ơn, Gouranga Das.

+0

Thực sự, tôi yêu câu trả lời của bạn, cảm ơn bạn :) –

Các vấn đề liên quan