Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to pipe some stream to ffmpeg and capture it's output so that I can pass on another stream in my code. Here is a code example, that just stops the process from continuing after I write to its 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();

This example is pretty much the same as in the answer in this question: https://stackoverflow.com/a/8999542/2277280

What am I doing wrong? Why does the process not continue? Is it ffmpeg specific?

You may need to try reading the Standard Output similar to how you have the Error Output - based on the event handler. My guess is that the output buffer is full, since your code doesn't read it until after the input is completed. It is probably in a deadlocked state, where it can't continue the input, but also cannot output any more data to the output buffer. – Wiz Jun 4, 2018 at 17:06

I had to write and read from stdin and stdout asynchronously to avoid a deadlock. The comment from Wiz and this post took me in the right direction! Thanks! It was also important to close the StandardInput to make the process end. Otherwise it would still wait for more input and the stdout keeps open and would never finish copying. Following code works perfectly fine in my scenario:

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

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.