# Crop-Clips.ps1 Batch crop videos generated by **LTX-2**, **Kling** and **Wan** to standard resolutions using ffmpeg. Every non-standard resolution these generators produce is recognised by a single lookup table in the script, so one command handles a folder containing clips from any of them. Resolutions are unique per generator, so there is no ambiguity. Any resolution not listed below is skipped without modification. Use `-Size` to ignore the table and convert every video to a specific resolution instead — see [Forcing a Size](#forcing-a-size). ## Parameters - **`-Source`** (optional): Source directory containing video files (default: current directory) - **`-Target`** (optional): Target directory for cropped videos (default: current directory) - **`-Size`** (optional): Output video size. Possible values: `320p`, `384p`, `480p`, `720p`, `900p`, `1080p`, `HD`, `1440p`, `2K`, `2160p`, `4K`, or a custom `width:height`. When specified it **overrides the resolution table** and converts every video to that size — see [Forcing a Size](#forcing-a-size). Without it, the table below is used. ## Supported Resolutions ### LTX-2 **Landscape:** - **3744x2112** → **3840x2160**: Scale up to 3840 width, then vertical center crop - **2496x1408** → **2560x1440**: Scale up to 2560 width, then vertical center crop - **2160x1216** → **1920x1080**: Scale down to 1920 width, then vertical center crop - **1920x1088** → **1920x1080**: Center crop (removes 4px from top and bottom) - **1920x1056** → **1920x1080**: Scale up to 1080 height, then horizontal center crop - **1872x1056** → **1920x1080**: Scale up to 1920 width, then vertical center crop - **1600x896** → **1600x900**: Scale to 900 height, then center crop - **1312x704** → **1280x720**: Scale up to 720 height, then horizontal center crop - **1280x704** → **1280x720**: Scale to 720 height, then center crop - **1248x704** → **1280x720**: Scale up to 1280 width, then vertical center crop - **832x448** → **854x480**: Scale to 480 height, then center crop - **640x384** → **684x384**: Scale to 684 width, then center crop - **576x320** → **570x320**: Center crop (removes 3px from left and right) **Portrait:** - **2112x3744** → **2160x3840**: Scale up to 3840 height, then horizontal center crop - **1408x2496** → **1440x2560**: Scale up to 2560 height, then horizontal center crop - **1216x2160** → **1080x1920**: Scale down to 1920 height, then horizontal center crop - **1088x1920** → **1080x1920**: Center crop (removes 4px from left and right) - **1056x1920** → **1080x1920**: Scale up to 1080 width, then vertical center crop - **1056x1872** → **1080x1920**: Scale up to 1920 height, then horizontal center crop - **896x1600** → **900x1600**: Scale to 900 width, then center crop - **704x1312** → **720x1280**: Scale up to 720 width, then vertical center crop - **704x1280** → **720x1280**: Scale to 720 width, then center crop - **704x1248** → **720x1280**: Scale up to 1280 height, then horizontal center crop - **448x832** → **480x854**: Scale to 480 width, then center crop - **384x640** → **384x684**: Scale to 684 height, then center crop - **320x576** → **320x570**: Center crop (removes 3px from top and bottom) ### Kling - **1928x1072** → **1920x1080**: Scale to 1080 height, then center crop width to 1920 - **1920x1076** → **1920x1080**: Scale to 1080 height, then center crop width to 1920 - **1920x1072** → **1920x1080**: Scale to 1080 height, then center crop width to 1920 - **1916x1080** → **1920x1080**: Already 1080 tall, so the 4 missing columns are padded (centered) instead of rescaling ### Wan - **1928x1076** → **1920x1080**: Scale to 1080 height, then center crop width to 1920 - **1926x1076** → **1920x1080**: Scale to 1080 height, then center crop width to 1920 - **1284x716** → **1280x720**: Scale to 720 height, then center crop width to 1280 ### Square (1:1) - **NxN** → **1080x1080**: Any square resolution other than 1080x1080 is scaled up or down to 1080x1080 (no crop needed) ## Forcing a Size `-Size` bypasses the resolution table entirely. Every video is **cover-scaled** (`force_original_aspect_ratio=increase`, which preserves the pixel aspect ratio and guarantees the frame is fully covered) and then **centre-cropped** to the exact requested size — the same approach as [Clone-Image.ps1](Clone-Image.md). Because the table is not consulted, resolutions that would normally be skipped are converted too. ### Presets Named presets are the landscape targets this script already produces: | Preset | Size | Preset | Size | | --- | --- | --- | --- | | `320p` | 570x320 | `1080p` / `HD` | 1920x1080 | | `384p` | 684x384 | `1440p` / `2K` | 2560x1440 | | `480p` | 854x480 | `2160p` / `4K` | 3840x2160 | | `720p` | 1280x720 | | | | `900p` | 1600x900 | | | Preset names are case-insensitive (`-Size hd` works). ### Portrait sources Presets are **transposed for portrait sources**, so a 9:16 clip stays 9:16 instead of losing most of the frame to a landscape crop: | Source | `-Size 1080p` | `-Size 720p` | | --- | --- | --- | | 1920x1088 (landscape) | 1920x1080 | 1280x720 | | 640x480 (landscape) | 1920x1080 | 1280x720 | | 512x512 (square) | 1920x1080 | 1280x720 | | 1080x1920 (portrait) | 1080x1920 *(already — skipped)* | 720x1280 | | 720x1280 (portrait) | 1080x1920 | 720x1280 *(already — skipped)* | A custom `width:height` is **always used exactly as given** (never transposed), so `-Size 1080:1920` forces portrait output for every video, landscape sources included. Odd custom dimensions are rounded up to the next even number, as `libx264`/`yuv420p` requires even sizes (`-Size 571:321` becomes 572x322). ### Already-correct videos A video that is already exactly the requested size is left untouched — no re-encode, no generation loss: ```text Skipping: 1920x1080.mp4 (already 1920x1080) ``` An invalid `-Size` value fails immediately, before any file is processed. ## Behavior - Processes all `.mp4` files in source directory - Skips files ending with `.bak.mp4` or `.skip.mp4` - Automatically detects resolution and applies appropriate crop filter (or uses `-Size` when given) - Preserves original quality and audio - **In-place mode** (source and target are the same directory). This is the default when `-Source` and `-Target` are both omitted, because both default to the current directory: - Each original `video.mp4` is copied to `video.bak.mp4`. An existing `.bak.mp4` is replaced. - Only files that are cropped are backed up. A file that is skipped, because it is already at the requested size or its resolution is not in the table, keeps its existing `.bak.mp4`. Re-running in place without `-Size` skips the files it already cropped, so the backup stays the original. A re-run with a different `-Size` crops them again, and replaces the backup with the first run's output. Keep your own copy of the originals before a re-run with a different `-Size`, or use a separate `-Target` folder. - The cropped result is written to `video.crop.mp4`. Only after that succeeds is the original `video.mp4` deleted and replaced by the cropped file. The `.bak.mp4` backup is kept. - Run with `-WhatIf` first, and do not run it on a folder you have not designated. - **Separate target folder**: the source files are not changed. A file with the same name already in the target folder is deleted and replaced. - If ffmpeg fails, the partial `.crop.mp4` file is deleted and the script stops with an error ## Examples **Crop videos in current directory:** ```powershell .\Crop-Clips.ps1 ``` **Crop videos from specific source:** ```powershell .\Crop-Clips.ps1 -Source "C:\Videos\Input" ``` **Crop to different target directory:** ```powershell .\Crop-Clips.ps1 -Source "C:\Videos\Input" -Target "C:\Videos\Output" ``` **Force every video to 1080p (table ignored):** ```powershell .\Crop-Clips.ps1 -Source "C:\Videos\Input" -Size 1080p # Landscape clips -> 1920x1080, portrait clips -> 1080x1920 ``` **Force a small preset:** ```powershell .\Crop-Clips.ps1 -Size 480p # Landscape clips -> 854x480, portrait clips -> 480x854 ``` **Force a custom size (used verbatim, never transposed):** ```powershell .\Crop-Clips.ps1 -Size "1080:1920" # Every video becomes 1080x1920, landscape sources included ``` **Skip specific files:** ```powershell # Rename files to skip processing: # video.mp4 -> video.skip.mp4 .\Crop-Clips.ps1 ``` ## Safe Execution This script supports `-WhatIf` and `-Confirm` for safe execution: - **`-WhatIf`**: Simulate the operation without actually modifying files. Shows what would be cropped. - **`-Confirm`**: Prompt for confirmation before processing each video file. **Simulate without making changes:** ```powershell .\Crop-Clips.ps1 -Source "C:\Videos\Input" -Target "C:\Videos\Output" -WhatIf ``` **Prompt before each file:** ```powershell .\Crop-Clips.ps1 -Source "C:\Videos\Input" -Confirm ```