Skip to content

Instantly share code, notes, and snippets.

@chauek
Created June 7, 2019 11:31
Show Gist options
  • Save chauek/df469313046447854a27cb50580bbc14 to your computer and use it in GitHub Desktop.
Save chauek/df469313046447854a27cb50580bbc14 to your computer and use it in GitHub Desktop.
Converts movies in current and sub dirs showing progressbar.
#!/bin/bash
# Install ffmpeg on OSX:
# brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-libass --with-libvorbis --with-libvpx --with-opus --with-x265
IFS=$'\n'
WATCHER_PORT=9998
LINE=""
PERCENT=0
DURATION=0
print_eta() {
ETA="$1"
printf 'ETA %02dh:%02dm:%02ds' $((ETA/3600)) $((ETA%3600/60)) $((ETA%60))
}
progress_bar() {
if [ "$1" == "done" ]; then
spinner="X"
percent_done="100"
progress_message="Done!"
new_line="\n"
else
spinner='/-\|'
percent_done="${1:-0}"
progress_message="$percent_done %"
fi
percent_none="$(( 100 - $percent_done ))"
[ "$percent_done" -gt 0 ] && local done_bar="$(printf '%*s' $percent_done "" | tr ' ' '█')"
[ "$percent_none" -gt 0 ] && local none_bar="$(printf '%*s' $percent_none "" | tr ' ' '.')"
# print the progress bar to the screen
printf "Progress: [%s%s] %s %s${new_line}" \
"$done_bar" \
"$none_bar" \
"${spinner:x++%${#spinner}:1}" \
"$progress_message "
print_eta "$2"
}
watch_progress() {
echo "Watch on $WATCHER_PORT"
start_timestamp="$(date +%s)"
isFirst=true
nc -l $WATCHER_PORT | while read ROW; do
KEY=$(echo "$ROW" | cut -d'=' -f1)
VAL=$(echo "$ROW" | cut -d'=' -f2)
if [ "$KEY" == "out_time_ms" ]
then
PERCENT=$(bc -l <<< "(($VAL / 1000000) / $DURATION * 100)")
now_timestamp="$(date +%s)"
cur_duration=$(bc -l <<< "($now_timestamp - $start_timestamp)")
ETA=$(bc -l <<< "($cur_duration / $PERCENT) * (100 - $PERCENT)")
ETA=${ETA%.*}
PERCENT=${PERCENT%.*}
fi
if [ "$ROW" == "progress=continue" ]
then
now_timestamp="$(date +%s)"
if [ "$isFirst" = true ]
then
echo ""
echo ""
echo ""
echo ""
isFirst=false
fi
printf "\033[3A"
echo "CONVERTING: $COUNTER($AMOUNT) $FILESIZE $src"
echo "$LINE"
progress_bar "$PERCENT" "$ETA"
echo ""
LINE=""
else
LINE="$LINE $ROW"
fi
if [ "$ROW" == "progress=end" ]
then
# echo " ==> watch break"
break
fi
done &
}
FILES=$(find . -iname "*.mp4" -o -iname "*.avi" -o -iname "*.MPG" -o -iname "*.MOV" -o -iname "*.MTS" -o -iname "*.mkv" | grep -v -E "_x26[4-5].mp4" | grep -v -E "_x26[4-5].avi")
AMOUNT=$(echo "$FILES" | sed '/^\s*$/d' | wc -l)
AMOUNT="$(echo -e "${AMOUNT}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo "FOUND $AMOUNT FILES"
COUNTER=0
for src in $FILES
do
LINE=""
PERCENT=0
COUNTER=$((COUNTER + 1))
FILESIZE=$(du -h "$src" | cut -f1)
DURATION=$(ffprobe -v quiet -select_streams v:0 -show_entries "stream=duration" -of compact "$src" | sed 's!.*=\(.*\)!\1!g')
WIDTH=$(ffprobe -v quiet -show_streams "$src" | grep coded_width)
WIDTH=${WIDTH#*=}
dest="${src/.mp4/_x265.mp4}"
dest="${src/.MP4/_x265.mp4}"
dest="${dest/.avi/_x265.mp4}"
dest="${dest/.MPG/_x265.mp4}"
dest="${dest/.MOV/_x265.mp4}"
dest="${dest/.MTS/_x265.mp4}"
dest="${dest/.mkv/_x265.mp4}"
if [ "$WIDTH" -gt "1920" ];
then
dest="${src/.mp4/_1080p_x265.mp4}"
dest="${dest/.avi/_1080p_x265.mp4}"
dest="${dest/.MPG/_1080p_x265.mp4}"
dest="${dest/.MOV/_1080p_x265.mp4}"
dest="${dest/.MTS/_1080p_x265.mp4}"
dest="${dest/.mkv/_1080p_x265.mp4}"
fi;
echo "CONVERTING: $COUNTER($AMOUNT) $FILESIZE $src -> $dest"
echo "CONVERTING: $COUNTER($AMOUNT) $src -> $dest" >> convert_all_movies.log
rc=0
watch_progress &
if [ "$WIDTH" -gt "1920" ];
then
# ffmpeg -stats -i "$src" -vf "scale=1920:1080,setsar=1" -c:v libx265 "$dest" || rc=$?
ffmpeg -stats -i "$src" -vf "scale=1920:1080,setsar=1" -nostats -progress http://localhost:$WATCHER_PORT -c:v libx265 "$dest" || rc=$?
else
# ffmpeg -stats -i "$src" -c:v libx265 "$dest" || rc=$?
echo "ffmpeg-bar -stats -i \"$src\" -c:v libx265 \"$dest\""
echo ""
ffmpeg -stats -i "$src" -nostats -progress http://localhost:$WATCHER_PORT -c:v libx265 "$dest" || rc=$?
fi;
if [ ! "$rc" -eq "0" ]
then
echo "ERROR: $rc Removing dest and exit"
rm "$dest" 2>/dev/null
exit 1
fi
FILESIZE_AFTER=$(du -h "$dest" | cut -f1)
echo "DONE: $COUNTER($AMOUNT) $FILESIZE -> $FILESIZE_AFTER $src -> $dest"
echo "DONE: $FILESIZE -> $FILESIZE_AFTER $src -> $dest" >> convert_all_movies.log
# TO REMOVE SOURCE
rm "$src"
# TO LEAVE SOURVE
# echo "$src" >> convert_all_movies.to_remove.log
sleep 10
done
# Remove from convert_all_movies.to_remove.log
# cat convert_all_movies.to_remove.log | xargs -I{} rm -v {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment