使用PowerShell和ffmpeg编写一个自动压缩视频脚本

 更新时间:2025年12月03日 09:23:40   作者:爱宇阳  
视频文件往往体积庞大,尤其是高分辨率或高码率的视频,如果你经常需要压缩视频以便存储、传输或分享,那么手动输入 ffmpeg 命令会很繁琐,本文将教你如何编写一个 PowerShell 自动化脚本,智能选择压缩参数,需要的朋友可以参考下

引言

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

  • 默认有损压缩(自动推荐 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

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)

./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4"

指定 CRF 值(例如 CRF=24,高质量)

./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4" -CRF 24

无损压缩

./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4" -Lossless

目标大小模式(例如目标 100MB)

./auto_compress.ps1 -InputFile "input.mp4" -OutputFile "output.mp4" -TargetSizeMB 100

总结

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

  • 自动推荐 CRF 值(智能选择质量与体积平衡)
  • 手动指定 CRF 值
  • 无损压缩(保留原始质量)
  • 目标大小模式(精确控制输出文件大小)

到此这篇关于使用PowerShell和ffmpeg编写一个自动压缩视频脚本的文章就介绍到这了,更多相关PowerShell ffmpeg自动压缩视频内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

最新评论