Skip to content

Instantly share code, notes, and snippets.

@jhonasn
Last active December 16, 2022 20:37
Show Gist options
  • Save jhonasn/b984361e091e5890eb072c4f74d1dd8b to your computer and use it in GitHub Desktop.
Save jhonasn/b984361e091e5890eb072c4f74d1dd8b to your computer and use it in GitHub Desktop.
This script converts all at once pictures and videos to reduce their sizes from one directory to another mantaning the directory structure. Ideal to use when you want to share some pictures or earn some disc space.
#!/bin/bash
clear
#rm -r lasttrip-converted/ # Debug to delete last try
originpath=`readlink -f "$1"`
destinpath=`readlink -f "$2"`
function showhelp {
echo '
This script converts all at once pictures and videos to reduce their sizes from one
directory to another mantaning the directory structure.
Usage:
sh media-reducer.sh [option] {origin path} [destination path]
[option] optional:
-h - show this help message
{origin path}: required if not -h
[destination path] optional:
A destination path to put the converted files in;
If is not passed a sibling directory will be created to do this
with the name of [origin directory name]-converted
Note:
- Pictures are converted if they are greater than 1.5mb and their type is jpg.
- Videos are converted if their width or height are greater than 640 and their type is mp4.
- Smaller pictures or jpEg are copied to the relative path
'
exit
}
# FIXME: check passed params and assign defaults if not passed
#if [[ -n "$originpath" && "$originpath" == *"-h"* ]]; then
#showhelp
if [ ! -n "$originpath" ]; then
# set defaut origin
originpath='.'
elif [ ! -d "$originpath" ]; then
# invalid origin
echo 'Please set a valid origin path'
echo
showhelp
fi
if [ ! -n "$destinpath" ]; then
# set defaut destination
destinpath="../`dirname '$originpath'`-converted"
elif [ ! -f "$destinpath" ]; then
# destination does not exist yet, trying to create
mkdir -p $destinpath
[ $? -eq 0 ] || {
# mkdir error
echo 'Please set a valid destination path'
echo
showhelp
}
fi
echo origin path $originpath
echo destin path $destinpath
echo
echo
echo 'CONVERT JPG (1 of 4)'
files=`find $originpath -type f -name '*.jpg' -size +1500k`
cmdconvert="convert -strip -interlace Plane -gaussian-blur 1.05 -quality 60% -adaptive-resize 60%"
for i in "${!files[@]}"; do
len=${#files[@]}
pc=$((($i * 100) / $len))
file=`readlink -f "${!i}"`
filedest="${file/$originpath\//}"
filedest="$destinpath/$filedest"
#echo "CONV FILE: $file TO: $filedest" # debug
echo "$pc% - $i of $len: $file"
mkdir -p `dirname "$filedest"`
$cmdconvert $file $filedest
done
echo
echo
echo 'COPY JPG SMALLER FILES (2 of 4)'
files=`find $originpath -type f -name '*.jpg' -size -1500k`
for i in "${!files[@]}"; do
file=`readlink -f "${!i}"`
filedest="${file/$originpath\//}"
filedest="$destinpath/$filedest"
mkdir -p `dirname "$filedest"`
echo "smaller jpg: $file"
#echo "FROM: $file TO: $filedest" # debug
cp "$file" "$filedest"
done
echo
echo
echo 'COPY JPEG FILES (3 of 4)'
files=`find $originpath -type f -name '*.jpeg'`
for i in "${!files[@]}"; do
file=`readlink -f "${!i}"`
filedest="${file/$originpath\//}"
filedest="$destinpath/$filedest"
mkdir -p `dirname "$filedest"`
echo "jpeg: $file"
#echo "FROM: $file TO: $filedest" # debug
cp "$file" "$filedest"
done
echo
echo
echo 'CONVERT VIDEOS (4 of 4)'
files=`find $originpath -type f -name '*.mp4'`
cmdconvert="ffmpeg-bar -i input -y -s hd480 -ac 1 -ar 16000 -b:a 80k -c:v vp9 -c:a libopus output"
function timefmt {
seconds=`echo "round($1 / 1000)" | qalc -t -f -`
TZ=UTC0 printf "%(%H:%M:%S)T\n" "$seconds"
}
for i in "${!files[@]}"; do
file=`readlink -f "${!i}"`
filedest="${file/$originpath\//}"
filedest="$destinpath/$filedest"
len=${#files[@]}
pc=$((($i * 100) / $len))
duration=`ffprobe -i $file -v quiet -show_entries format=duration -of csv="p=0"`
# convert duration to ms
duration=`echo ${duration/./,} "* 1000" | qalc -t -f -`
size=`du -h $file | cut -d " " -f 1`
res=`ffprobe -v error -show_entries stream=width,height -of csv=p=0:s=x $file`
res=($(echo $res | tr "x" "\n"))
w=${res[0]}
h=${res[1]}
portrait=0
if [[ w -gt h ]]; then
res=$w
else
res=$h
portrait=1
fi
status="$pc% - $i of $#: $path | ${w}x$h | $size"
if [[ res -gt 640 ]]; then
echo "CONVERTING: $status | `timefmt $duration`"
cmd=${cmdconvert/input/$file}
cmd=${cmd/output/$filedest}
mkdir -p `dirname "$filedest"`
#echo "I: $i FROM: $file TO: $filedest DIRNAME: `dirname "$filedest"`" # debug
$cmd
else
echo "SMALL RES, NOT CONVERT " $status
fi
done
# TODO: show diff quantities
#echo "PICTURES ${find $originpath -type f -name '*.jp*g' -print | xargs wc -l}"
#echo " ${find $originpath -type f -name '*.jp*g' -print | xargs wc -l}"
#find $originpath -type f -name '*.jp*g' -not -path 'converted' -print | xargs ls -la | wc -l
# NOTE: SHOW VIDEOS SIZES AND RESOLUTIONS
#find . -type f -name '*.mp4' -print | xargs du -sh
#OR (SLOWER):
#find . -type f -name '*.mp4' -exec bash -c 'du -h $1; ffprobe -v error -show_entries stream=width,height -of csv=p=0:s=x $1' bash {} \;
# NOTE: PLAY VIDEOS
#find . -type f -name '*.mp4' -size -10M -exec bash -c 'mpv $1' bash {} \;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment