Refactor Crop-Clips.ps1 to use table-driven crop profiles for LTX-2, Kling and Wan resolutions, add -Vertical parameter to Create-PillarBox.ps1 for 9:16 portrait output from square sources with horizontal bars, update Resolve-Size to check both dimensions when selecting presets and transpose named sizes in portrait mode, and update README to reflect consolidated cropping functionality
This commit is contained in:
1 parent
274dac5786
commit
b823259ab1
3 files changed
+111
-86
No files matched your search
+55
-67
@@ -6,7 +6,9 @@
|
||||
.PARAMETER Target
|
||||
Target directory for cropped video files.
|
||||
.DESCRIPTION
|
||||
Crops video clips using ffmpeg.
|
||||
Crops video clips to standard resolutions using ffmpeg. Handles the non-standard resolutions
|
||||
produced by LTX-2, Kling and Wan (see the $cropProfiles table), plus any square (1:1) source,
|
||||
which is scaled to 1080x1080. Videos with any other resolution are skipped.
|
||||
Supports -WhatIf and -Confirm for safe execution.
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
@@ -83,6 +85,50 @@ function Format-Quality {
|
||||
return "${kbps}kbps"
|
||||
}
|
||||
|
||||
# Known non-standard generator resolutions and the ffmpeg filter that brings each one
|
||||
# back to a standard size. Resolutions are unique across all generators, so a single
|
||||
# lookup is unambiguous. Any resolution not listed here is skipped, except square
|
||||
# sources, which are handled by a generic rule in the loop below.
|
||||
$cropProfiles = @(
|
||||
# LTX-2 landscape
|
||||
@{ Width = 1920; Height = 1088; Filter = 'crop=1920:1080:0:4' }
|
||||
@{ Width = 1280; Height = 704; Filter = 'scale=-2:720,crop=1280:720:(in_w-1280)/2:(in_h-720)/2' }
|
||||
@{ Width = 1600; Height = 896; Filter = 'scale=-2:900,crop=1600:900:(in_w-1600)/2:(in_h-900)/2' }
|
||||
@{ Width = 832; Height = 448; Filter = 'scale=-2:480,crop=854:480:(in_w-854)/2:(in_h-480)/2' }
|
||||
@{ Width = 640; Height = 384; Filter = 'scale=684:-2,crop=684:384:(in_w-684)/2:(in_h-384)/2' }
|
||||
@{ Width = 576; Height = 320; Filter = 'crop=570:320:3:0' }
|
||||
@{ Width = 3744; Height = 2112; Filter = 'scale=3840:-2,crop=3840:2160:0:(in_h-2160)/2' }
|
||||
@{ Width = 2496; Height = 1408; Filter = 'scale=2560:-2,crop=2560:1440:0:(in_h-1440)/2' }
|
||||
@{ Width = 2160; Height = 1216; Filter = 'scale=1920:-2,crop=1920:1080:0:(in_h-1080)/2' }
|
||||
@{ Width = 1872; Height = 1056; Filter = 'scale=1920:-2,crop=1920:1080:0:(in_h-1080)/2' }
|
||||
@{ Width = 1248; Height = 704; Filter = 'scale=1280:-2,crop=1280:720:0:(in_h-720)/2' }
|
||||
|
||||
# LTX-2 portrait
|
||||
@{ Width = 1088; Height = 1920; Filter = 'crop=1080:1920:4:0' }
|
||||
@{ Width = 704; Height = 1280; Filter = 'scale=720:-2,crop=720:1280:(in_w-720)/2:(in_h-1280)/2' }
|
||||
@{ Width = 896; Height = 1600; Filter = 'scale=900:-2,crop=900:1600:(in_w-900)/2:(in_h-1600)/2' }
|
||||
@{ Width = 448; Height = 832; Filter = 'scale=480:-2,crop=480:854:(in_w-480)/2:(in_h-854)/2' }
|
||||
@{ Width = 384; Height = 640; Filter = 'scale=-2:684,crop=384:684:(in_w-384)/2:(in_h-684)/2' }
|
||||
@{ Width = 320; Height = 576; Filter = 'crop=320:570:0:3' }
|
||||
@{ Width = 2112; Height = 3744; Filter = 'scale=-2:3840,crop=2160:3840:(in_w-2160)/2:0' }
|
||||
@{ Width = 1408; Height = 2496; Filter = 'scale=-2:2560,crop=1440:2560:(in_w-1440)/2:0' }
|
||||
@{ Width = 1216; Height = 2160; Filter = 'scale=-2:1920,crop=1080:1920:(in_w-1080)/2:0' }
|
||||
@{ Width = 1056; Height = 1872; Filter = 'scale=-2:1920,crop=1080:1920:(in_w-1080)/2:0' }
|
||||
@{ Width = 704; Height = 1248; Filter = 'scale=-2:1280,crop=720:1280:(in_w-720)/2:0' }
|
||||
|
||||
# Kling
|
||||
@{ Width = 1920; Height = 1072; Filter = 'scale=-2:1080,crop=1920:1080:(in_w-1920)/2:(in_h-1080)/2' }
|
||||
@{ Width = 1928; Height = 1072; Filter = 'scale=-2:1080,crop=1920:1080:(in_w-1920)/2:(in_h-1080)/2' }
|
||||
@{ Width = 1920; Height = 1076; Filter = 'scale=-2:1080,crop=1920:1080:(in_w-1920)/2:(in_h-1080)/2' }
|
||||
# 1916x1080 is already 1080 tall: pad the missing 4 columns instead of rescaling.
|
||||
@{ Width = 1916; Height = 1080; Filter = 'pad=1920:1082:2:1:black,crop=1920:1080:0:1' }
|
||||
|
||||
# Wan
|
||||
@{ Width = 1928; Height = 1076; Filter = 'scale=-2:1080,crop=1920:1080:(in_w-1920)/2:(in_h-1080)/2' }
|
||||
@{ Width = 1926; Height = 1076; Filter = 'scale=-2:1080,crop=1920:1080:(in_w-1920)/2:(in_h-1080)/2' }
|
||||
@{ Width = 1284; Height = 716; Filter = 'scale=-2:720,crop=1280:720:(in_w-1280)/2:(in_h-720)/2' }
|
||||
)
|
||||
|
||||
$sourceFull = (Resolve-Path -LiteralPath $Source).Path
|
||||
$targetFull = (Resolve-Path -LiteralPath $Target).Path
|
||||
|
||||
@@ -112,76 +158,18 @@ foreach ($video in $videos) {
|
||||
$inQuality = Format-Quality -BitRate $inInfo.BitRate
|
||||
$inAudioText = if ($inInfo.HasAudio) { 'yes' } else { 'no' }
|
||||
|
||||
$vf = $null
|
||||
if ($inInfo.Width -eq 1920 -and $inInfo.Height -eq 1088) {
|
||||
$vf = 'crop=1920:1080:0:4'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1280 -and $inInfo.Height -eq 704) {
|
||||
$vf = 'scale=-2:720,crop=1280:720:(in_w-1280)/2:(in_h-720)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1088 -and $inInfo.Height -eq 1920) {
|
||||
$vf = 'crop=1080:1920:4:0'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 704 -and $inInfo.Height -eq 1280) {
|
||||
$vf = 'scale=720:-2,crop=720:1280:(in_w-720)/2:(in_h-1280)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 832 -and $inInfo.Height -eq 448) {
|
||||
$vf = 'scale=-2:480,crop=854:480:(in_w-854)/2:(in_h-480)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 448 -and $inInfo.Height -eq 832) {
|
||||
$vf = 'scale=480:-2,crop=480:854:(in_w-480)/2:(in_h-854)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1600 -and $inInfo.Height -eq 896) {
|
||||
$vf = 'scale=-2:900,crop=1600:900:(in_w-1600)/2:(in_h-900)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 640 -and $inInfo.Height -eq 384) {
|
||||
$vf = 'scale=684:-2,crop=684:384:(in_w-684)/2:(in_h-384)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 576 -and $inInfo.Height -eq 320) {
|
||||
$vf = 'crop=570:320:3:0'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 896 -and $inInfo.Height -eq 1600) {
|
||||
$vf = 'scale=900:-2,crop=900:1600:(in_w-900)/2:(in_h-1600)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 384 -and $inInfo.Height -eq 640) {
|
||||
$vf = 'scale=-2:684,crop=384:684:(in_w-384)/2:(in_h-684)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 320 -and $inInfo.Height -eq 576) {
|
||||
$vf = 'crop=320:570:0:3'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1248 -and $inInfo.Height -eq 704) {
|
||||
$vf = 'scale=1280:-2,crop=1280:720:0:(in_h-720)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1872 -and $inInfo.Height -eq 1056) {
|
||||
$vf = 'scale=1920:-2,crop=1920:1080:0:(in_h-1080)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 2160 -and $inInfo.Height -eq 1216) {
|
||||
$vf = 'scale=1920:-2,crop=1920:1080:0:(in_h-1080)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 2496 -and $inInfo.Height -eq 1408) {
|
||||
$vf = 'scale=2560:-2,crop=2560:1440:0:(in_h-1440)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 3744 -and $inInfo.Height -eq 2112) {
|
||||
$vf = 'scale=3840:-2,crop=3840:2160:0:(in_h-2160)/2'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 704 -and $inInfo.Height -eq 1248) {
|
||||
$vf = 'scale=-2:1280,crop=720:1280:(in_w-720)/2:0'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1056 -and $inInfo.Height -eq 1872) {
|
||||
$vf = 'scale=-2:1920,crop=1080:1920:(in_w-1080)/2:0'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1216 -and $inInfo.Height -eq 2160) {
|
||||
$vf = 'scale=-2:1920,crop=1080:1920:(in_w-1080)/2:0'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 1408 -and $inInfo.Height -eq 2496) {
|
||||
$vf = 'scale=-2:2560,crop=1440:2560:(in_w-1440)/2:0'
|
||||
}
|
||||
elseif ($inInfo.Width -eq 2112 -and $inInfo.Height -eq 3744) {
|
||||
$vf = 'scale=-2:3840,crop=2160:3840:(in_w-2160)/2:0'
|
||||
$cropProfile = $cropProfiles | Where-Object { $_.Width -eq $inInfo.Width -and $_.Height -eq $inInfo.Height } | Select-Object -First 1
|
||||
|
||||
if ($cropProfile) {
|
||||
$vf = $cropProfile.Filter
|
||||
}
|
||||
elseif ($inInfo.Width -eq $inInfo.Height -and $inInfo.Width -ne 1080) {
|
||||
# Any square (1:1) source other than 1080x1080 is scaled to 1080x1080; no crop needed.
|
||||
$vf = 'scale=1080:1080'
|
||||
}
|
||||
else {
|
||||
$vf = $null
|
||||
}
|
||||
|
||||
if (-not $vf) {
|
||||
Write-Host "Skipping: $($inInfo.FileName) (resolution $inRes)"
|
||||
|
||||
Reference in new issue
Block a user