如何在C#asp.net中使用FFMPEG获取视频时长

Ham*_*mad 6 c# asp.net ffmpeg

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

ffmpeg -i inputfile.avi
Run Code Online (Sandbox Code Playgroud)

而且每个人都说要解析输出的持续时间.

这是我的代码

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();
    }
Run Code Online (Sandbox Code Playgroud)

现在请告诉我如何保存输出字符串并在视频持续时间内解析它.

感谢致敬,

Bur*_*imi 5

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

使用Ffmpeg:

proc.StartInfo.RedirectErrorOutput = true;
string message = proc.ErrorOutput.ReadToEnd();
Run Code Online (Sandbox Code Playgroud)

过滤不应该成为问题,所以这是您自己。

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


Bra*_*don 5

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);
Run Code Online (Sandbox Code Playgroud)

太好了,现在您已经获得了 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();
Run Code Online (Sandbox Code Playgroud)

...然后遍历它们寻找 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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

以下是一些可以为您解析的代码:

    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];
    }
Run Code Online (Sandbox Code Playgroud)