如何在PowerShell中检测FFmpeg输出停滞并自动重启进程?
实现FFmpeg进程停滞检测与自动重启(PowerShell)
完全可以实现这个需求,核心是实时捕获FFmpeg的输出流,跟踪最后一行内容的更新时间,当超过5秒未更新时判定为进程停滞,执行日志记录、终止进程并重启的操作。
实现思路
- 用
Start-Process启动FFmpeg,重定向标准输出和错误输出到临时文件,方便实时读取最新输出 - 启动后台监控任务,定期检查输出的最后一行内容,记录其更新时间戳
- 当最后一行内容超过5秒未变化时,触发停滞处理逻辑:写入日志、终止FFmpeg进程,随后重启命令
完整代码示例
# 配置参数 $logFilePath = ".\ffmpeg_monitor.log" $ffmpegExe = "ffmpeg" # 若未加入系统PATH,替换为完整路径如"C:\ffmpeg\bin\ffmpeg.exe" $outputBasePath = ".\recording_" # 可根据需求修改输出路径规则 function Invoke-FFmpegWithWatchdog { # 生成当前录制文件路径(避免重名覆盖) $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $outputPath = "${outputBasePath}${timestamp}.mp3" $ffmpegArgs = '-f', 'dshow', '-i', 'audio="Microphone (USB Microphone)"', '-y', '-t', '00:10:00', '-b:a', '128k', $outputPath # 临时输出文件(捕获FFmpeg的stdout/stderr) $tempStdout = ".\ffmpeg_temp_stdout.log" $tempStderr = ".\ffmpeg_temp_stderr.log" Remove-Item $tempStdout, $tempStderr -ErrorAction SilentlyContinue # 启动FFmpeg进程 $ffmpegProc = Start-Process -FilePath $ffmpegExe -ArgumentList $ffmpegArgs -PassThru -NoNewWindow ` -RedirectStandardOutput $tempStdout -RedirectStandardError $tempStderr # 启动后台监控任务 $watchdogJob = Start-Job -ScriptBlock { param($stdoutPath, $stderrPath, $logPath) $lastLine = "" $lastUpdateTime = Get-Date while ($true) { # 读取最新的输出行(优先取stderr,FFmpeg进度通常输出到这里) $currentStderr = Get-Content $stderrPath -Tail 1 -ErrorAction SilentlyContinue $currentLine = $currentStderr ? $currentStderr : (Get-Content $stdoutPath -Tail 1 -ErrorAction SilentlyContinue) if ($currentLine -ne $lastLine) { $lastLine = $currentLine $lastUpdateTime = Get-Date } else { # 检查是否超过5秒未更新 if ((Get-Date) - $lastUpdateTime -gt [TimeSpan]::FromSeconds(5)) { $logMsg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): warning: the program is freezing. trying to restart..." Add-Content $logPath $logMsg Write-Host $logMsg # 强制终止FFmpeg进程 Stop-Process -Id $using:ffmpegProc.Id -Force -ErrorAction SilentlyContinue break } } Start-Sleep -Seconds 1 } } -ArgumentList $tempStdout, $tempStderr, $logFilePath # 等待FFmpeg进程结束或被监控任务终止 Wait-Process -Id $ffmpegProc.Id -ErrorAction SilentlyContinue # 清理监控任务 Stop-Job $watchdogJob -ErrorAction SilentlyContinue Remove-Job $watchdogJob -ErrorAction SilentlyContinue } # 循环执行:进程终止后自动重启 while ($true) { Invoke-FFmpegWithWatchdog Start-Sleep -Seconds 1 # 重启前短暂延迟,避免频繁重启 }
注意事项
- 确保FFmpeg可被PowerShell调用:要么将FFmpeg所在目录加入系统PATH,要么在代码中指定完整的可执行文件路径
- 临时输出文件和日志文件的路径可根据实际环境调整,避免权限不足的问题
- FFmpeg通常将进度信息输出到标准错误流(stderr),所以代码中优先读取stderr的内容
- 可根据需求调整监控间隔(比如将
Start-Sleep -Seconds 1改为0.5以提升检测灵敏度)
内容的提问来源于stack exchange,提问作者丶 Limeー来夢 丶
相关产品推荐
相关产品推荐

