如何捕获FFmpeg实时进度流并在PS2EXE编译脚本中展示
解决FFmpeg在ps2exe编译后的进度显示问题
问题说明
使用ps2exe将PowerShell脚本编译为exe后,FFmpeg默认的交互式单行进度报告无法正常显示——原因是该进度输出到标准错误(stderr)而非标准输出(stdout)。若在脚本中添加-progress pipe:1参数,FFmpeg会每秒输出多行包含frame等字段的进度信息,导致控制台刷屏,需要实现单行可更新的进度百分比或符号进度条,或让默认进度正常显示。
方案1:恢复FFmpeg默认交互式进度显示
FFmpeg默认的单行交互进度输出到stderr,ps2exe编译后的程序需正确转发该输出。修改调用命令,将stderr重定向到stdout即可:
& $ffmpeg_path -i input.mp4 -c:v libx264 -pix_fmt yuv420p -crf 25 -preset fast -an output.mp4 2>&1
此方法无需额外处理,直接让FFmpeg原生的单行进度在exe控制台中显示。
方案2:基于-progress pipe:1实现自定义单行进度条
若需自定义进度展示,可捕获FFmpeg的-progress输出,提取当前帧并结合总帧数计算进度,用Write-Host实现单行刷新效果:
完整实现代码
# 用ffprobe提前获取视频总帧数 $maxFrames = [int](& ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp4) # 调用FFmpeg并实时处理进度输出 & $ffmpeg_path -progress pipe:1 -i input.mp4 -c:v libx264 -pix_fmt yuv420p -crf 25 -preset fast -an output.mp4 | ForEach-Object { # 匹配提取当前帧数值 if ($_ -match 'frame=(\d+)') { $currentFrame = [int]$matches[1] # 计算进度百分比(取整) $progress = [math]::Round(($currentFrame * 100) / $maxFrames, 0) # 生成进度条符号 $completedBars = "#" * $progress $remainingBars = "-" * (100 - $progress) # 单行刷新输出进度 Write-Host -NoNewLine "`r进度: $progress% | $completedBars $remainingBars|" } } # 进度完成后换行,避免后续输出覆盖进度条 Write-Host ""
关键说明
- 必须预先通过ffprobe获取视频总帧数
$maxFrames,确保进度计算准确 - 使用
Write-Host -NoNewLine配合\r(回车符)实现单行覆盖,解决刷屏问题 - ps2exe编译后
Write-Progress无法正常工作,因此采用Write-Host的替代方案
内容的提问来源于stack exchange,提问作者user206904
相关产品推荐
相关产品推荐

