使用FFmpeg录制桌面触发StandardIn未重定向异常的解决求助
解决FFmpeg录制桌面时StandardIn未重定向的异常
问题原因
- FFmpeg启动失败:若FFmpeg路径错误、命令参数无效,会导致进程提前退出,此时访问
StandardInput会触发异常。 - 进程实例状态复用问题:类级别的
Process实例可能因重复配置导致重定向设置未正确生效。 - 未检查进程运行状态:直接操作
StandardInput前未确认进程是否仍在运行。
解决方案
- 确认FFmpeg路径正确,命令参数有效;
- 在启动方法内创建新的
Process实例,避免复用旧实例的状态; - 操作
StandardInput前先检查进程是否处于运行状态; - 设置
CreateNoWindow=true隐藏FFmpeg控制台窗口; - 简化停止命令的写入方式,直接使用
StandardInput.Write("q")。
修正后的完整代码
using System; using System.Diagnostics; using System.Windows.Forms; namespace Desktop_Recorder { public partial class Form1 : Form { private Process _recorderProcess; public Form1() { InitializeComponent(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { StopRecording(); } public void StartRecording(string fileName, int frameRate) { // 先停止已有录制进程 StopRecording(); _recorderProcess = new Process(); var startInfo = _recorderProcess.StartInfo; // 替换为你的FFmpeg实际路径 startInfo.FileName = @"d:\ffmpeg\ffmpeg.exe"; startInfo.WorkingDirectory = @"D:\"; // 桌面录制参数,如需录制音频可添加对应参数(如-f dshow -i audio="麦克风名称") startInfo.Arguments = $"-y -f gdigrab -framerate {frameRate} -i desktop -preset ultrafast -pix_fmt yuv420p {fileName}"; // 重定向输入输出必须设置为false startInfo.UseShellExecute = false; // 隐藏控制台窗口 startInfo.CreateNoWindow = true; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardError = true; _recorderProcess.Start(); // 异步读取错误输出,方便排查FFmpeg启动问题 _recorderProcess.BeginErrorReadLine(); } public void StopRecording() { if (_recorderProcess != null && !_recorderProcess.HasExited) { try { // 向FFmpeg发送停止命令 _recorderProcess.StandardInput.Write("q"); _recorderProcess.StandardInput.Flush(); // 等待进程正常退出,避免强制关闭导致文件损坏 _recorderProcess.WaitForExit(5000); } catch (Exception ex) { Debug.WriteLine($"停止录制出错:{ex.Message}"); } finally { _recorderProcess.Close(); _recorderProcess.Dispose(); _recorderProcess = null; } } } private void btnStartRecording_Click(object sender, EventArgs e) { // 点击按钮启动录制 StartRecording(@"d:\test.mp4", 30); } } }
关键修改说明
- 取消类级别的
Process预初始化,改为在启动录制时创建新实例,避免状态冲突; - 添加进程运行状态检查,确保操作
StandardInput时进程未退出; - 设置
CreateNoWindow=true实现控制台窗口隐藏; - 使用
StandardInput.Write("q")替代直接操作BaseStream,简化代码且避免编码问题; - 增加进程资源释放逻辑,防止内存泄漏和文件损坏;
- 异步读取错误输出,便于排查FFmpeg启动失败的具体原因。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

