Skip to content

Instantly share code, notes, and snippets.

@tatze
Last active August 22, 2019 22:25
Show Gist options
  • Save tatze/3c4738481bb2bc0d02ad2a872f41c0e6 to your computer and use it in GitHub Desktop.
Save tatze/3c4738481bb2bc0d02ad2a872f41c0e6 to your computer and use it in GitHub Desktop.
creates reduced versions of images and mp4 either in relative (path) or absolute (collection) directory... mainly used to save space on smartphones
#!/bin/bash
set -Eeuo pipefail
#
# 20190822 | tatze
# ------------------------------------------
# programs needed:
# - ffmpeg
# - imagemagick
# ------------------------------------------
# ------------------------------------------
# ------------------------------------------
# path settings
global_path=~/Pictures/_reduced/
local_path='reduced/'
# ------------------------------------------
# image settings
width=2220
quality=90
# ------------------------------------------
# video settings (crf 0..51 [23 is default 51 means worst quality])
crf=23
# ------------------------------------------
# create directory if it's non-existent
function dir {
if [ ! -d "$1" ]
then
printf "${bold}creating folder $1 ${normal}\n"
mkdir -p -- "$1"
if [ ! -d "$1" ]
then
printf "${bold}creating folder $1 FAILED, aborting script.${normal}\n"
exit 1
fi
fi
}
# terminal output: bold or normal?
bold=$(tput bold)
normal=$(tput sgr0)
# your choice ...
printf "\n${bold}Where shall the reduced images be created? ${normal}
1. locally ($local_path) ${bold}[default]${normal}
2. globaly ($global_path)\n${bold}
[?] : ${normal}"
read RP
case $RP in
2)
printf "using $global_path ${normal}\n\n"
path=$global_path
pth=$(basename $PWD)/
path+=$pth
;;
*)
printf "using $local_path ${normal}\n\n"
path=$local_path
;;
esac
dir "$path"
find . -iregex '.*\.mp4$\|.*\.jpe?g$' \
-not -iregex '.*_reduced\.mp4$\|.*_reduced\.jpe?g$' \
-not -path "$path/*" -print0 | sort -z |
while IFS= read -rd '' file; do
# path for reduced files
rd=$path${file%/*}
dir "$rd"
# get basename
bn=${file##*/}
ext=${file##*.}
# create filename for temp version
tmp="${bn%.*}_temp.$ext"
# create filename for reduced version
bn="${bn%.*}_reduced.$ext"
# check if reduced file already exists
if [ ! -f "$rd/$bn" ]
# nope, go on
then
# uppercase the extension to trigger on all ext|eXt|exT|eXT|...
ext=${ext^^}
case $ext in
MP4)
printf "compressing video $file ... "
# prepending < /dev/null to prevent characters bleeding to ffmpeg
# using temporary file to avoid faulty files when escaping the loop (next run the script will re-do $file then)
< /dev/null ffmpeg -y -i "$file" \
-c:v libx264 -crf $crf -preset medium -c:a aac -b:a 128k \
-movflags +faststart -vf scale=-2:720,format=yuv420p \
-v 0 \
"$rd/$tmp"
printf "done.\ncopying metadata ..."
# copy metadata to the reduced version
< /dev/null ffmpeg -i "$file" \
-i "$rd/$tmp" -map 1 -map_metadata 0 \
-v 0 \
-c copy "$rd/temp_for_metadata".mp4
# move the reduced file to its final version
mv "$rd/temp_for_metadata.mp4" "$rd/$bn"
# remove the temporary file
rm "$rd/$tmp"
# preserve modified timestamp
touch -r "$file" "$rd/$bn"
printf "done.\nhere it is: $rd/$bn\n\n"
;;
JPG|JPEG)
printf "compressing image $file ... "
convert "$file" -resize $width -quality $quality "$rd"/"$bn"
# preserve modified timestamp
touch -r "$file" "$rd"/"$bn"
printf "done.\nhere it is: $rd/$bn\n\n"
;;
*)
printf "${bold}extension not supported, skipping.\n${normal}"
;;
esac
# file exists, skip it
else
printf "$rd/$bn already exists, skipping.\n"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment