Here's a class that starts FF and attaches event handlers to the relevant process events so it can see the output data as it's generated. It is used within a context where it's interesting to know if audio has started or stopped, which relied on ff having an extension that monitored the audio channels and pumped a message when silence started or stopped, but it demonstrates how you could have your own events on this class and raise them when ffmpeg pumps messages of interest. Mostly the class just captures the output into a log
public class FfmpegRecorder
{
public event Action SilenceDetected;
public event Action NoiseDetected;
private StringBuilder _ffLog = new StringBuilder();
private Process _ffmpeg;
private string _streamStats;
public override void StartRecording()
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = Properties.Settings.Default.CommandLineFfmpegPath,
Arguments = string.Format(
Properties.Settings.Default.CommandLineFfmpegArgs,
OutputPath
),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
_ffmpeg = System.Diagnostics.Process.Start(psi);
_ffmpeg.OutputDataReceived += Ffmpeg_OutputDataReceived;
_ffmpeg.ErrorDataReceived += Ffmpeg_ErrorDataReceived;
_ffmpeg.BeginOutputReadLine();
_ffmpeg.BeginErrorReadLine();
_ffmpeg.PriorityClass = ProcessPriorityClass.High;
}
void Ffmpeg_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && IsInteresting(e.Data))
{
_ffLog.Append("STDOUT: ").AppendLine(e.Data);
}
}
void Ffmpeg_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && IsInteresting(e.Data))
{
_ffLog.Append("STDERR: ").AppendLine(e.Data);
}
}
bool IsInteresting(string data)
{
if (data.StartsWith("frame="))
{
_streamStats = data;
return false;
}
try
{
if (SilenceDetected != null && data.Contains("silence_start"))
SilenceDetected();
else if (NoiseDetected != null && data.Contains("silence_end"))
NoiseDetected();
}
catch { }
return true;
}
}
}