Skip to content

Instantly share code, notes, and snippets.

@oxagast
Last active October 25, 2025 16:43
Show Gist options
  • Select an option

  • Save oxagast/aa4bda692f6a636fa749cec5e2ace85a to your computer and use it in GitHub Desktop.

Select an option

Save oxagast/aa4bda692f6a636fa749cec5e2ace85a to your computer and use it in GitHub Desktop.
Video Downsampler in Bash
#!/usr/local/bin/bash
# oxagast / marshall@oxasploits.com
#
#
maxres="480p" ## Target Resolution
audiochs=2 ## Max Audio Channels
maxsize=600 ## Max filesize in megabytes
#
cleanup()
{
printf "\nCaught CTRL+C cleaning up... "
rm -f "downsample/*.mp4"
echo "Exiting..."
exit 1
}
trap cleanup SIGINT
res=$(echo $maxres | tr -d 'p')
if [[ $(pgrep ffmpeg | wc -l) -ne 0 ]]; then
echo "Already encoding!"
exit 1
fi
mkdir -p orig
mkdir -p downsample
count=0
totfiles=$(ls -1 *.{mp4,mpg,avi,mkv} 2>/dev/null | wc -l | tr -d ' ')
for file in *.{mp4,mpg,avi,mkv}; do
((count++))
filename=$(basename -- "$file")
extension="${filename##*.}"
filename_no_ext="${filename%.*}"
if [[ -f "downsample/${file}" ]]; then
rm -f "downsample/${file}"
fi
if [[ $(echo "${file}" | grep -E "[[:digit:]]{4}") ]]; then
date=$(echo "${file}" | tr '.' ' ' | sed -E 's|.* ([[:digit:]]+) mp4|\1|' || echo "${file}" | grep -oE \
"[[:digit:]]{4}")
title=$(echo "${file}" | tr '.' ' ' | sed -E 's|(.*) [[:digit:]]{4} mp4|\1|' || echo "${filename_no_ext}")
else
date=""
title=""
fi
if [[ -f "${file}" ]]; then
osize=$(stat -f "%z" "${file}" | tr -d '\n')
osizemb=$(stat -f "%z" "${file}" | gnumfmt --to-unit M --format "%8.0f" | xargs printf "\r%s")
else
osize=0
osizemb=0
fi
if [ $osizemb -gt $maxsize ]; then
if [[ $(ffprobe -v fatal -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 "${file}") -gt $res ||
$(ffprobe -v fatal -select_streams a:0 -show_entries stream=channels -of default=noprint_wrappers=1:nokey=1 \
"${file}" 2>/dev/null) -gt 2 ]]; then
if [ ! -s "downsample/${filename_no_ext}.mp4" ] || [[ ! $(ffprobe -v fatal -show_entries format=duration -of \
default=noprint_wrappers=1:nokey=1 "${file}" 2>&1 >/dev/null) ]]; then
if [ ! -f "orig/${file}" ] || [[ $(ffprobe -ignore_chapters 1 -v fatal -show_entries format=duration -of \
default=noprint_wrappers=1:nokey=1 "${file}" | cut -d '.' -f 1) -ne $(ffprobe -v \
error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "orig/${file}" |
cut -d '.' -f 1) ]]; then
#FRAMECOUNT=$(mediainfo --Output="Video;%FrameCount%" "${file}" | tr -d '\n')
pv -s "${osize}" -aepN "Downsampling: ($count/$totfiles) ${title} [$date]" "${file}" | ffmpeg -i pipe:0 -y \
-nostats -hide_banner -loglevel fatal -ignore_chapters 1 -vf "scale=-2:$res:flags=lanczos+accurate_rnd" \
-c:v libx264 -preset slow -filter:v fps=24 -crf 31 -maxrate 2M -bufsize 4M -c:a aac -ac $audiochs -b:a \
128k -metadata year=$date -metadata title="${title}" "downsample/${filename_no_ext}.mp4" && mv \
"${file}" "orig/" 2>/dev/null && mv -f "downsample/${filename_no_ext}.mp4" "${filename_no_ext}.mp4" \
2>/dev/null || mv -f "orig/${file}" "${file}" 2>/dev/null
fi
fi
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment