简体   繁体   English

异步从ffmpeg输出流

[英]c# - How to asynchronously stream output from ffmpeg

I created a method to call ffmpeg binaries and do stuff for me. 我创建了一种方法来调用ffmpeg二进制文件并为我做一些事情。 It worked perfectly fine on a standard console application. 在标准控制台应用程序上,它工作得很好。 I am trying to make a Windows Form Application version but there are few problems. 我正在尝试制作Windows窗体应用程序版本,但问题很少。 The app freezes (but the progress bar is still updating) when the ffmpeg process is still running. 当ffmpeg进程仍在运行时,应用程序冻结(但进度栏仍在更新)。 The textboxes are not being updated. 文本框未更新。 I cannot move the app window. 我无法移动应用程序窗口。 I suspect this is because of the loop and I googled some stuff and found out that I might need to do this asynchronously but how do I do that exactly. 我怀疑这是由于循环造成的,我在Google上搜索了一些内容,发现我可能需要异步执行此操作,但是我该怎么做呢。

public void ffmpeg(string ffmpeg_exe, string args)
        {
            Process p = new Process();
            p.StartInfo.FileName = ffmpeg_exe;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.Arguments = args;
            p.StartInfo.UseShellExecute = false;
            p.Start();

            StreamReader reader = p.StandardError;
            string line;

            string size = "", current_duration = "", duration = "";

            while ((line = reader.ReadLine()) != null)
            {
                if (!string.IsNullOrEmpty(line))
                {
                    if (line.Contains("Duration") && line.Contains("bitrate") && line.Contains("start"))
                    {
                        duration = RemoveWhitespace(Between(line, "Duration:", ", start"));
                        totaltime.Text = duration;
                    }

                    if (line.Contains("frame=") && line.Contains("size=") && line.Contains("time="))
                    {
                        size = RemoveWhitespace(Between(line, "size=", " time"));
                        current_duration = RemoveWhitespace(Between(line, "time=", " bitrate"));
                        progressBar_main.Value = Convert.ToInt32(Math.Round(TimeSpan.Parse(current_duration.Substring(0, current_duration.Length -3)).TotalSeconds * 100 / TimeSpan.Parse(duration.Substring(0,duration.Length-3)).TotalSeconds, 3));
                        current_time.Text = current_duration;
                        filesize.Text = size;
                    }
                }
            }

            p.Close();

            current_time.Text = "";
            filesize.Text = "";
            totaltime.Text = "";
            progressBar_main.Value = 0;

        }

Try using Task like this : 尝试像这样使用Task

Action action = () =>
                            {
                               //Do your streaming here
                            };

Then start it : 然后启动它:

Task t2 = Task.Factory.StartNew(action);

Hope this was useful. 希望这是有用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM