【问题标题】:C# Process StandardInput and StandardOutput with FFmpeg freezes带有 FFmpeg 的 C# 处理 StandardInput 和 StandardOutput 冻结
【发布时间】:2018-11-13 18:40:12
【问题描述】:

我正在尝试将一些流传输到 ffmpeg 并捕获它的输出,以便我可以在我的代码中传递另一个流。 这是一个代码示例,它只是在我写入其StandardInput.BaseStream 后停止进程继续。

internal class Program
    {
        private static void Main(string[] args)
        {
            var inputFile = @"C:\Temp\test.mp4";
            var outputFile = @"C:\Temp\test.mp3";

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    Arguments = "-i - -f mp3 -",
                    FileName = "ffmpeg.exe"
                },
                EnableRaisingEvents = true
            };

            process.ErrorDataReceived += (sender, eventArgs) => Console.WriteLine(eventArgs.Data);

            process.Start();
            process.BeginErrorReadLine();

            using (var input = new FileStream(inputFile, FileMode.Open))
            using (var output = new FileStream(outputFile, FileMode.Create))
            {
                input.CopyTo(process.StandardInput.BaseStream);
                process.StandardOutput.BaseStream.CopyTo(output);
            }

            process.WaitForExit();

            Console.WriteLine("done");
            Console.ReadLine();
        }
    }

这个例子和这个问题的答案几乎一样:https://stackoverflow.com/a/8999542/2277280

我做错了什么? 为什么这个过程不继续? 是 ffmpeg 特有的吗?

【问题讨论】:

  • 您可能需要尝试读取标准输出,类似于您获得错误输出的方式 - 基于事件处理程序。我的猜测是输出缓冲区已满,因为您的代码直到输入完成后才会读取它。它可能处于死锁状态,无法继续输入,也无法向输出缓冲区输出更多数据。

标签: c# .net ffmpeg process


【解决方案1】:

我必须异步读写标准输入和标准输出以避免死锁。 Wiz 和this post 的评论把我引向了正确的方向!谢谢! 关闭 StandardInput 以结束进程也很重要。 否则它仍然会等待更多输入并且标准输出保持打开并且永远不会完成复制。 以下代码在我的场景中运行良好:

private static void Main(string[] args)
        {
            var inputFile = @"C:\Temp\test.mp4";
            var outputFile = @"C:\Temp\test.mp3";

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    Arguments = "-i - -f mp3 -",
                    FileName = "ffmpeg.exe"
                },
                EnableRaisingEvents = true
            };

            process.ErrorDataReceived += (sender, eventArgs) =>
            {
                Console.WriteLine(eventArgs.Data);
            };

            process.Start();
            process.BeginErrorReadLine();

            var inputTask = Task.Run(() =>
            {
                using (var input = new FileStream(inputFile, FileMode.Open))
                {
                    input.CopyTo(process.StandardInput.BaseStream);
                    process.StandardInput.Close();
                }
            });

            var outputTask = Task.Run(() =>
            {
                using (var output = new FileStream(outputFile, FileMode.Create))
                {
                    process.StandardOutput.BaseStream.CopyTo(output);
                }
            });


            Task.WaitAll(inputTask, outputTask);

            process.WaitForExit(); 

            Console.WriteLine("done");
            Console.ReadLine();
        }

【讨论】:

  • 这个可以处理不断增长的视频文件吗?
猜你喜欢
  • 1970-01-01
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
  • 2017-06-07
相关资源
最近更新 更多