You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:35:16