Skip to content

Instantly share code, notes, and snippets.

@pruperting
Created May 11, 2010 16:29
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save pruperting/397509 to your computer and use it in GitHub Desktop.
Save pruperting/397509 to your computer and use it in GitHub Desktop.
#!/bin/bash
#"simple" ffmpeg progress indicator, though because evil ffmepg doesn't use Carriage Returns or Line Feeds like any normal person, it is actually a right pain in the bum ;)
#by Rupert Plumridge
#for updates visit www.prupert.co.uk
#Creative Commons Attribution-Non-Commercial-Share Alike 2.0 UK: England & Wales Licence
#
# File name: fs.sh - saved in the "nautilus-scripts" directory.
# http://handybashscripts.blogspot.com/2011/01/ffmpeg-with-progress-bar-re-work.html
#
# Author: robz
# Version: 310111
# Vars.
LOG=$HOME/ffmpeg.log
display () # Calculate/collect progress
{
START=$(date +%s); FR_CNT=0; ETA=0; ELAPSED=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=$(date -d @$(awk 'BEGIN{print int(('$ELAPSED' / '$FR_CNT') *\
('$TOT_FR' - '$FR_CNT'))}') -u +%H:%M:%S) # ETA calc.
fi
echo -ne "\rFrame:$FR_CNT of $TOT_FR Time: $(date -d @$ELAPSED -u +%H:%M:%S) ETA: $ETA Percent: $PERCENTAGE" # Text for stats. output.
done
}
trap "killall ffmpeg fs.sh; 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":" -f1)
MIN=$(echo $DUR | cut -d":" -f2)
SEC=$(echo $DUR | cut -d":" -f3)
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" -vcodec libx264 -level 41 -vpre main -vpre medium -crf 24 -threads 0 -sn -acodec libfaac -ab 128k -ac 2 -ar 48000 -vsync 1 -async 1000 -map 0.0:0.0 -map 0.1:0.1 "$1".mkv 2>/dev/null & # Background FFmpeg.
PID=$! &&
echo "ffmpeg PID = $PID"
echo "Length: $DUR - Frames: $TOT_FR "
display # GUI stats. func.
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 -e $COUNT\. ${NFILE%.*}\
"\nDuration: $DUR - Total frames: $TOT_FR" >> $LOG
# Elapsed time for 1 pass, average for 2 passes, fps average for both.
AV_RATE=$(( TOT_FR / ELAPSED ))
echo -e "Re-coding time taken: $(date -d @$ELAPSED -u +%H:%M:%S)"\
"at an average rate of $AV_RATE""fps.\n" >> $LOG
done
# Notify finished batch ding-dong gong and message, log it, all done bye ;¬)
TEXT="Total re-coding time: $(date -d @$BATCH -u +%H:%M:%S)."
echo -e "$TEXT\n\
__________________________________________________________________" >> $LOG
echo -e "$TEXT\n\
__________________________________________________________________"
exit
@Fmstrat
Copy link

Fmstrat commented Sep 9, 2019

I ended up using your algorithm for ffmkv: https://github.com/Fmstrat/ffmkv which is a bash wrapper for FFMPEG with an Inquirer menu interface and progress monitoring. During that I did a rewrite after noticing a few division by 0 issues and some inefficiencies with things like the repeated parsing of ffmpeg1.log and calculating variables. Much of this may just be because it's now 2019 and this code is 10 years old. If you'd like to pull code from there, feel free!

@Rendevior
Copy link

This is my personal use Here.

Pretty much same algo as yours, i just did a few optimizations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment