Files
Video-Processing-Scripts/video-processing-scripts/Create-ShortClip.md
T

347 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Create-ShortClip.ps1
Creates a short clip video file from a 16:9 video file with dynamic cropping, padding, and optional overlay.
## Synopsis
Transforms landscape videos into portrait (9:16) or square (1:1) format clips by:
1. Extracting frames with optional vertical padding
2. Applying horizontal cropping with smooth transitions between keyframes
3. Optionally overlaying a PNG image with transparency
4. Encoding the final video with preserved quality settings
The output filename is automatically generated by appending `-ShortClip` before the file extension.
## Parameters
- **`-Video`** (required): Path to input video file (absolute or relative)
- **`-Plan`** (required): Path to INI plan file defining clip specifications and cropping behavior
- **`-Images`** (optional): Path to output PNG images file pattern. If not provided, frames are saved in subdirectory 'Frames' with video filename and 4-digit frame numbers
- **`-Keep`**: Preserve temporary and frames directories after processing
- **`-Render`**: Skip frame extraction/cropping and only create video from existing frames
- **`-Color`** (optional): Override INI file Color value for padding color name or RGB value (default: `black`)
- Named colors: `black`, `white`, `red`, `blue`, etc.
- Hex format: `#RRGGBB` (e.g., `#1a1a1a`)
- FFmpeg format: `0xRRGGBB`
- **`-Overlay`** (optional): Override INI file Overlay value for path to PNG file with transparency to overlay on each cropped frame
- **`-Smoothing`** (optional): Override INI file Smoothing value (`None`, `Up`, `Center`, `Down`)
- **`-Speed`** (optional): Override INI file Speed value (minimum: 1)
- **`-WhatIf`**: Simulate the operation without actually creating files. Shows what would be done.
- **`-Confirm`**: Prompt for confirmation before each state-changing operation (frame extraction, cropping, video creation).
## Plan File Format (INI)
### [Clip] Section
Defines output video specifications:
- **`Format`**: Output aspect ratio (default: `Portrait`)
- `Portrait`: 9:16 aspect ratio
- `Square`: 1:1 aspect ratio
- **`Height`**: Vertical height in pixels (default: `1920`). Width is computed based on format
- **`Padding`**: Vertical padding position when input height < output height (default: `Center`)
- `Top`: All padding at top
- `Bottom`: All padding at bottom
- `Center`: Padding split evenly top and bottom
- `None`: No padding; scale video to fill output height and crop horizontally to match format width
- **'Color'**: Padding color name or RGB value (default: `black`)
- Named colors: `black`, `white`, `red`, `blue`, etc.
- Hex format: `#RRGGBB` (e.g., `#1a1a1a`)
- FFmpeg format: `0xRRGGBB`
- **`Overlay`**: Path to PNG file with transparency to overlay on each cropped frame
- **`Audio`**: Copy audio from input video (default: `Yes`)
- `Yes`: Include audio
- `No`: Video only
- **`Position`**: Reference point for numeric cropping offset values (default: `Center`)
- `Left`: Numeric values represent absolute pixel offset from left edge
- `Center`: Numeric values represent pixel offset from center (value - output_width/2)
- `Right`: Numeric values represent pixel offset from right edge (value - output_width)
- **`Smoothing`**: Mode for adjusting cropping transition length to control speed (default: `None`)
- `None`: No smoothing, use calculated interpolation as-is
- `Up`: Extend transition by incrementing upper frame until speed limit is met
- `Center`: Extend transition by adjusting frame closest to center until speed limit is met
- `Down`: Extend transition by decrementing lower frame until speed limit is met
- **`Speed`**: Maximum cropping transition speed in pixels per frame (default: `10`, minimum: `1`)
- Controls how fast the crop position can change between frames
- If interpolated speed exceeds this value, smoothing extends the transition
### [Cropping] Section
Defines horizontal cropping keyframes with automatic interpolation:
**Format:** `frame_number=position`
**Position values:**
Each keyframe value is resolved to a **Left offset**: the X coordinate (in input-frame pixels) of the left edge of the crop window. The crop window has width `output_width` (or the intermediate width when downscaling).
- `Left`: Crop from left edge (Left offset = 0)
- `Center`: Crop from center (Left offset = (input_width - output_width) / 2)
- `Right`: Crop from right edge (Left offset = input_width - output_width)
- `number`: Absolute pixel offset, interpreted according to the `Position` setting in the `[Clip]` section (see `Position`). Result is clamped to `[0, input_width - output_width]`.
From the Left offset, the script also derives:
- **Center offset** = Left offset + output_width / 2 (X coordinate of the crop window's center)
- **Right offset** = Left offset + output_width (X coordinate of the crop window's right edge)
All three values are printed in the cropping offsets table at runtime to help diagnose framing.
**Behavior:**
- Frame numbers must be in ascending order
- Intermediate frames are automatically interpolated with smooth transitions
- Frames after the last keyframe use the last defined offset
- If section is empty or missing, defaults to `0=Center`
**Example:**
```ini
[Cropping]
0=Left
84=Left
85=Right
140=Right
159=Left
```
This creates:
- Frames 0-84: Crop from left
- Frame 84→85: Quick transition from left to right
- Frames 85-140: Crop from right
- Frames 140-159: Smooth pan from right to left
- Frames 159+: Crop from left
## Examples
**Basic portrait clip:**
```powershell
.\Create-ShortClip.ps1 -Video input.mp4 -Plan plan.ini
# Creates: input-ShortClip.mp4 (9:16 format)
```
**Square format with white padding:**
```ini
# plan.ini
[Clip]
Format=Square
Height=1920
Padding=Center
Audio=Yes
[Cropping]
0=Center
```
```powershell
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Color white
```
**With overlay graphic:**
```powershell
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Overlay border.png
# Applies border.png (with transparency) over each cropped frame
```
**No padding (scale to fill height):**
```ini
# plan.ini
[Clip]
Format=Portrait
Height=1920
Padding=None
```
```powershell
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini
# Scales video to fill 1920px height, crops horizontally to 1080px width
# No vertical padding bars added
```
**Keep frames for inspection:**
```powershell
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Keep
# Preserves Frames/ directory for review
```
**Re-render with different encoding:**
```powershell
# First run: extract and crop frames
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Keep
# Modify encoding settings in script, then re-render
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Render
# Skips extraction/cropping, only creates video from existing frames
```
**Custom output location:**
```powershell
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Images "C:\Output\frames\frame-%04d.png"
```
**Custom padding color:**
```powershell
# Dark gray padding
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Color #1a1a1a
# Navy blue padding
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Color navy
```
**Position parameter with numeric values:**
```ini
# plan.ini - Input: 1920x1088, Output: 1080x1920
[Clip]
Format=Portrait
Position=Center
[Cropping]
0=960
```
With `Position=Center` and output width 1080:
- Numeric value 960 is adjusted: 960 - (1080/2) = 960 - 540 = 420
- Final offset: 420 pixels from left edge (centered in 1920px input)
With `Position=Left`:
- Numeric value 960 is used directly: 960 pixels from left edge
With `Position=Right` and output width 1080:
- Numeric value 960 is adjusted: 960 - 1080 = -120 → clamped to 0
**Simulate without making changes:**
```powershell
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -WhatIf
# Displays what would be done (cropping offsets, frame extraction, video creation) without actually processing
```
**Prompt before each operation:**
```powershell
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Confirm
# Will prompt for confirmation before frame extraction, each cropping operation, and video creation
```
**Smoothing fast transitions:**
```ini
# plan.ini - Control transition speed
[Clip]
Format=Portrait
Smoothing=Center
Speed=5
[Cropping]
0=Left
10=Right
```
Without smoothing, frames 0-10 would transition at 84 pixels/frame (too fast).
With `Smoothing=Center` and `Speed=5`, the transition extends to more frames, keeping speed ≤ 5 pixels/frame.
**Override INI settings via command-line:**
```powershell
# Override smoothing settings from command line
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Smoothing Up -Speed 3
# Uses Up smoothing and speed limit of 3, ignoring INI file values
```
## Cropping Interpolation Example
Input: 1920x1088 video → Output: 1080x1920 (Portrait)
```ini
[Cropping]
0=Left
10=200
50=Center
91=Right
```
**Calculated Left offsets:**
- **Frame 0**: 0 (Left)
- **Frames 1-9**: Linear interpolation from 0 to 200
- Frame 1: 20, Frame 2: 40, ..., Frame 9: 180
- **Frame 10**: 200
- **Frames 11-49**: Linear interpolation from 200 to 420 (Center = (1920-1080)/2)
- Frame 11: 194.5, Frame 12: 189, ..., Frame 49: 425.5
- **Frame 50**: 420 (Center)
- **Frames 51-90**: Linear interpolation from 420 to 840 (Right = 1920-1080)
- Frame 51: 430.5, Frame 52: 441, ..., Frame 90: 829.5
- **Frame 91**: 840 (Right)
- **Frames 92+**: 840 (last known value)
All fractional values are rounded to nearest pixel.
**Runtime output** prints Left, Center (= Left + 540), and Right (= Left + 1080) offsets only at frames where the Left offset changes:
```text
Frame Left Center Right
----------------------------------------
0 0 540 1080
1 20 560 1100
2 40 580 1120
...
10 200 740 1280
...
50 420 960 1500
...
91 840 1380 1920
```
## Quality Preservation
The script automatically preserves video quality from the input:
- Detects and uses same codec (H.264 → libx264, H.265 → libx265)
- Preserves pixel format
- Uses input bitrate when available
- Falls back to CRF 8 (near-lossless) for VBR/CRF-encoded inputs
- Audio encoded as AAC at 192k bitrate
## Processing Workflow
1. **Validation**: Check video and plan file existence
2. **Analysis**: Extract video metadata (dimensions, frame count, FPS, codec)
3. **Offset Calculation**: Compute per-frame cropping offsets with interpolation and optional smoothing
4. **Frame Extraction**: Extract all frames with vertical padding applied
5. **Cropping**: Apply horizontal crop to each frame based on computed offsets
6. **Overlay** (optional): Apply PNG overlay during cropping step
7. **Encoding**: Create output video from processed frames
8. **Cleanup**: Remove temporary directories (unless `-Keep` specified)
> With `-WhatIf`, the workflow shows all planned operations without executing them.
## Existing Files and Folders
- **Default `-Images`** (the `Frames` folder next to the video): files directly in `Frames` are deleted before extraction. Subfolders are not touched. With `-Render`, nothing is deleted, because the existing frames are the input.
- **Explicit `-Images`**: existing frames that match the `-Images` pattern are deleted before extraction. The `Frames` folder is not used or deleted.
- **Output video**: an existing file at the output path is overwritten.
- **Temporary extraction directory** (in the system temporary folder): always removed when the run ends.
- **`Frames` folder** (default `-Images` only): removed after the video is created, unless `-Keep` is given.
## Notes
- Requires `ffmpeg` and `ffprobe` in system PATH
- Frame numbers in INI file are 0-based
- Overlay PNG should match output dimensions (width × height)
- Transparent areas in overlay allow video content to show through
- Use `-Render` to quickly re-encode with different settings without reprocessing frames
- Use `-WhatIf` to preview the full workflow (cropping offsets, frame operations, video creation) before committing to a full run
- Use `-Confirm` to be prompted before each state-changing operation
- `Smoothing` only takes effect when the interpolated speed between two keyframes exceeds the `Speed` limit; otherwise offsets are used unchanged