Last active
October 5, 2024 16:04
-
-
Save Eltiech/5520052ba29b0c97912622ef5747707b 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
#!/bin/bash | |
#Batch processor for assorted media yielding web playback compatible mp4s | |
#basic summary of args | |
#batch-ffmpegger.sh tuningparameter [FILES]... [trimstring] | |
#tuningparameter - ffmpeg's x264 tuning parameter. should be "film" or "animation" most likely. | |
# (googlit for the other options which you probably don't need) | |
#FILES - however many files you want. Doesn't do directories, use a wildcard/*.mkv etc | |
#trimstring - an optional custom string to trim the torrent-name and resolution stuff off the end | |
# of the file. a regex down below catches most of it though | |
# if the last argument isn't an existing file, it will be treated as the trimstring | |
#notes on behavior of this itteration: | |
#* If you don't have a version of ffmpeg with --enable-libfdk_aac, fix that. it's better than ffmpeg's built-in, just | |
# not default because of stupid software patents. If you don't do this, audio arguments in the final command will need tweaking | |
#* If surround sound is detected it will be downsampled with a formula superior to ffmpeg's default | |
#* Necessary bc firefox chokes on surround sound last I checked (not recently, admittedly) | |
#* DOES NOT account for 7.1 mid channels. Most of the crap I process is 5.1. | |
#* preset is set to slow down in the main ffmpeg command, change that to medium or fast if you're | |
# like, really impatient and/or your machine sucks | |
#* volume is boosted till the max volume within the file is 0.0 (loudest without clipping) | |
# This is highly desirable for most surround sound downsampling(often heckin quiet otherwise) | |
# This may make things overall undesirably loud if your media item has absolutely no loud noises (haven't had this happen much in practice) | |
# ideally I guess one would have prefer a target mean volume or some such. but it don't be like that rn. | |
#* target res is generally gonna be scaled down to 720p if source is 800p or greater. (no change if less) | |
#* Scaling is done with lanczos. Makes for "I can't believe it's not [one standard step in resolution up] sharpness" | |
#* crf is 25. Decent balance of size/quality imho. I sometimes go as high as 27. 23 is ffmpeg/x264's default. Higher num = lower quality. | |
#* tweaking may necessary if there are multiple audio or video tracks, or they're in some nonstandard order | |
#* Quits processing on a bad file, remove """|| echo "Something borked for $i" && exit""" if you don't want that | |
#* the file's metadata title is set to the trimmed name of file. | |
#* as current written everything goes to /tmp/ | |
#* Batch ffmpeger? I barely know 'er | |
#like change this if you want to nice it lower (higher priority). +5 makes it more of a background thing. | |
sudo renice +5 $$ | |
IFS=$'\n' | |
echo "files: ${@:${#@}}" | |
TRIMSTRING="" | |
LASTARG="${@:${#@}}" | |
if [ ! -e "$LASTARG" ]; then | |
TRIMSTRING="$LASTARG" | |
echo "Custom trim string: $TRIMSTRING" | |
#remove the last arg | |
set -- "${@:1:$(($#-1))}" | |
echo "$@" | |
fi | |
function trimname() | |
{ | |
FNAME="$1" | |
SHORT="$(perl -pe 's/([^\/]+?)([ \.]+(1080i|1080p|HEVC|AVC|x264|FiNAL|x265|H264|H265|720i|720p|BluRay|REPACK|AMZN|PROPER|2160p|MULTi)[^\/]+)?\.\w{2,4}$/\1/'<<<"$FNAME")" | |
#replace periods with spaces to avoid Some.Show.Name.S01E05 looking stuff | |
SHORT="$(perl -pe 's/\./ /g'<<<"${SHORT##*/}")" | |
if [ -n "$TRIMSTRING" ]; then | |
SHORT="${SHORT% ${TRIMSTRING}*}" | |
fi | |
echo -n "$SHORT" | |
} | |
#preview the trimmed names | |
echo "Cleaned up names are:" | |
for i in "${@:2}"; do | |
echo "$(trimname "$i")" | |
done | |
for i in "${@:2}"; do | |
SHORTNAME="$(trimname "$i")" | |
echo "SHORTNAME: $SHORTNAME" | |
FFPROBE="$(ffprobe "$i" 2>&1)" | |
#SUBTRACK="$(grep -Poh '(?<=#)\d:\d{1,2}(?=\(eng\): Subtitle)')<<<"$FFPROBE")" | |
#tries and find the resolution. also tries to avoid attached images like cover art or included thumbnails | |
VIDTRACK="$(grep -v "attached"<<<"$FFPROBE"| grep -Po 'Stream #0:\d(\[\w{3,6}\])?(\(\w{3}\))?: Video.*?, \d{3,4}x\d{3,4}')" | |
echo "VIDTRACK: $VIDTRACK" | |
[ -z "$VIDTRACK" ] && echo "shit, bad vidtrack detection for $i" && exit | |
#split the resolution string into an array | |
IFS=" x" | |
vtsplit=($VIDTRACK) | |
IFS="\n" | |
HEIGHT="${vtsplit[-1]}" | |
WIDTH="${vtsplit[-2]}" | |
echo "${WIDTH} x ${HEIGHT}" | |
#if it's 800p or higher, let's shrink it. | |
if ((HEIGHT>799)); then | |
WIDTH=$((720 * WIDTH / HEIGHT)) | |
WIDTH=$((WIDTH + WIDTH%2)) #even it out if something's odd | |
HEIGHT=720 | |
fi | |
echo "Res will be ${WIDTH} x ${HEIGHT}" | |
sleep 2 | |
grep -P 'Audio:.*?(5|7).(0|1)'<<<"$FFPROBE" | |
if grep -P 'Audio:.*?(5|7).(0|1)'<<<"$FFPROBE"; then | |
echo "Surround sound detected?" | |
grep -P 'Audio:.*?(5|7).(0|1)'<<<"$FFPROBE" | |
AUDIOFILTER="pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.5*LFE" | |
fi | |
# | |
[[ -n "$AUDIOFILTER" ]]&&COMMA="," | |
BOOST="$(ffmpeg -hide_banner -i "$i" -map 0:a -filter:a "${AUDIOFILTER}${COMMA}volumedetect" -vn -sn -dn -f null /dev/null 2>&1 | grep -Po "(?<=max_volume: -)[0-9\.]+")" | |
[ -z "$BOOST" ] && BOOST="0" | |
BOOST="$BOOST" | |
echo "BOOST IS $BOOST" | |
BOOST="${BOOST}dB" | |
AUDIOFILTER="${AUDIOFILTER}${COMMA}volume=$BOOST" | |
echo "Audio Filter will be $AUDIOFILTER" | |
#\"$AUDIOFILTER\"" | |
#if there's an audio filter string, we needa add the flag | |
#with the boost stuff now moved out of the surround stuff though, always needed..whatever | |
[[ -n "$AUDIOFILTER" ]]&&AFB="-filter:a" | |
echo "SHORTNAME: $SHORTNAME" | |
ffmpeg -hide_banner -y -canvas_size "${WIDTH}x${HEIGHT}" -i "$i" -sn -c:v libx264 -crf 24 -preset slow -pix_fmt yuv420p -filter_complex "[0:v]scale=w=${WIDTH}:h=${HEIGHT}[vid]" -map "[vid]" -sws_flags lanczos $AFB "$AUDIOFILTER" -map "0:a" -tune "$1" -c:a libfdk_aac -vbr 5 -movflags +faststart -threads 0 -dn -metadata Title="$SHORTNAME" -f mp4 "/tmp/${SHORTNAME}.mp4" || echo "Something borked for $i" && exit | |
#Insert whatever uploading bits you wanna use here, if you want | |
#rm "/tmp/${SHORTNAME}" | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment