I'm gonna call this one Mastodon-related because basically any other method of getting a given video clip below the file limit (40MB, in mastodon.social's case,) drives me crazy. #shortcuts #video #automation #mac https://routinehub.co/shortcut/14270
- [Mastodon](https://mastodon.social/@DavidBlue/109872079917980053)
- [Telegram](https://t.me/extratone/13627)
---
## Re-encode video files to a specific size target with ffmpeg.
**Please note**: this shortcut is macOS-only.
### Requirements
- [**ffmpeg**](https://ffmpeg.org) (`brew install ffmpeg`)
This shortcut re-encodes single inputted video files to a **specified file size target** (in MB, per run) with [**ffmpeg**](https://ffmpeg.org), which it will then save to a new .mp4 file entitled `[source filename]-[provided file size]MB.mp4` in a directory of your choosing via a [Save File action](https://www.matthewcassinelli.com/actions/save-file).
### Installation
At install, you will be asked to specify:
1. The default source prompt for the shortcut (`Photos` will ask you for a video file from iCloud Photos while `Files` will use a standard Finder prompt.)
2. Whether or not you'd like the `Delete Immediately` option in the [Delete Files](https://matthewcassinelli.com/actions/delete-files/) action toggled on by default. This action is handling a (frankly, completely redundant) file - neither the source file nor the output from the Save File action will be deleted.
### Source
- [Original Stack Overflow answer](https://stackoverflow.com/a/61146975/14383008) (whoo!)
- [Script Gist](https://gist.github.com/extratone/4e9ffa59994ca32aaba3666c2031d9b1)
```bash
#!/bin/bash
#
# Re-encode a video to a target size in MB.
# Example:
# ./this_script.sh video.mp4 15
T_SIZE="$2" # target size in MB
T_FILE="${1%.*}-$2MB.mp4" # filename out
# Original duration in seconds
O_DUR=$(\
ffprobe \
-v error \
-show_entries format=duration \
-of csv=p=0 "$1")
# Original audio rate
O_ARATE=$(\
ffprobe \
-v error \
-select_streams a:0 \
-show_entries stream=bit_rate \
-of csv=p=0 "$1")
# Original audio rate in KiB/s
O_ARATE=$(\
awk \
-v arate="$O_ARATE" \
'BEGIN { printf "%.0f", (arate / 1024) }')
# Target size is required to be less than the size of the original audio stream
T_MINSIZE=$(\
awk \
-v arate="$O_ARATE" \
-v duration="$O_DUR" \
'BEGIN { printf "%.2f", ( (arate * duration) / 8192 ) }')
# Equals 1 if target size is ok, 0 otherwise
IS_MINSIZE=$(\
awk \
-v size="$T_SIZE" \
-v minsize="$T_MINSIZE" \
'BEGIN { print (minsize < size) }')
# Give useful information if size is too small
if [[ $IS_MINSIZE -eq 0 ]]; then
printf "%s\n" "Target size ${T_SIZE}MB is too small!" >&2
printf "%s %s\n" "Try values larger than" "${T_MINSIZE}MB" >&2
exit 1
fi
# Set target audio bitrate
T_ARATE=$O_ARATE
# Calculate target video rate - MB -> KiB/s
T_VRATE=$(\
awk \
-v size="$T_SIZE" \
-v duration="$O_DUR" \
-v audio_rate="$O_ARATE" \
'BEGIN { print ( ( size * 8192.0 ) / ( 1.048576 * duration ) - audio_rate) }')
# Perform the conversion
ffmpeg \
-y \
-i "$1" \
-c:v libx264 \
-b:v "$T_VRATE"k \
-pass 1 \
-an \
-f mp4 \
/dev/null \
&& \
ffmpeg \
-i "$1" \
-c:v libx264 \
-b:v "$T_VRATE"k \
-pass 2 \
-c:a aac \
-b:a "$T_ARATE"k \
$T_FILE
```
Resize Video to Target Size Shortcut
Updated
02152023-204521
https://davidblue.wtf/targetffmpeg
Social
I'm gonna call this one Mastodon-related because basically any other method of getting a given video clip below the file limit (40MB, in mastodon.social's case,) drives me crazy. #shortcuts #video #automation #mac https://routinehub.co/shortcut/14270
- [Mastodon](https://mastodon.social/@DavidBlue/109872079917980053) - [Telegram](https://t.me/extratone/13627) --- ## Re-encode video files to a specific size target with ffmpeg. **Please note**: this shortcut is macOS-only. ### Requirements - [**ffmpeg**](https://ffmpeg.org) (`brew install ffmpeg`) This shortcut re-encodes single inputted video files to a **specified file size target** (in MB, per run) with [**ffmpeg**](https://ffmpeg.org), which it will then save to a new .mp4 file entitled `[source filename]-[provided file size]MB.mp4` in a directory of your choosing via a [Save File action](https://www.matthewcassinelli.com/actions/save-file). ### Installation At install, you will be asked to specify: 1. The default source prompt for the shortcut (`Photos` will ask you for a video file from iCloud Photos while `Files` will use a standard Finder prompt.) 2. Whether or not you'd like the `Delete Immediately` option in the [Delete Files](https://matthewcassinelli.com/actions/delete-files/) action toggled on by default. This action is handling a (frankly, completely redundant) file - neither the source file nor the output from the Save File action will be deleted. ### Source - [Original Stack Overflow answer](https://stackoverflow.com/a/61146975/14383008) (whoo!) - [Script Gist](https://gist.github.com/extratone/4e9ffa59994ca32aaba3666c2031d9b1) ```bash #!/bin/bash # # Re-encode a video to a target size in MB. # Example: # ./this_script.sh video.mp4 15 T_SIZE="$2" # target size in MB T_FILE="${1%.*}-$2MB.mp4" # filename out # Original duration in seconds O_DUR=$(\ ffprobe \ -v error \ -show_entries format=duration \ -of csv=p=0 "$1") # Original audio rate O_ARATE=$(\ ffprobe \ -v error \ -select_streams a:0 \ -show_entries stream=bit_rate \ -of csv=p=0 "$1") # Original audio rate in KiB/s O_ARATE=$(\ awk \ -v arate="$O_ARATE" \ 'BEGIN { printf "%.0f", (arate / 1024) }') # Target size is required to be less than the size of the original audio stream T_MINSIZE=$(\ awk \ -v arate="$O_ARATE" \ -v duration="$O_DUR" \ 'BEGIN { printf "%.2f", ( (arate * duration) / 8192 ) }') # Equals 1 if target size is ok, 0 otherwise IS_MINSIZE=$(\ awk \ -v size="$T_SIZE" \ -v minsize="$T_MINSIZE" \ 'BEGIN { print (minsize < size) }') # Give useful information if size is too small if [[ $IS_MINSIZE -eq 0 ]]; then printf "%s\n" "Target size ${T_SIZE}MB is too small!" >&2 printf "%s %s\n" "Try values larger than" "${T_MINSIZE}MB" >&2 exit 1 fi # Set target audio bitrate T_ARATE=$O_ARATE # Calculate target video rate - MB -> KiB/s T_VRATE=$(\ awk \ -v size="$T_SIZE" \ -v duration="$O_DUR" \ -v audio_rate="$O_ARATE" \ 'BEGIN { print ( ( size * 8192.0 ) / ( 1.048576 * duration ) - audio_rate) }') # Perform the conversion ffmpeg \ -y \ -i "$1" \ -c:v libx264 \ -b:v "$T_VRATE"k \ -pass 1 \ -an \ -f mp4 \ /dev/null \ && \ ffmpeg \ -i "$1" \ -c:v libx264 \ -b:v "$T_VRATE"k \ -pass 2 \ -c:a aac \ -b:a "$T_ARATE"k \ $T_FILE ```