ffmpeg process how to read from pipe to pipe in c#

Viewed 28

I need to read audio data from stream 1 to stream 2 passing the data through ffmpeg. It works great when i input data from file and output to pipe:

Process? CreateStream()
{
    return Process.Start(new ProcessStartInfo
    {
        FileName = @"sources\ffmpeg",
        Arguments = @"-i input.mp3 -f s16le pipe:1",
        UseShellExecute = false,
        RedirectStandardOutput = true
    });
}

Or when i input data from pipe and output to file:

Process? CreateStream()
{
    return Process.Start(new ProcessStartInfo
    {
        FileName = @"sources\ffmpeg",
        Arguments = @"-i pipe: -f s16le output.file",
        UseShellExecute = false,
        RedirectStandardInput = true
    });
}

But if i try to do both:

Process? CreateStream()
{
    return Process.Start(new ProcessStartInfo
    {
        FileName = @"sources\ffmpeg",
        Arguments = @"-i pipe:0 -f s16le pipe:1",
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true
    });
}

Runtime will hang in place printing:

Input #0, matroska,webm, from 'pipe:0': Metadata: encoder : google/video-file Duration: 00:04:15.38, start: -0.007000, bitrate: N/A Stream #0:0(eng): Audio: opus, 48000 Hz, stereo, fltp (default) Stream mapping: Stream #0:0 -> #0:0 (opus (native) -> pcm_s16le (native))

Output #0, s16le, to 'pipe:1': Metadata: encoder : Lavf59.27.100 Stream #0:0(eng): Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s (default) Metadata: encoder : Lavc59.37.100 pcm_s16le

main function code (it is the same for all examples):

async Task Do()
{
    using (var ffmpeg = CreateStream())
    {
        if (ffmpeg == null) return;

        using (var audioStream = GetAudioStream())
        {
            await audioStream.CopyToAsync(ffmpeg.StandardInput.BaseStream);
            ffmpeg.StandardInput.Close();
        }

        //runtime will hang in here

        Console.WriteLine("\n\ndone\n\n"); //this won't be printed

        using (var outputStream = CreatePCMStream())
        {
            try
            {
                await ffmpeg.StandardOutput.BaseStream.CopyToAsync(outputStream);
            }
            finally
            {
                await outputStream.FlushAsync();
            }
        }
    }
}

And the most interesting is if i remove RedirectStandardOutput = true string programm will work as expected printing a bunch of raw data to the console.

I'd like to solve this problem without using any intermediate files and so on.

0 Answers
Related