【问题标题】:How to get the video duration using FFMPEG in C# asp.net如何在 C# asp.net 中使用 FFMPEG 获取视频持续时间
【发布时间】:2011-09-21 10:47:54
【问题描述】:

我想使用 C# 以字符串形式获取视频文件的持续时间。我搜索了互联网,我得到的是:

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

现在请告诉我如何保存输出字符串并将其解析为视频持续时间。

感谢和问候,

【问题讨论】:

标签: c# asp.net ffmpeg process


【解决方案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]));
        }
    }

感谢, 古兰加达斯。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 对不起,伙计!我无法理解您的代码。我的 inputavi 文件将在哪里适合我想找到持续时间???还要解释你使用的变量,例如“encodeArgs”它是什么。
    • 您的代码运行良好,当使用 ffmpeg 作为输入时,它会显示有关 ffmpeg 的信息。我如何使用它来发送我的 avi 文件作为输入并获取它的信息???不管怎么说,多谢拉。余做得很好
    • 如果有一个名为 Duration 和 Value "00:00:00" 的元数据怎么办?安全性并不完美
    【解决方案3】:

    还有另一个选项来获取视频长度,通过使用媒体信息DLL

    使用 Ffmpeg:

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

    过滤不应该是问题,你自己做吧。

    PS:使用 ffmpeg 你不应该阅读 StandardOutput 但 ErrorOutput 我不知道为什么,但它只是这样工作。

    【讨论】:

    • 谢谢你的代码没有工作,而是我使用了以下代码:'proc.StartInfo.RedirectStandardError = true;字符串消息 = proc.StandardError.ReadToEnd();'但无论如何,谢谢,你向我展示了第一步,最终对我来说很好。保持祝福!!!
    猜你喜欢
    • 2014-02-26
    • 2022-11-10
    • 2016-12-17
    • 2015-06-14
    • 2011-10-04
    • 1970-01-01
    • 2014-08-07
    • 2015-05-29
    • 2020-12-11
    相关资源
    最近更新 更多