c# winforms 显示 ffmpeg 输出
c# winforms display ffmpeg output
我正在开发一个可以使用网络摄像头和麦克风录制 video/audio 的应用程序,同时还可以在 winforms 上显示它。
Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-f dshow -video_size 1280x720 -framerate 30 -vcodec mjpeg -i video=\"{video device}\":audio=\"{audio device}\" -pix_fmt yuv420p -f mp4 -movflags frag_keyframe+empty_moov {output}"
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
});
目前正在使用这个 ffmpeg 命令来录制和保存 mp4。我想知道如果我使用 pipe:1 作为输出而不是文件路径,如何在 winforms 中显示输出流。我以前用过 aforge.Directshow 但是保存的视频质量很差。欢迎就如何执行此操作提出任何其他建议。
这是一个 class,它启动 FF 并将事件处理程序附加到相关的流程事件,以便它可以在生成时查看输出数据。它用于了解音频是否已开始或停止的有趣上下文,这依赖于 ff 有一个扩展程序来监视音频通道并在静音开始或停止时发送消息,但它演示了如何拥有自己的事件在此 class 上,并在 ffmpeg 发送感兴趣的消息时引发它们。大多数情况下 class 只是将输出捕获到日志中
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;
}
}
}
发现vlc 有一个用于winforms 的库。 here is a tutorial on how to add it. for the VlcLibDirectory property you will need to download vlc。
只需将 ffmpeg.StandardOutput.BaseStream 传递到它的播放方法中即可。
我正在开发一个可以使用网络摄像头和麦克风录制 video/audio 的应用程序,同时还可以在 winforms 上显示它。
Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-f dshow -video_size 1280x720 -framerate 30 -vcodec mjpeg -i video=\"{video device}\":audio=\"{audio device}\" -pix_fmt yuv420p -f mp4 -movflags frag_keyframe+empty_moov {output}"
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
});
目前正在使用这个 ffmpeg 命令来录制和保存 mp4。我想知道如果我使用 pipe:1 作为输出而不是文件路径,如何在 winforms 中显示输出流。我以前用过 aforge.Directshow 但是保存的视频质量很差。欢迎就如何执行此操作提出任何其他建议。
这是一个 class,它启动 FF 并将事件处理程序附加到相关的流程事件,以便它可以在生成时查看输出数据。它用于了解音频是否已开始或停止的有趣上下文,这依赖于 ff 有一个扩展程序来监视音频通道并在静音开始或停止时发送消息,但它演示了如何拥有自己的事件在此 class 上,并在 ffmpeg 发送感兴趣的消息时引发它们。大多数情况下 class 只是将输出捕获到日志中
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;
}
}
}
发现vlc 有一个用于winforms 的库。 here is a tutorial on how to add it. for the VlcLibDirectory property you will need to download vlc。 只需将 ffmpeg.StandardOutput.BaseStream 传递到它的播放方法中即可。