Just trying to make things easier for myself.


The usefulness of bash_aliases and bash_functions.

How did I get from here:

ffmpeg -i Inception.mkv

Running “ffmpeg -i Inception.mkv” yields:

…to there?

sniff Inception.mkv

Pretty colors. 🙂

Well first you might want to amend the following lines to your $HOME/.bash_functions file!? And while I’m at it, add some flavor to the output. (the ‘pretty’ colors you see in the images.)

First we’re going to need some color.:

## Insert a new line into '$HOME/Bashrc'
echo >> $HOME/Bashrc
## Or simply hit 'ctrl+d' instead of using '<<_EOF_' here.
cat >> $HOME/Bashrc<<_EOF_
# Define some colors first:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
export Black="\033[0;30m"
export Red="\033[0;31m"
export Green="\033[0;32m"
export Yellow="\033[1;33m"
export Blue="\033[1;34m"
export Magenta="\033[1;35m"
export Cyan="\033[1;36m"
export White="\033[1;37m"
export Nc="\033[0m" # No Color
# --> Nice. Has the same effect as using "ansi.sys" in DOS.
_EOF_

But first we’ve to enable a .bash_functions file. 😉

## Insert a new line into '$HOME/.bashrc'
echo >> $HOME/.bashrc
## Or simply hit 'ctrl+d' instead of using '<<_EOF_' here.
## The following will enable to use the function as described below.
cat >> $HOME/.bashrc<<_EOF_
# Functions: check for a separate function file, and if we find one
# source it.
if [ -f ~/.bash_functions ]; then
    . ~/.bash_functions
fi
_EOF_

As for the function itself!

## You'll have to paste this in manually (why?)
## (Because my 'here doggy' didn't work here)
## So open up your favorite editor and save it as...
## .bash_functions
sniff()
{
## We might not want to run this as root!?
if [ $USER = root ]; then
echo -e ${Red}"\tAre you Insane!\n${Cyan}\tError: In order to use this script, one must NOT be $USER.\n${Yellow}\tExiting..."${Nc}
exit 0
else
echo -e ${Blue}"\t${USER} may proceed.\n${Cyan}\tMay peace be with you."${Nc}
fi
clear
## If no argument given, then assume the user wants to run things interactively.
if [ -z "$1" ];then
echo -e ${Blue}"\t(Hit \"${Yellow}ctrl+shift+v${Blue}\" to paste.)\n"${Nc}
echo -en ${Yellow}"\tPlease enter your url/file: "${Nc}
read Arg
  if [ -z "$Arg" ];then echo -e ${Red}"\tPlease provide me with a string to work on."${Nc}
  else 
  [ -n "$Arg" ];export Arg="$Arg"
  fi
fi
## Let's for now assume that the first argument passed is the filename.
## I'll work on a somewhat more flexible 'small program'
## (which a function actually is) later. ; - )
if [ -n "$1" ];then Arg="$1";fi
## If the 'Arg' is copied from nautilus and then pasted into 'gnome-terminal':
## Then this leads to: an 'argument' with 'ugly' spaces.
## And 2: A trailing space at the end of the 'argument'.
#
## Let's change that:
## First we will remove the 'file:///' part from your string and give you '/' in its stead.
## Because Bash or perhaps 'gnome-terminal' doesn't understand this.
Arg="${Arg/file:\/\//}"
#
## Second: If you're lazy like me, then you're most likely to have forgotten
## to remove the trailing space.
## Doesn't happen when using 'konsole'!
## The following 'undo's this particular 'damage'. ; - )
Arg=${Arg%\ }
#
## I use the following folder/directory for convenience's sake.
## E.g. the files used by sed are placed here.
if [ ! -d "$HOME/.usr/etc" ];then mkdir -p "$HOME"/.usr/etc;fi
## Let's define those files then.
sed_in=$HOME/.usr/etc/sed.in.txt
sed_out=$HOME/.usr/etc/sed.out.txt
## And create them, if necessary.
if [ ! -f "$sed_in" ];then
cat >>"$sed_in"<<_EOF_
s/%20/\ /g
s/%23/\#/
s/%26/\&/g
s/%2B/\+/
s/%2C/\,/g
s/%3A/\:/
s/%3B/\;/g
s/%3D/\=/g
s/%3F/\?/g
s/%5B/\[/g
s/%5D/\]/g
s/%7B/\{/g
s/%7D/\}/g
s/-/\-/g
s/(/\(/g
s/)/\)/g
_EOF_
fi
if [ ! -f "$sed_out" ];then
cat >>"$sed_out"<<_EOF_
s/ - /./g
s/ /./g
s/.\&//g
s/\&//g
s/.{/.[/g
s/}./]./g
s/.(/_/g
s/)./_/g
s/,_/_/g
s/</[/g
s/>/]/g
s/\],/\]/g
s/\.\.\[/\.\[/g
s/\._/_/g
s/_\./_/g
_EOF_
fi
#
## All the above implies, that we can now work with,
## e.g. files that contain 'ugly' spaces. YaY
## (i.e. files with embedded '%20's)
#
## And files that have names like:
# 'my-file with spaces and {curly}, [square], <chevron> and (parantheses) which are - of _type_ bracket.mkv'
#
## Let's get to work shall we.
## This will 'ready' the string.
Arg=$(echo "$Arg" | sed -f "$sed_in")
## The following:
## Might be(come) useful, when we're going to 'quote' or 'scale' the input later on.
# e.g. 'my-file with spaces and {curly}, [square], <chevron> and (parantheses) which are - of _type_ bracket.mkv'
# Will have: 'my-file.with.spaces.and.[curly].[square].[chevron].and_parantheses_which.are.of_type_bracket.mkv',
# as possible 'Output' name.
Output=$(echo "$Arg" | sed -f "$sed_out")
## Since we only want to use a few 'fragments' of ffmpeg's output
## (which is 'standard error' in this case).
duration="$(ffmpeg -i "${Arg}" 2>&1| sed -n "s/^.*Duration: \([^,]*\),.*/\1/p"|head -n 1)"
audio="$(ffmpeg -i "${Arg}" 2>&1| sed -n "s/^.*Audio: \([^,]*\),.*/\1/p"|head -n 1)"
video="$(ffmpeg -i "${Arg}" 2>&1| sed -n "s/^.*Video: \([^,]*\),.*/\1/p"|head -n 1)"
size="$(ffmpeg -i "${Arg}" 2>&1 | grep -i 'video' | awk '{print $6}' | cut -d, -f1 | tail -n 1)"
## Surely there must be a more elegant solution to this?
Fps="$(ffmpeg -i "${Arg}" 2>&1 | grep "[[:digit:]]*.[[:digit:]]*\ tbr" | sed -e 's/tbr\(.*\)//' -e 's/\(.*\),//' | awk -F ' ' '{print $1}')"
## Now let's break the 'Arg' up into useful pieces for later use.
File=$(basename "$Arg")
## E.g.:
# If File='my-file.avi.avi', then
## 1 % matches shortest range.
# ${File%.*} becomes my-file.avi
## 2 %% matches longest range.
# ${File%%.*} becomes my-file
Base=$(basename "${File%.*}")
Ext=${File/"$Base"}
## You might want to experiment a bit here!?
## I'm a proponent of using the 'matroska' container
## (if not in all cases). ; - )
#
## This implies the resulting 'Output' to be posted into the working directory.
## Which is what you'd most likely want.
## I.e. the 'Output' has become a safe copy to work on.
Output=$(basename "$Output" "$Ext").mkv
## This might seem somewhat 'redundant' and perhaps it is?
## Feel free to adjust things to your own needs!
## I'd say: 'Gotta catch them all...' : - D
if [ -z "${Arg}" ]; then echo -e ${Yellow}"\tProviding a filename is mandatory."${Nc}
elif [ ! -f "${Arg}" ]; then echo -e ${Yellow}"\tFile doesn't exist."${Nc}
elif [ -z "$video" ] && [ -z "$audio" ]; then echo -e ${Red}"\tThis is NOT a media file."${Nc}
else
  hours=$(echo $duration | cut -d: -f1)
  if [[ "$hours" = 00 ]];then hours="0";else hours=$(( $(echo $hours | cut -d'0' -f2) * 3600 ));fi
  minutes=$(echo $duration | cut -d: -f2)
  if [[ "$minutes" = 00 ]];then minutes="0"
  elif [[ "$minutes" < 10 ]];then minutes=$(( $(echo $minutes | cut -d'0' -f2) * 60 ))
  else minutes=$(($minutes * 60))
  fi
  seconds=$(echo $duration | cut -d: -f3)
  seconds=$(echo $seconds | cut -d. -f1)
  mseconds=$(echo $duration | cut -d. -f2)
  if [[ "$seconds" = 00 ]];then seconds=0
  elif [[ "$seconds" < 10 ]];then seconds=$(echo $seconds | cut -d'0' -f2)
  else seconds="$seconds"
  fi
  total=$((hours + minutes + seconds))."$mseconds"
  split=$((hours + minutes + seconds))
  ## Set a limit, to the amount we can 'quote', for later on.
  export Max_duration="$split"
  ## And set a minimum for the same purpose.
  export Min_duration="00:00:00.00"  
  echo
  echo -e ${Magenta}"\tThe argument's full path:\n\t${Cyan}"$Arg""${Nc}
  echo -e ${Magenta}"\tFilename:\n\t${Cyan}"$File""${Nc}
  echo -e ${Magenta}"\tWhen stripped from its suffix:\n\t${Cyan}"$Base""${Nc}
    echo -e ${Magenta}"\tThe file is stored in the {Container,Format}:\n\t${Cyan}"$Ext""${Nc}
  echo -e ${Magenta}"\tPotential outfile:\n\t${Cyan}"$Output"\n\r"${Nc} 
  echo -e ${Magenta}"\tFrames/s:\t${Cyan}"$Fps""${Nc}
  echo -e ${Magenta}"\tIts resolution:\t${Cyan}"$size""${Nc}  
  echo -e ${Magenta}"\tIts duration:\t${Cyan}"$duration" or "$total seconds""${Nc}
  if [ -z "$video" ];then echo -e ${Red}"\tVideo-codec:\tNo video stream found."${Nc};export result=audio_only
  else echo -e ${Magenta}"\tVideo-codec:\t${Cyan}"$video""${Nc}
  fi
  if [ -z "$audio" ];then echo -e ${Red}"\tAudio-codec:\tNo audio stream found."${Nc};export result=video_only
  else echo -e ${Magenta}"\tAudio-codec:\t${Cyan}"$audio""${Nc}
  fi
  echo
fi
## The following might be useful to
## 'repackage' files created with e.g. gtk-recordMyDesktop?
## Your mileage may vary though!?
## This also requires both mkvmerge && gtk-recordmydesktop to be installed though.
# sudo apt-get install mkvtoolnix mkvtoolnix-gui gtk-recordmydesktop
#case "$2" in
#"repack")
#if [ "$Ext" = ".ogv" ];then
#mkvmerge -o \
#"${Output}" \
#--language 1:eng --track-name 1:"${Base}." \
#--forced-track 1:no --display-dimensions 1:"${size}" \
#--language 2:eng --track-name 2:"${Base}." \
#--forced-track 2:no \
#-a 2 -d 1 -S -T --no-global-tags --no-chapters \
#"${Arg}" --track-order 0:1,0:2 --title "${Base}. ™"
#fi
#;;
#*)
#;;
#esac
}

Last but not the least I’m once again fiddling about and experimenting with… 😉

Oh and btw, it works just fine on images too. 😉

Speaking of which:
Image edits!? Courtesy of The Gimp and some nice plugins I found recently here and here.

That’s all folks!

Kindest regards,

Alex

♫ d(。◕‿◕。)b ♪♪

PS: My words are my own, my actions are my own. Everything I wrote and did in this post are my own responsibility. All I’m offering is: YAP! 😉

«Everything we do (in life) is meaningless, without the appropriate conviction

Before you comment!?

Back to top.