I was a bit bored today and decided that i wanted to run through some video conversion script in Handbrake. While i've converted a handful of files from my own library before (tutorials, quick guides for employees) I wanted a way that i could easily convert files without needing to run through the entire process in Handbrake every time.
While this isn't an intense process by any means, when you have multiple files to convert it's just nice to be able to drop them in a folder and see them queue up automatically.
That said, i went ahead and checked for Subtitles, file names that might need to be stripped, and the like. While i'm not using it for the express purpose of converting mkv/mp4 files, i know that it's a common thing people might use this for so i went ahead and implemented some subtitles/SRT file monitoring, routing, and compression at H265 with an RF of 20. If you'd like to lower/increase your video quality, you can do so by adjusting the Preset used (it's own variable) or adjusting the RF to a higher/lower number.
I've also included
note: If you're not familiar, in Handbrake a higher RF means lower quality, lower RF is higher quality. These correlate to file size and visual artifacts inversely, so the higher RF means a smaller but visually scarred file, and lower RF means cleaner, sharper, larger files.
### Code:
```
#!/bin/bash
# Directories to watch
$SUBS_DIR="~/Movies/Handbrake-this/WithSubtitles" # Folder to watch for files with subtitles
$NO_SUBS_DIR="~/Movies/Handbrake-this/NoSubtitles" # Folder to watch
$OUTPUT_DIR="~/Movies/Handbroken" # Folder for converted files
$NEEDS_SUBS_DIR="~/Movies/Handbrake-this/SubtitlesNeeded" #folder for files that need subtitles
# HandBrake Settings
$PRESET="Very Fast 2160p60 4K HEVC"
$RF="20" # Constant Quality (Lower = Better Quality)
# Ensure input/ output directories exist
mkdir -p "$OUTPUT_DIR"
mkdir -p "$NEEDS_SUBS_DIR"
mkdir -p "$SUBS_DIR"
mkdir -p "$NO_SUBS_DIR"
# Function to check dependencies
check_dependencies() {
echo "Checking system dependencies..."
# Check for Homebrew
if ! command -v brew &>/dev/null; then
echo "🚨 Homebrew is not installed. Please install it with:"
echo '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
exit 1
fi
# Check for HandBrakeCLI
if ! command -v HandBrakeCLI &>/dev/null; then
echo "🚨 HandBrakeCLI is not installed. Installing it now..."
brew install handbrake || { echo "❌ Failed to install HandBrakeCLI. Exiting."; exit 1; }
fi
# Check for fswatch
if ! command -v fswatch &>/dev/null; then
echo "🚨 fswatch is not installed. Installing it now..."
brew install fswatch || { echo "❌ Failed to install fswatch. Exiting."; exit 1; }
fi
echo "✅ All dependencies are installed. Proceeding..."
}
# Function to clean movie title
clean_movie_title() {
input_file="$1"
# Remove file extension
filename=$(basename "$input_file")
filename_no_ext="${filename%.*}"
# Remove specific encoding/release tags while keeping movie title numbers
clean_title=$(echo "$filename_no_ext" | sed -E '
s/[._]/ /g; # Replace dots and underscores with spaces
s/([0-9]{4})[^a-zA-Z]*//g; # Remove years (e.g., "2023" but not "300")
s/(1080p|720p|480p|2160p|4K)//g; # Remove resolution info
s/(WEBRip|BluRay|x264|x265|AAC|HDR|DV)//g; # Remove encoding tags
s/\[.*\]//g; # Remove bracketed tags like "[YTS.MX]"
s/^[ \t]+|[ \t]+$//g; # Trim leading/trailing spaces
')
echo "$clean_title"
}
# Function to convert video files and route them to the appropriate folder
convert_video() {
input_file="$1"
watch_folder="$2"
# Determine output file name
output_file="$OUTPUT_DIR/$(basename "${input_file%.*}.mp4")"
# Check for a matching SRT subtitle file
srt_file="${input_file%.*}.srt"
# Choose HandBrake settings based on the folder
if [[ "$watch_folder" == "$SUBS_DIR" ]]; then
if [[ -f "$srt_file" ]]; then
echo "Converting (Burned-in External Subtitles): $input_file with $srt_file -> $output_file"
HandBrakeCLI -i "$input_file" -o "$output_file" --preset "$PRESET" -q "$RF" --srt-file "$srt_file" --srt-burn
else
echo "No matching SRT found, converting without subtitles: $input_file -> $output_file"
HandBrakeCLI -i "$input_file" -o "$output_file" --preset "$PRESET" -q "$RF"
fi
elif [[ "$watch_folder" == "$NO_SUBS_DIR" ]]; then
echo "Converting (No Subtitles): $input_file -> $output_file"
HandBrakeCLI -i "$input_file" -o "$output_file" --preset "$PRESET" -q "$RF" --subtitle none
else
echo "Skipping unknown folder: $watch_folder"
return
fi
# If conversion succeeds, remove original file
if [ $? -eq 0 ]; then
echo "Conversion successful: $output_file"
rm "$input_file"
if [[ -f "$srt_file" ]]; then
rm "$srt_file" # Remove SRT after burning in
fi
else
echo "Error converting: $input_file"
fi
}
# Function to watch multiple directories
watch_folder() {
folder="$1"
fswatch -0 "$folder" | while read -d "" file; do
if [[ "$file" == *.mp4 || "$file" == *.mkv || "$file" == *.avi ]]; then
convert_video "$file" "$folder" &
fi
done
}
# Start watching both directories in parallel (requires fswatch)
watch_folder "$SUBS_DIR" &
watch_folder "$NO_SUBS_DIR" &
# Keep script running
wait
```
# Tags
#handbrake #video #compression #scripting #coding #gpt #automation #homebrew #sharing