Created
December 1, 2025 00:53
-
-
Save Mrfiregem/9f5bafe0ac8da8708934af90701e210a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env nu | |
| # Round the input down to the nearest multiple of a given divisor | |
| def 'round down' [divisor: number = 10]: number -> number { $in - ($in mod $divisor) } | |
| def main []: nothing -> nothing { | |
| help main | |
| } | |
| # Use two-pass encoding to compress a video to a certain filesize | |
| def 'main compress' [ | |
| --target-size(-s): filesize = 10MB # The target size of the output | |
| --in-place(-i) # Replace the original input file | |
| --audio-bitrate(-a): int = 128 # Audio bitrate in kBit | |
| file: path # The original video file | |
| output?: path # An optional output path (default: '{name}_{size}.{ext}') | |
| ]: nothing -> nothing { | |
| # Get the length of the input video in seconds | |
| let video_duration_sec = ^ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $file | |
| | into float | |
| # Convert the user's given filesize to kBits | |
| let target_size_kbit = $target_size | into int # Convert to bytes | |
| | $in * 8 # Convert bytes to bits | |
| | $in / 1000.0 # Convert bits to kBit | |
| | round down # Round the number down so it's just below the target for extra leeway | |
| # Calculate the bitrate needed to get close to the filesize | |
| let target_bitrate = $'($target_size_kbit / $video_duration_sec | $in - $audio_bitrate)k' | |
| # Determine where to save the compressed file to | |
| let output_path = if $in_place { | |
| mktemp -t --suffix mp4 | |
| } else if $output != null { | |
| $output | |
| } else { | |
| $file | |
| | path parse | |
| | update stem { append ($target_size | into string | str replace -a ' ' '') | str join '_' } | |
| | path join | |
| } | |
| # Compress the video using the calculated bitrate | |
| ^ffmpeg -y -i $file -c:v libx264 -b:v $target_bitrate -pass 1 -an -f 'null' /dev/null | |
| ^ffmpeg -i $file -c:v libx264 -b:v $target_bitrate -pass 2 -c:a aac -b:a $'($audio_bitrate)k' $output_path | |
| # Overwrite original file if desired | |
| if $in_place { | |
| mv --force $output_path $file | |
| } | |
| # Cleanup ffmpeg log files | |
| glob 'ffmpeg2pass-*.log*' | |
| | if $in != [] { rm ...$in } | |
| } | |
| # Scale a given video to a specific size or ratio | |
| def 'main scale' [ | |
| --in-place(-i) # Replace the original input file | |
| --width(-w): int = 480 # The width the video should be scaled to | |
| --height(-h): int = -2 # The height the video should be scaled to | |
| file: path # The original video file | |
| output?: path # An optional output path (default: '{name}_{scale}.{ext}') | |
| ]: nothing -> nothing { | |
| # Construct the scale string ('{width}:{height}') | |
| let scale_str = [$width, $height] | str join ':' | |
| # Determine where to save the compressed file to | |
| let output_path = if $in_place { | |
| mktemp -t --suffix mp4 | |
| } else if $output != null { | |
| $output | |
| } else { | |
| $file | |
| | path parse | |
| | update stem { append ($scale_str | str replace ':' 'x') | str join '_' } | |
| | path join | |
| } | |
| # Scale the input video to the given dimensions | |
| ^ffmpeg -i $file -vf $'scale=($scale_str)' $output_path | |
| # Overwrite original file if desired | |
| if $in_place { | |
| mv --force $output_path $file | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment