Search code examples
c#ffmpegprocess

How to recognize that ffmpeg pipe ended?


I am executing an ffmpeg command with a very complex filter and with a pipe within a C# application. I am putting images into the ffmpeg input stream (pipe)for rendering these images as overlays to the final video.

I want to render images with the pipe until the pipe closes. Unfortunately, I do not know how I can recognize that the pipe of the ffmpeg process has closed. Is there any possibility of recognizing this event within C#?

The process is started like:

this._ffmpegProcess = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = this._ffmpegPath,
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        CreateNoWindow = true
    }
};

this._ffmpegProcess.StartInfo.Arguments = ffmpegCmd;
this._ffmpegProcess.OutputDataReceived += this.Proc_DataReceived;
this._ffmpegProcess.ErrorDataReceived += this.Proc_DataReceived;
this._ffmpegProcess.Exited += this._ffmpegProcess_Exited;
this._ffmpegProcess.Start();
this._ffmpegProcess.BeginOutputReadLine();
this._ffmpegProcess.BeginErrorReadLine();

The rendering happens within a timer:

this._renderOverlayTimer = new Timer(this.RenderOverlay);
this._renderOverlayTimer.Change(0, 30);    

The timer is started right after starting the ffmpeg process:

private void RenderOverlay(object state)
{
   using (var ms = new MemoryStream())
   {
      using (var img = GetImage(...))
      {
          img.Save(ms, ImageFormat.Png);
          ms.WriteTo(this._ffmpegProcess.StandardInput.BaseStream);
      }
   }
}

The problem is that I always receive a "The pipe has ended" error at ms.WriteTo().


Solution

  • I now use a named pipe and trace the number of frames to process. The named pipe is closed right after the last frame is processed. This solution leads to a correct video without IOExceptions.