Skip to content

Instantly share code, notes, and snippets.

@codedninja
Forked from pruperting/ffmpeg-progress.sh
Last active November 12, 2016 02:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codedninja/c31d7adb0c6fc02edc015c57bc31468a to your computer and use it in GitHub Desktop.
Save codedninja/c31d7adb0c6fc02edc015c57bc31468a to your computer and use it in GitHub Desktop.
#!/bin/bash
#updated ffmpeg progress indicator
#by Rupert Plumridge
#for updates visit www.prupert.co.uk
#Creative Commons Attribution-Non-Commercial-Share Alike 2.0 UK: England & Wales Licence
# Based on the ffmpegprogress bar from: http://handybashscripts.blogspot.com/2011/01/ffmpeg-with-progress-bar-re-work.html
# which was based on my initital progress script - circle of life and all that ;)
# version 2.0
# 07.04.2011
# now uses apparently better progress detection, based on duration of overall video and progress along the conversion
####################################################################################
# USAGE #
# 1) Run the script with the name of the file to be converted after the name of the script (e.g. ./ffmpeg-progress.sh "My Awesome Video.mpg)
###################################################################################
# Please adjust the following variables as needed.
# It is recommended you at least adjust the first variable, the name of the script
SCRIPT=ffmpeg-progress.sh
LOG=$HOME/ffmpegprog.log
display () # Calculate/collect progress
{
START=$(date +%s); FR_CNT=0; ETA=0; ELAPSED=0; TIME_STR=0;
while [ -e /proc/$PID ]; do # Is FFmpeg running?
sleep 2
VSTATS=$(awk '{gsub(/frame=/, "")}/./{line=$1-1} END{print line}' \
/tmp/vstats) # Parse vstats file.
if [ $VSTATS -gt $FR_CNT ]; then # Parsed sane or no?
FR_CNT=$VSTATS
PERCENTAGE=$(( 100 * FR_CNT / TOT_FR )) # Progbar calc.
ELAPSED=$(( $(date +%s) - START )); echo $ELAPSED > /tmp/elapsed.value
ETA_SEC=$(awk 'BEGIN{print int(('$ELAPSED' / '$FR_CNT') * ('$TOT_FR' - '$FR_CNT'))}') # ETA calc.
ETA=$(printf '%dh:%dm:%ds\n' $((ETA_SEC/3600)) $((ETA_SEC%3600/60)) $((ETA_SEC%60)))
TIME_STR=$(printf '%dh:%dm:%ds\n' $((ELAPSED/3600)) $((ELAPSED%3600/60)) $((ELASPED%60)))
fi
echo -ne "\rFrame:$FR_CNT of $TOT_FR Time:$TIME_STR ETA:$ETA Percent:$PERCENTAGE" # Text for stats output.
done
}
trap "killall ffmpeg $SCRIPT; rm -f "$RM/vstats*"; exit" \
INT TERM EXIT # Kill & clean if stopped.
# Get duration and PAL/NTSC fps then calculate total frames.
FPS=$(ffprobe "$1" 2>&1 | sed -n "s/.*, \(.*\) tbr.*/\1/p")
DUR=$(ffprobe "$1" 2>&1 | sed -n "s/.* Duration: \([^,]*\), .*/\1/p")
HRS=$(echo $DUR | cut -d":" -f2)
MIN=$(echo $DUR | cut -d":" -f3 | cut -d"." -f1)
SEC=$(echo $DUR | cut -d"." -f2)
TOT_FR=$(echo "($HRS*3600+$MIN*60+$SEC)*$FPS" | bc | cut -d"." -f1)
if [ ! "$TOT_FR" -gt "0" ]; then echo error; exit; fi
# Re-code with it.
nice -n 15 ffmpeg -deinterlace -vstats_file /tmp/vstats -y -i "$1" -c:v libx264 -map 0:v:0 -c:a aac -b:a 160k -map 0:a:1 -strict -2 -preset slow -crf 28 "$1".mp4 2>/dev/null &
PID=$! &&
echo "ffmpeg PID = $PID"
echo "Length: $DUR - Frames: $TOT_FR "
display # Show progress.
rm -f "$RM"/vstats* # Clean up tmp files.
# Statistics for logfile entry.
((BATCH+=$(cat /tmp/elapsed.value))) # Batch time totaling.
ELAPSED=$(cat /tmp/elapsed.value) # Per file time.
echo "\nDuration: $DUR - Total frames: $TOT_FR" >> $LOG
AV_RATE=$(( TOT_FR / ELAPSED ))
echo -e "Re-coding time taken: $(printf '%dh:%dm:%ds\n' $(($ELAPSED/3600)) $(($ELAPSED%3600/60)) $(($ELASPED%60)))"\
"at an average rate of $AV_RATE""fps.\n" >> $LOG
exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment