12 KiB
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:
- Extracting frames with optional vertical padding
- Applying horizontal cropping with smooth transitions between keyframes
- Optionally overlaying a PNG image with transparency
- 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
- Named colors:
-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 ratioSquare: 1:1 aspect ratio
Height: Vertical height in pixels (default:1920). Width is computed based on formatPadding: Vertical padding position when input height < output height (default:Center)Top: All padding at topBottom: All padding at bottomCenter: Padding split evenly top and bottomNone: 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
- Named colors:
Overlay: Path to PNG file with transparency to overlay on each cropped frameAudio: Copy audio from input video (default:Yes)Yes: Include audioNo: Video only
Position: Reference point for numeric cropping offset values (default:Center)Left: Numeric values represent absolute pixel offset from left edgeCenter: 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-isUp: Extend transition by incrementing upper frame until speed limit is metCenter: Extend transition by adjusting frame closest to center until speed limit is metDown: 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 thePositionsetting in the[Clip]section (seePosition). 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:
[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:
.\Create-ShortClip.ps1 -Video input.mp4 -Plan plan.ini
# Creates: input-ShortClip.mp4 (9:16 format)
Square format with white padding:
# plan.ini
[Clip]
Format=Square
Height=1920
Padding=Center
Audio=Yes
[Cropping]
0=Center
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Color white
With overlay graphic:
.\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):
# plan.ini
[Clip]
Format=Portrait
Height=1920
Padding=None
.\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:
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Keep
# Preserves Frames/ directory for review
Re-render with different encoding:
# 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:
.\Create-ShortClip.ps1 -Video video.mp4 -Plan plan.ini -Images "C:\Output\frames\frame-%04d.png"
Custom padding color:
# 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:
# 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:
.\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:
.\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:
# 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:
# 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)
[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:
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
- Validation: Check video and plan file existence
- Analysis: Extract video metadata (dimensions, frame count, FPS, codec)
- Offset Calculation: Compute per-frame cropping offsets with interpolation and optional smoothing
- Frame Extraction: Extract all frames with vertical padding applied
- Cropping: Apply horizontal crop to each frame based on computed offsets
- Overlay (optional): Apply PNG overlay during cropping step
- Encoding: Create output video from processed frames
- Cleanup: Remove temporary directories (unless
-Keepspecified)
With
-WhatIf, the workflow shows all planned operations without executing them.
Existing Files and Folders
- Default
-Images(theFramesfolder next to the video): files directly inFramesare 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-Imagespattern are deleted before extraction. TheFramesfolder 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.
Framesfolder (default-Imagesonly): removed after the video is created, unless-Keepis given.
Notes
- Requires
ffmpegandffprobein 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
-Renderto quickly re-encode with different settings without reprocessing frames - Use
-WhatIfto preview the full workflow (cropping offsets, frame operations, video creation) before committing to a full run - Use
-Confirmto be prompted before each state-changing operation Smoothingonly takes effect when the interpolated speed between two keyframes exceeds theSpeedlimit; otherwise offsets are used unchanged