【问题标题】:Show progress of a video conversion with FFMpeg使用 FFMpeg 显示视频转换的进度
【发布时间】:2015-04-26 20:08:56
【问题描述】:

我正在使用 C# WinForms 制作视频转换器,我正在使用 NReco.VideoConverter 库。它有一个名为ConvertProgress 的事件处理程序,但我从未使用过事件处理程序,我在互联网上搜索了一些信息,但我仍然不知道如何将它应用到我的应用程序中。

我试过了:

public static event EventHandler<ConvertProgressEventArgs> _getPercent;
//...
_getPercent += ???
progressBar1.Value = ??

我被困在那里,我不知道该怎么办。有人能帮我吗??提前致谢。

【问题讨论】:

    标签: c# ffmpeg progress-bar encoder video-conversion


    【解决方案1】:

    首先,摆脱您的自定义事件。您想收听/订阅他们的事件,而不是你的。

    其次,您需要一个实际的转换器实例,然后订阅它的事件:

    FFMpegConverter converter = new FFMpegConverter(); //May not work, for sample only
    converter.ConvertProgress += UpdateProgress;
    

    现在您需要一个名为 UpdateProgress 的方法(您也可以只使用上面的 lambda 表达式):

    private void UpdateProgress(object sender, ConvertProgressEventArgs e)
    {
    }
    

    然后在该方法的主体中,更新您的进度条。请注意,您需要将更改编组到 UI 线程。在使用 Control.Invoke 完成的 Windows 窗体中

    progressBar1.Invoke(new Action(() =>
    {
         progressBar1.Value = e.Processed; //Or whatever calculation you want
    }));
    

    对于其他人,如果您还没有看过,这里是该事件的文档:http://www.nrecosite.com/doc/NReco.VideoConverter/html/E_NReco_VideoConverter_FFMpegConverter_ConvertProgress.htm

    【讨论】:

    • @ChrisCreateBoss 是的,除非您熟悉事件,否则它没有多大帮助:) FFMpeg 文档很好,但它们没有太多“使用”示例:(
    • 是的,这是真的......否则,我如何将您的 e.Processed 转换为整数(progressBar.Value 需要一个整数值才能工作)。
    • @ChrisCreateBoss 该事件“TotalDuration”还有另一个属性。您将除以该值(将完成百分比作为两倍)并将其缩放为您的进度条
    • 试过了,但我仍然得到“无法将类型 TimeSpan 隐式转换为 int”
    • @ChrisCreateBoss 为每个人使用TotalMilliseconds (processed.TotalMilliseconds / total.TotalMilliseconds)
    【解决方案2】:

    我已经解决了标准错误的重定向并在方法中使用流式阅读器读取。

    public double Progress{get;set;}
    

    创建新进程

    Process run = new Process();
    run.StartInfo.FileName = Path.Combine(path, "ffmpeg.exe");
    run.StartInfo.Arguments ="your string with output options";
    run.StartInfo.UseShellExecute = false;
    run.StartInfo.CreateNoWindow = true;
    run.StartInfo.RedirectStandardError = true;
    run.Start();
    StreamReader sr = run.StandardError;
    while (!sr.EndOfStream)
    {
        getTotalSecondProcessed(sr.ReadLine());
    }
    

    并重定向输出

    private void getTotalSecondProcessed(string v)
    {
       try
       {
           string[] split = v.Split(' ');
           foreach (var row in split)
           {
               if (row.StartsWith("time="))
               {
                   var time = row.Split('=');
                   Progress = TimeSpan.Parse(time[1]).TotalSeconds;
               }
           }      
           catch{}
       }
    

    在 WinForm 中创建一个由 timer_Tick 调用的方法

    private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {        
                int progress = int.Parse(utilityVideo.Progress.ToString("0"));
    
                if (progress > 0)
                {
                    RefreshProgressBar(Progress);
                }
            }                
        }
        catch { }
        }
    
    private void RefreshProgressBar(int currentTimeProcessed)
        {
            if (InvokeRequired)
            {
                BeginInvoke((MethodInvoker)delegate { RefreshProgressBar(currentTimeProcessed); });
                return;
            }
            progressBar1.Value = currentTimeProcessed;
        }
    

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 2017-12-20
      • 1970-01-01
      • 2020-01-11
      • 2016-01-28
      • 2013-08-19
      • 1970-01-01
      • 2013-06-17
      • 2012-12-19
      相关资源
      最近更新 更多