使用 PowerShell + ffmpeg 自动压缩视频(支持 CRF、无损、目标大小模式)

视频文件往往体积庞大,尤其是高分辨率或高码率的视频。如果你经常需要压缩视频以便存储、传输或分享,那么手动输入 ffmpeg 命令会很繁琐。本文将教你如何编写一个 PowerShell 自动化脚本,智能选择压缩参数,支持以下模式:

前提:需要安装Windows 安装 FFmpeg 新手教程(附环境变量配置)

  • 默认有损压缩(自动推荐 CRF)
  • 手动指定 CRF 值
  • 无损压缩
  • 目标大小模式(指定目标文件大小,自动计算码率)

🔧 背景知识

什么是 CRF?

  • CRF (Constant Rate Factor) 是 ffmpeg 在使用 libx264libx265 编码时的一种恒定质量模式。
  • 范围:0--51
    • 0 → 无损压缩(文件极大)
    • 18--23 → 高质量(接近无损)
    • 24--28 → 中等质量(常用压缩)
    • 29+ → 低质量(极限压缩)

无损压缩

  • 使用 -crf 0(H.264)或 -x265-params lossless=1(H.265)。
  • 文件体积通常不会比原始小很多,但保证质量不丢失。

目标大小模式

  • 根据视频时长和目标大小计算码率:
    目标码率 (kbps) = 目标大小 (MB) x 8 x 1024 / 时长 (秒)
  • 使用 -b:v 设置视频码率,音频固定为 128k

📜 脚本源码:auto_compress.ps1

powershell 复制代码
param(
    [Parameter(Mandatory=$true)]
    [string]$InputFile,

    [Parameter(Mandatory=$true)]
    [string]$OutputFile,

    [Parameter(Mandatory=$false)]
    [switch]$Lossless,   # 是否启用无损压缩

    [Parameter(Mandatory=$false)]
    [int]$CRF,           # 用户可手动指定 CRF 值

    [Parameter(Mandatory=$false)]
    [int]$TargetSizeMB   # 目标大小 (MB)
)

# 检查 ffmpeg 是否可用
if (-not (Get-Command ffmpeg -ErrorAction SilentlyContinue)) {
    Write-Host "错误: 未检测到 ffmpeg,请先安装并配置到 PATH。" -ForegroundColor Red
    exit 1
}

# 获取视频信息
$info = & ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate,bit_rate,duration -of default=noprint_wrappers=1 "$InputFile"

$width   = ($info | Select-String "width="   | ForEach-Object { $_.ToString().Split("=")[1] })
$height  = ($info | Select-String "height="  | ForEach-Object { $_.ToString().Split("=")[1] })
$fpsRaw  = ($info | Select-String "r_frame_rate=" | ForEach-Object { $_.ToString().Split("=")[1] })
$bitrate = ($info | Select-String "bit_rate=" | ForEach-Object { $_.ToString().Split("=")[1] })
$duration = ($info | Select-String "duration=" | ForEach-Object { $_.ToString().Split("=")[1] })

# 计算帧率
$fpsParts = $fpsRaw -split "/"
if ($fpsParts.Count -eq 2) {
    $fps = [math]::Round([double]$fpsParts[0] / [double]$fpsParts[1], 2)
} else {
    $fps = [double]$fpsRaw
}

Write-Host "检测到视频: ${width}x${height}, ${fps}fps, 码率=${bitrate}bps, 时长=${duration}s"

# 判断压缩模式
if ($Lossless) {
    # 无损压缩
    $codec = "libx264"
    $preset = "slow"
    $extraParams = "-crf 0"
    $audioCodec = "copy"
    Write-Host "选择无损压缩: $codec $preset $extraParams, 音频=$audioCodec"
} elseif ($TargetSizeMB) {
    # 目标大小模式
    $targetBitrate = [math]::Round(($TargetSizeMB * 8 * 1024) / [double]$duration)
    Write-Host "目标大小模式: 目标=$TargetSizeMB MB, 计算码率=$targetBitrate kbps"

    $codec = "libx264"
    $preset = "slow"
    $extraParams = "-b:v ${targetBitrate}k"
    $audioCodec = "aac -b:a 128k"
    Write-Host "选择目标大小压缩: $codec $preset $extraParams, 音频=$audioCodec"
} else {
    # 有损压缩,自动推荐 CRF
    if ($CRF) {
        $chosenCRF = $CRF
        Write-Host "用户指定 CRF=$chosenCRF"
    } else {
        if ([int]$width -ge 1920 -or [int]$bitrate -ge 4000000) {
            $chosenCRF = 23
        } elseif ([int]$width -ge 1280 -or [int]$bitrate -ge 2000000) {
            $chosenCRF = 26
        } else {
            $chosenCRF = 28
        }
        Write-Host "自动推荐 CRF=$chosenCRF"
    }

    $codec = "libx264"
    $preset = "slow"
    $extraParams = "-crf $chosenCRF"
    $audioCodec = "aac -b:a 128k"
    Write-Host "选择有损压缩: $codec $preset $extraParams, 音频=$audioCodec"
}

# 执行压缩
$ffmpegCmd = "ffmpeg -i `"$InputFile`" -c:v $codec -preset $preset $extraParams -c:a $audioCodec `"$OutputFile`""
Write-Host "执行命令: $ffmpegCmd"
& cmd /c $ffmpegCmd

# 显示文件大小对比
$origSize = (Get-Item $InputFile).Length
$newSize  = (Get-Item $OutputFile).Length

Write-Host "原始大小: $([math]::Round($origSize/1MB,2)) MB"
Write-Host "压缩后大小: $([math]::Round($newSize/1MB,2)) MB" -ForegroundColor Green

🚀 使用方法

  • 默认有损压缩(自动推荐 CRF)

    powershell 复制代码
    ./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4"
  • 指定 CRF 值(例如 CRF=24,高质量)

    powershell 复制代码
    ./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4" -CRF 24
  • 无损压缩

    powershell 复制代码
    ./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4" -Lossless
  • 目标大小模式(例如目标 100MB)

    powershell 复制代码
    ./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4" -TargetSizeMB 100

📌 总结

这个脚本让你在 Windows 下用 PowerShell 一键压缩视频,支持:

  • 自动推荐 CRF 值(智能选择质量与体积平衡)
  • 手动指定 CRF 值
  • 无损压缩(保留原始质量)
  • 目标大小模式(精确控制输出文件大小)
相关推荐
知南x5 小时前
【物联网视频监控系统----韦东山老师视频总结】(4)流媒体方案的实现之Nginx
物联网·nginx·音视频
知南x5 小时前
【物联网视频监控系统----韦东山老师视频总结】(2)三种视频监控方案介绍
物联网·音视频
5Gcamera9 小时前
执法记录仪、智能安全帽、smarteye平台常见问题解答FAQ
5g·音视频·智能安全帽·执法记录仪·smarteye
熊猫钓鱼>_>12 小时前
当想象力成为生产力,AI视频生成如何重塑2026年的创作世界
人工智能·ai·aigc·音视频·提示词·ai视频
EasyCVR14 小时前
视频汇聚平台EasyCVR助力农贸市场迈向“智慧监管”新时代
音视频
小李独爱秋14 小时前
计算机网络经典问题透视:可以通过哪些方案改造互联网,使互联网能够适合于传送音频/视频数据?
运维·服务器·网络协议·计算机网络·音视频
xwz小王子14 小时前
GenMimic:让机器人从生成视频中学动作
机器人·音视频
weixin_4624462314 小时前
Python + FFmpeg 批量提取视频音频(支持 Windows / macOS / Linux)
python·ffmpeg·音视频
小李独爱秋15 小时前
计算机网络经典问题透视:流式存储、流式实况与交互式音视频的深度解析
服务器·网络协议·计算机网络·安全·音视频
非凡ghost15 小时前
GiliSoft Audio Recorder(音频录制工具)
学习·音视频·软件需求