使用 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 值
  • 无损压缩(保留原始质量)
  • 目标大小模式(精确控制输出文件大小)
相关推荐
CoookeCola20 分钟前
M.I.O: Interactive Intelligence for Digital Humans(交互式智能数字人)
论文阅读·人工智能·aigc·音视频
Lueeee.26 分钟前
FFMPEG核心结构体
linux·ffmpeg
特立独行的猫a3 小时前
鸿蒙PC三方库移植:x264视频编码库的移植适配实践
华为·音视频·harmonyos·三方库移植·鸿蒙pc
HyperAI超神经3 小时前
入选NeurIPS 2025,智源/北大/北邮提出多流控制视频生成框架,基于音频解混实现精确音画同步
人工智能·ai·音视频·视频生成·neurlps 2025
be or not to be13 小时前
HTML入门系列:从图片到表单,再到音视频的完整实践
前端·html·音视频
LCG米14 小时前
基于ESP32-S3与OV5640的高清低延迟无线视频传输系统构建教程
音视频
Angelina_Jolie15 小时前
基于 Retinex 的 TempRetinex:适用于不同光照条件下低光视频的无监督增强方法
计算机视觉·音视频
源之缘-专注WPF开发18 小时前
全栈开发实战:WPF+FFmpeg+GIS,打造工业级雷达探测终端
ffmpeg·wpf·gis
山海青风18 小时前
藏文TTS介绍:6 MMS 项目的多语言 TTS
人工智能·python·神经网络·音视频
Everbrilliant891 天前
FFmpeg解码OpenSL、ANativeWindow播放实现音视频同步
ffmpeg·音视频·opensl音视频同步播放·音视频同步播放·唇音同步·音视频时钟漂移·播放时钟同步