Register
It is currently Sat Nov 01, 2014 5:10 am

Help: script with a "resume" feature


All times are UTC - 6 hours


Post new topic Reply to topic  [ 4 posts ] 
Author Message
 PostPosted: Thu Sep 10, 2009 11:58 am   

Joined: Thu Sep 10, 2009 11:19 am
Posts: 2
Hi!

I need help with a little script. Here's the idea:

The script takes a list of files, i.e., a text file containing the absolute path to a file on each line (one per line), like this:

/path/to/file1
/path/to/file2
/path/to/file3
...

The idea is the following: for each file in that list, you do some operations, and when the operations are finished, you delete the file from the list, so that the list only contains files that have not been processed so far. The rationale behind this is that this script will be applied to a huge number of files, and I want a way for the script to "resume" to where it was if it's stopped for some reason.

So far, this is what I've tried. It's for converting all my MP3s to OGG format (since it's a free standard, which MP3 is not).

Code:
#!/bin/bash

cat list.txt | while read file ; do
    tempfile=`echo $file | sed 's/mp3/wav/'` ;
    oggfile=`echo $file | sed 's/mp3/ogg/'` ;
    mpg321 "$file" -w "$tempfile" ;
    oggenc "$tempfile" -o "$oggfile" -q 6 ;
    rm "$tempfile" ;
    cat list.txt | sed "/$file/d" > list.txt ;
done


The problem with this script is that for some reason it doesn't update list.txt at the end of the loop (i.e, getting rid of the filename it just finished processing). It does the conversion alright, but since the list isn't updated, I won't be able to "resume" it.

Thanks in advance for your help.


Top
 Profile  
 PostPosted: Thu Sep 10, 2009 2:49 pm   
User avatar

Joined: Sat Jun 13, 2009 8:53 pm
Posts: 73
Location: Texas!
I got this to work for some small tests. This also prevents removing accidental matches with sed by using tail instead.

Code:
#!/bin/bash

cat list.txt | while read file ; do
    tempfile=`echo $file | sed 's/mp3/wav/'` ;
    oggfile=`echo $file | sed 's/mp3/ogg/'` ;
    mpg321 "$file" -w "$tempfile" ;
    oggenc "$tempfile" -o "$oggfile" -q 6 ;
    rm "$tempfile" ;
    tail --lines=+2 list.txt > list.temp
    mv list.temp list.txt
done

if [ -f "list.temp" ] ; then
    rm list.temp
fi


Top
 Profile  
 PostPosted: Thu Sep 10, 2009 4:55 pm   

Joined: Thu Sep 10, 2009 11:19 am
Posts: 2
Ah, clever solution: 'tailing' the file from line 2 onwards. Thank you very much! Here's the completed script. Seems to be working correctly.

Code:
#!/bin/bash
# This script converts all MP3s in the directory tree routed 'here'
# to OGG vorbis format at 192kbps. It won't delete the original MP3s,
# so that will have to be done manually after it has finished. The
# script will generate its own list of file to process so that it can
# be resumed at any later point if it is stopped.

# Generate a list of all MP3s in the directory tree, or use an already
# existing one (when resuming).
if [ ! -f "list.txt" ] ; then
    find . -iname "*.mp3" > list.txt
fi

# Iterate over every file in the list, converting it to OGG
# This requires first decoding the MP3 with mpg321 into a WAV
# file, and then encoding to OGG (at 192 kbps) with oggenc.
# Finally, when the conversion is done, remove the file from the list.
cat list.txt | while read file ; do
    tempfile=`echo $file | sed 's/mp3/wav/'` ;
    oggfile=`echo $file | sed 's/mp3/ogg/'` ;
    mpg321 "$file" -w "$tempfile" ;
    oggenc "$tempfile" -o "$oggfile" -q 6 ;
    rm "$tempfile" ;
    tail --lines=+2 list.txt > list.tmp ;
    mv list.tmp list.txt ;
done

# Clean up
if [ -f "list.temp" ] ; then rm list.temp ; fi


Top
 Profile  
 PostPosted: Mon Oct 05, 2009 8:44 pm   

Joined: Mon Oct 05, 2009 6:31 pm
Posts: 6
Good idea with the conversions. I had exactly ythe same thought quite awhile ago so I wrote this monster script to undertake the task. I didn't really use a list per se but instead just used whatever was passed on the command line. I like your idea of resuming though, there were quite a few times during converting a large number of files that the process would be interrupted and I would have to pick up where I left off. The way I worked around it though (as you will see in the script itself) was to simply check to see whether an ogg file with the same name as the source mp3 already existed and go from there. In comparison with your idea, it seems a little more flexible as it checks at runtime against the actual sources as opposed to a static list which may not represent changes. Anyway, here it is, it is rather long so be warned. Hopefully it may give you some inspiration...

Code:
#!/bin/bash

# SCRIPT NAME: mp3-ogg
# FUNCTION: converts MPEG1 Layer III files to Ogg/Vorbis format
# DEVELOPED BY - GD Lewis (rapskat@gmail.com)
# CREATION DATE - Sat Oct 5 00:20:06 EDT 2002
# REVISION NUMBER - 0.3
# REVISION DATE - Mon Jun 15 18:04:04 EDT 2009
# DEVELOPMENT ENVIRONMENT - Mepis Linux 8.0 2.6.27-1-mepis-smp #1 SMP PREEMPT i686 GNU bash 3.2.39(1)
# COMMENTS - Big thanks to Jon Portnoy for helping me figure out the mkfifo thing.
# NOTE - I opted for a direct pipe since using mkfifo was slow and added extra steps...sorry Jon :-(
# This script was developed on a Linux system and only tested on other Linux systems.
# In theory, it should be able to run on any system that can run bash shell scripts and has the necessary
# programs installed, but I don't know for sure.  Hell, I don't even know if it will work on most Linux systems!
# If anyone tries it let me know how it turns out.
#
#                                          REVISION HISTORY
#
# 0.1 - Conversion using mkfifo to create an intermediary .wav file
#          Used mpg321 and oggenc for decoding/encoding.
#
# 0.2 - Replaced mkfifo with direct pipe, changed to mpg123.
#          Added...
#                 -  transfer id3tag data to ogg file using mp3info
#                 -  option to sort ogg files in subdirs based on id3 info
#                 -  option to specify location of encoded ogg files
#                 -  global defaults section
#                 -  removal of caps, spaces and punctuation from dirs and filenames
#                 -  check to see whether mp3 file has already been encoded
#                 -  help message
#                 -  check for programs needed
#                 -  option to specify quality of ogg encoding
#                 -  attempt best possible match of original encoding specs
#                 -  advisory about high encoding quality
#                 -  revision history
#                 -  about 10lbs since I started this project.
#
# 0.3 - Improved error checking, cleaned up unnecessary program output, fixed problem with ID3 info being truncated
#          Added...
#                 -  recurse and replicate mode
#                 -  clean up routine for exit
#                 -  defaults for temp files and empty dir cleanup
#                 -  sig handling for interrupts
#                 -  automagic nose-picker
#                 -  additional comments throughout script
#
# 0.4 - Added code for parallel processing

# =========================GLOBAL DEFAULTS =================
# These variables hold the default values for the various options.  The command
# line option will override the default if specified.  By modifying these values, you
# can specify the default behavior and values for this script and save yourself some
# typing, especially if you plan on using it alot.  Certain options are mutually exclusive,
# such as sort and r&r, so you might want to take that into consideration.

#  This sets the default encoding quality to use for all ogg files
#  Value can be an integer from 1 to 10. If you set this to a value above 6,
#  then you might want to also suppress the high quality advisory with the
#  VERIFY option below.
#  This can also be specified at runtime with the -q | --quality <n> option
OGGQUAL=3

#  This default sets the buffer size (in bytes) that mpg123 will use for mp3 playback.
#  If you are having issues during encoding or are getting skips or artifacts in the oggs,
#  then you can try raising or lowering this value and it may help.  200 bytes is equal to
#  about 1 second of playback.  Keep in mind that higher values will seriously slow down
#  the encoding process and use more system resources.  Persons with really slow/old
#  systems should probably leave this at 0.
MP3BUFF=0

#  This specifies the default output path to write the encoded ogg files. Leave
#  blank to default to the same directory as the source mp3 files.
#  TIP:  It really is a good idea to have output files written to a separate
#  drive than the input files if at all possible as it greatly improves performance,
#  reliability and speed for encoding. Separate IDE channels are even better!
#  This can also be specified at runtime with the -o | --outdir <path> option
OUTDIR="/mnt/hdb2/tunez/oggz"

#  Setting this default to 1 will always attempt to sort the encoded ogg files by the
#  ID3 tag data if it is present. Subdirs are created in the order genre/artist/album
#  All spaces, caps and punctuation are removed from directory names.
#  This option is ignored in Recurse and Replicate mode.
#  This can also be specified at runtime with the -s | --sort option
SORTOGG=0

#  Setting this default to 0 will suppress the advisory about high quality encoding
#  If you know what you are doing and don't want to see it, then change this default.
#  This option is ignored in Recurse and Replicate mode.
#  This can also be specified at runtime by using the -n | --no-advise option
ADVISE=1

#  This is the global that determines what mode the script will run in.  If set to 1,
#  it will automatically go into Recurse and Replicate mode.  In R&R mode, the sub-
#  directory tree from the input path given will be replicated to the output path, and
#  all mp3 files found will be encoded to ogg and placed in the corresponding subdir
#  on the output path.  Only directories and their subs that actually contain mp3 files will
#  be replicated. The only other cli options processed in this mode are --quality & --outdir.
#  If this default is set to 1 then you must specify the input path as the first parameter at
#  runtime or you will get an error. Any other options must come after this.
#  This can also be specified at runtime by using the -r | --recurse </path> option
#  This mode disregards the sort option and suppresses the advisory.
REPLMODE=0

#  Setting this to 1 will cause the script to attempt to remove any empty subdirectories
#  from the output path in the case that the script is interrupted.  In Standard mode,
#  only empty subdirs from the output path are removed.  In R&R Mode, subdirs created
#  will be recursed from the output path down and removed if empty.
REMEMPTY=1

#  This default specifies the path to write any temp files to.  Usually /tmp is safe, but
#  you can change it if you would like temp files to be created elsewhere.  Make sure
#  that you have read and write permissions to whatever path you specify.
TMPDIR="$HOME/tmp"

#  Very rarely, file will mess up and not properly identify a valid MP3 file as such
#  This causes the script to skip the file.  Setting this default to 0 will disable the
#  builtin pre-verification for MP3 files and will pass all files through without checking
#  them first.  This could have undesirable effects at runtime, so use with caution!
#  This can also be specified at runtime by using the -f | --force option
VERIFY=0

#  Setting this default to 1 will cause the script to always delete the original mp3 files
#  after successfully encoding them to ogg.  Be VERY careful with this!
#  This can also be specified at runtime by using the -k | --kill-src option
KILLMP3=0

#  Setting this default to 1 will cause the script to normalize all source mp3 files
#  before encoding them to ogg using the defaults for normalization.  This of course
#  depends on the presence of normalize on the system.
NORM=1

#  This variable will determine how many parrallel processes to spawn at a time, useful for
#  systems with multiple processors and/or cores
CPU_PROC=2


#  This is the default to determine what level to pick your nose at.
#  For a light dig, set it for 1 or 2.  For an intermediate expedition,
#  you probably will want 3 or 4.  For a full on excavation, 5 will do the trick.
#  Be careful setting this above five or you may have to take a trip to the ER.
NOSE_DIG_LEVEL=3

# ======================END GLOBAL DEFAULTS =================

# ======================= FUNCTION SECTION =============================

# Pretty much self explanatory I think...
printHelp() {
     echo "    SCRIPT NAME: mp3-ogg"
     echo "    FUNCTION: converts MPEG1 Layer III files to Ogg/Vorbis format"
     echo "    EXPECTED USAGE: mp3-ogg <OPTIONS> /path/to/[mp3 file(s)]"
     echo "    RETURNS: none"
     echo "    DEPENDANCIES: mpg123, oggenc, mp3info, normalize, file, gawk, grep, tr, sed, bc, dirname, basename, ls, mkdir, rmdir, bash"
     echo "    INPUT FILES: as specified"
     echo "    OUTPUT FILES: as specified"
     echo " "
     echo "    OPTIONS: "
     echo -e "    -f | --force             Don't verify whether files are mp3 or not."
     echo -e "    -k | --kill-src          Delete the source mp3 upon successful encoding."
     echo -e "    -n | --no-advise         Suppress advisory about high encoding quality."
     echo -e "    -q | --quality <n>       Set quality of ogg encoding"
     echo -e "                             n=1-10 (10 being highest quality), default is 5."
     echo -e "    -r | --recurse <dir>     Recurse and replicate directory"
     echo -e "                             dir=fully qualified path (without trailing /) i.e. /var/share/media "
     echo -e "                             this option should be used with -o or alone (see script)"
     echo -e "    -s | --sort              Sort encoded ogg files by ID3 info if it exists"
     echo -e "                             subdirs are created in the order genre/artist/album"
     echo -e "    -o | --outdir <dir>      Specify directory to write encoded files to"
     echo -e "                             dir=fully qualified path (without trailing /) i.e. /var/share/media "
     echo -e "    -h | --help              Print this help and exit."
     echo ""
     echo "    EXAMPLES:"
     echo "    `basename "$0"` ~/media/foo.mp3"
     echo "    This would encode foo.mp3 to foo.ogg using all default settings"
     echo ""
     echo "    `basename "$0"` -k -q 7 ~/albums/*.mp3"
     echo "    This would encode all mp3 files in the albums directory with a quality of 7 (high)"
     echo "    and then remove the original mp3 file upon successful encoding"
     echo ""
     echo "    `basename "$0"` -f -q 3 -s  ~/muzak/*.mp3"
     echo "    This would encode and sort all files with an mp3 extension in the muzak directory with"
     echo "    a quality of 3 (very low) without verifying them first"
     echo ""
     echo "    `basename "$0"` -n -q 10 -s  -o /mnt/share/media/oggz /home/foo/tunez/*"
     echo "    This would encode and sort all mp3 files in the location /home/foo/tunez to the output "
     echo "    directory /mnt/share/media/oggz with a quality of 10 (ultra high) and suppress the advisory"
     echo ""
     echo "    `basename "$0"` -r /home/foo/tunez -q 8 -o /mnt/share/media/oggz"
     echo "    This would replicate the directory tree from /home/foo/tunez to the output "
     echo "    path /mnt/share/media/oggz and then encode all mp3 files to ogg with"
     echo "    a quality of 8 (very high) and place them in the equivelant subdirectory "
     echo "    on the output path."
     echo ""
     echo "    `basename "$0"` -r / -q 9 -o /mnt/otherdrive"
     echo "    This would search your entire system for mp3 files and then replicate the"
     echo "    directory structure for found mp3s to the output path /mnt/otherdrive"
     echo "    it would then encode all mp3 files to ogg with a quality of 9 (super high) and"
     echo "    place them in the equivelant subdirectory on the output path."
     echo ""
     echo "    KNOWN ISSUES"
     echo " - Options must be given in the order as listed or they won't be parsed correctly"
     echo " - Spaces and punctuation in dirnames and filenames will cause problems"
     echo " - Since encoding is done via a direct pipe, error correction is not possible"
     echo " - Comments from ID3 tag info are ignored"
     echo " - The nose picker doesn't really work"
     echo ""
}

CleanUp() {
     echo ""
     echo -e "Cleaning up...\c"
     # delete any temp files laying around...
     if [ -f "$LSTMP" ] ; then
          rm -f "$LSTMP"
     fi
     if [ -f "$LSTJOB" ] ; then
          rm -f "$LSTJOB"
     fi
     if [ -f "$LSTDIR2" ] ; then
          rm -f "$LSTDIR2"
     fi
     # Remove empty subdirs from output path...
     if [ "$REMEMPTY" -eq 1 ] ; then
          if [ -f "$LSTDIR" ] ; then
               while read TRYDIR
               do
                    DELDIR=`echo "$TRYDIR" | gawk  -v hdir="$SRCDIR" -v odir="$OUTDIR" ' {print gensub(hdir, odir, 1, $0)}'`
                    if [ -d "$DELDIR" ] ; then
                         rmdir -p --ignore-fail-on-non-empty "$DELDIR"
                    fi
               done < "$LSTDIR"
               rm -f "$LSTDIR"
          else
               if [ -d "$OUTDIR" ] ; then
                    rmdir --ignore-fail-on-non-empty "$OUTDIR"
               fi
          fi
     fi
     echo "done."
     # Show counts and exit gracefully
     echo "Operation completed...Final Stats:"
     echo "Attempted: $TRIED --  Skipped: $SKIPPED  Sucessful: $SUCCESS  Failed: $FAILED"
     if [ "$MP3CNT" -gt 0 ] ; then
          TOTOPS=$(($SKIPPED+$SUCCESS+$FAILED))
          ACCOM=`echo "scale=3;($TOTOPS/$MP3CNT)*100" | bc`
          echo "Total Given: $MP3CNT   Total Operations:  $TOTOPS  Total Accomplished: $ACCOM %"
     fi
     echo ""
     exit
}

killSrc() {
   if [ "$KILLMP3" == "Yes" ] ; then
      rm -f "$1"
   fi
}

# Verify user cli options and give chance to change or quit
verifyChoice() {
     echo "$1"
     select CHOICE2 in Yes No Cancel
     do
          case $CHOICE2 in
               Yes)  break ;;
               No)
                    TQUAL=
                    echo -e "$2 \c"
                    read UC ; break
                    ;;
               Cancel) echo "Cancelled."; exit ;;
               *) echo "Invalid option, $CHOICE2"
          esac
     done
     if [ "$3" -eq 0 ] ; then
        TQUAL="$UC"
     else
        KILLMP3="$UC"
     fi
}

# Check platform for programs needed, advise user if not found then die
chk4progs() {
     CHKCNT=0
     NOTFNDCNT=0
     echo -e "Checking system for necessary programs\c"
     for prog in mpg123 oggenc file normalize-audio mp3info gawk grep tr sed bc dirname basename ls mkdir rmdir ; do
          if [ -z "`which $prog 2> /dev/null`" ]; then
               NOTFNDCNT=$(($NOTFNDCNT+1))
               NOTFND[$NOTFNDCNT]="$prog"
          fi
         CHKCNT=$(($CHKCNT+1))
         if [ $CHKCNT = 3 ] ; then
               echo -e " \\244 \c"
               CHKCNT=0
         fi
     done
     if [ $NOTFNDCNT -gt 0 ] ; then
          echo "uh oh, you've got issues!"
          echo " "
          echo "    $NOTFNDCNT program(s) that are needed by this script were not found:"
          echo " "
          echo "              ${NOTFND[@]}"
          echo " "
          echo "    Install these program(s), and then try running this script again."
          echo "    If you think the program(s) are installed, then check your "\$PATH" variable"
          echo "    to make sure it lists the location that the binaries are in"
          echo "    and also that you have proper permissions to execute the program(s)."
          echo " "
          echo "Execution cannot continue, sorry."
          exit 1
     else
          echo "it's all good!"
     fi
}

# Retrieve ID3 tag info from source mp3 file
# I know this is a bit of a kludge, but it really is the best way I know of...
# TRACKINFO=`mp3info -p "%a@%c@%g@%l@%n@%t@%y@%r@%Q@%o" $1`
get_trackinfo() {
     #TSTMP3=`mp3info "$1" &>`
     #if echo "$TSTMP3" | grep "does not have" &> /dev/null ; then
     #     echo "--> No recognized ID3 tag info for this file..."
     #else
          TARTIST=`mp3info -p "%a" $1`
          TCOMMENT=`mp3info -p "%c" $1`
          TGENRE=`mp3info -p "%g" $1`
          TALBUM=`mp3info -p "%l" $1`
          TRACKNUM=`mp3info -p "%n" $1`
          TTITLE=`mp3info -p "%t" $1`
          TDATE=`mp3info -p "%y" $1`
     #fi
     TBITRATE=`mp3info -p "%r" $1`
     TFREQ=`mp3info -p "%Q" $1`
     TMODE=`mp3info -p "%o" $1`
     if [ "$TMODE" == "mono" ] ; then
          TCHAN=1
     else
          TCHAN=2
     fi
}

# Change UPPERCASE to lowercase and replace spaces with _
stripspc_caps() {
     OLDIFS="IFS"
     IFS=:
     MOD_NAME=`echo "$1" | gawk 'BEGIN { FS="@"} { print tolower($1) };' | tr '[:blank:]' '_'`
     IFS="$OLDIFS"
     return
}

# Strip punctuation
strippunc() {
     MOD_NAME=`echo "$1" | gawk '{ if ( $1 ~ /^[[:punct:]]/) {print substr($1, 2) ;} else { print $1 ;}}' | tr '!?":;\[\]{}(),' '.' | sed -e s/\&/and/g | sed -e s/\'//g | sed -e s/_w_/_and_/g | tr -s '[:punct:]'`
     return
}

# Check to see whether value given is valid for option, if not then die
isNum(){
     if [ "$1" == "" ]; then
          echo "Invalid parameter!"
          echo "Please use an integer value between 1 and 10...exiting."
          exit 1
     else
          if  echo "$1" | grep "[0-9]*" 1>/dev/null ; then
               if [ `echo "$1 <= 10" | bc` -eq 1 ] && [ `echo "$1 >= 1" | bc` -eq 1 ] ; then
                    encqual $1
                    if [ `echo "$1 > 6" | bc` -eq 1 ] ; then
                         printAdvisory 0 "$1"
                    fi
               return
               fi
          fi
          echo "It does not appear as though $1 is an allowed value for this option..."
          echo "Please use an integer value between 1 and 10...exiting."
          exit 1
     fi
}

#  Check to see whether file given appears to be an MP3 file or not unless overridden
isMP3() {
   if file -bn "$1" | grep -o "[mM][pP]*3" 2>&1> /dev/null ; then
      MP3OK=1
   elif [ "$VERIFY" -eq 0 ] ; then
      MP3OK=1
   else
      MP3OK=0
   fi 
}

#  normalize track if global default is set
equalize() {
   if [ "$NORM" -eq 1 ] ; then
      normalize-audio "$1"
   fi
}

#  Try to find or create a proper temp directory or else throw in the towel...
chktmp() {
     if [ ! -r "$TMPDIR" ] || [ ! -w "$TMPDIR" ] ; then
          echo -e "Can't use $TMPDIR for temp files, trying $HOME/tmp...\c"
          if [ "$TMPDIR" != "$HOME/tmp" ] && [ -r "$HOME/tmp" ]  && [ -w "$HOME/tmp" ] ; then
               TMPDIR="$HOME/tmp"
               echo "that works."
          else
               echo "nope."
               echo -e "Hmmm...how about /tmp?  \c"
               if  [ "$TMPDIR" != "/tmp" ] && [ -r "/tmp" ] && [ -w "/tmp" ] ; then
                    TMPDIR="/tmp"
                    echo "got it!"
               else
                    echo "no go."
                    echo -e "Alright, maybe we can make a temp then? \c"
                    if mkdir "$HOME/tmp" ; then
                         TMPDIR="$HOME/tmp"
                         echo "woohoo!"
                    else
                         echo "Cannot find a suitable directory for temporary files...giving up."
                         exit
                    fi
               fi
          fi
     fi
     echo "Using $TMPDIR for temp files..."
}

# Check to see that specfied file or directory exists and is writable, if not then warn
chkwrt() {
     if [ -w "$1" ] ; then
          return 0
     else
          echo "!!!AAGH!!! Unable to write to specified location: $1"
          echo "Please check that the directory exists and you have write access to it"
          echo "or choose another location..."
          if [ "$2" == "die" ] ; then
               echo "Execution cannnot continue, sorry."
               exit
          else
               return
          fi
     fi
}

# Check to see that specfied file or directory exists and is readable, if not then warn
chkrd() {
     if [ -r "$1" ] ; then
          return 0
     else
          echo "!!!DOH!!! Unable to read from specified location: $1"
          echo "Please check that the directory exists and you have read access to it"
          echo "or choose another location..."
          if [ "$2" == "die" ] ; then
               echo "Execution cannnot continue, sorry."
               exit
          else
               return
          fi
     fi
}

# Give readable value for numeric quality
encqual() {
     case $1 in
     "1")
          LEVEL="extremely low" ;;
     "2")
          LEVEL="really low" ;;
     "3")
          LEVEL="very low" ;;
     "4")
          LEVEL="low" ;;
     "5")
          LEVEL="medium" ;;
     "6")
          LEVEL="above medium" ;;
     "7")
          LEVEL="high" ;;
     "8")
          LEVEL="very high" ;;
     "9")
          LEVEL="super high" ;;
     "10")
          LEVEL="ultra high" ;;
     esac
}

# Warn about high encoding quality values
printAdvisory() {
     if [ "$ADVISE" -eq 1 ] ; then
        echo ""
        if [ "$1" -eq 0 ] ; then
           echo "    HEADS UP!"
           echo "    The level of encoding that you have specified ($2) will give you"
           echo "    $LEVEL quality media, but also will result in very large files"
           echo "    that will use more system resources for both storage and playback."
           echo "    Unless you are a serious audiophile that demands this level of"
           echo "    quality and you have a good system with plenty of resources,"
           echo "    I would suggest a lower value which would produce media"
           echo "    that still sounds good and is much more manageable."
           echo ""
           verifyChoice "Do you really wish to encode at this level?" "Enter quality to encode at [1-10]" 0
        else
            echo "   WHOA THERE, PARDNER!"
            echo "   You have chosen to delete all source mp3 files after they have"
            echo "   been encoded to ogg before having a chance to verify that the"
            echo "   encoded oggs are ok.  Unless you have a backup of the source mp3"
            echo "   files or have that much faith in this script, this might not be a"
            echo "   wise thing to do."       
            echo ""
            verifyChoice "Are you sure you want to delete the source files?" "Enter 0 if you don't or 1 if you do" 1
        fi
    fi
}


# Nifty formatting code "borrowed" from Mandrake's init script...
printCol() {
     # column to start in
     PRTCOL="$1"
     # move to specified column and print text without return
     echo -en "\033[${PRTCOL}G $2\c"
     return
}

# Just a simple spinner to use up CPU cycles unneccessarily...
setSpin() {
     case "$1" in
          "1" | "4" )
               SSPIN=' | ' ;;
          "2" )
               SSPIN=' / ' ;;
          "3" )
               SSPIN=' - ' ;;
          "5" )
               SSPIN=' \ ' ;;
     esac
     return
}

# ======================== END FUNCTION SECTION ========================

# ==================== VARIABLE DECLARATION SECTION ====================

TRIED=0
SUCCESS=0
FAILED=0
SKIPPED=0
TRACKINFO=
TARTIST=
TCOMMENT=
TGENRE=
TALBUM=
TRACKNUM=
TTITLE=
TDATE=
TBITRATE=
TQUAL=
MOD_NAME=
TRACK=
SRCTRACK=
OGGTRACK=
MP3OK=


# ================ END VARIABLE DECLARATION SECTION ==============

# +--------------------------------------------------------------------------------------------------+
# +                                            BEGIN SCRIPT                                                      +
# +--------------------------------------------------------------------------------------------------+
# Show "Splash"...
echo "               -=-=MP3 TO OGG CONVERSION SCRIPT=-=-"
# Can we run on this system?
chk4progs
chktmp
echo ""

# Check if enough cli parameters were passed, at least one is expected
if [ "$#" -lt 1 ]; then
     echo "    EXPECTED USAGE: mp3-ogg [-f|--force ][-q|--quality <n> ][-r|--recurse </path> ][-s|--sort ][-o|--outdir </path> ] /path/to/[mp3 file(s)]"
     echo "    Use -h or --help to print help."
     echo "No files specified...exiting."
     exit 1
else
     #  Parse cli parameters for options and values
     if [ "$REPLMODE" -eq 1 ] ; then
               ADVISE=0
               chkrd "$1" "die"
               SRCDIR="$1"
               shift 1
     fi
     case "$1" in
          -r | --recurse )
               REPLMODE=1 ;
               ADVISE=0 ;
               chkrd "$2" "die" ;
               SRCDIR="$2" ;
               shift 2 ;;
     esac
     case "$1" in
          -n | --no-advise )
               ADVISE=0 ;
               shift 1 ;;
     esac
     case "$1" in
          -f | --force )
               VERIFY=0 ;
               shift 1 ;;
     esac
     case "$1" in
          -k | --killsrc )
               KILLMP3="YES" ;
               shift 1 ;;
     esac
     case "$1" in
          -q | --quality )
               isNum $2 ;
               TQUAL="$2" ;
               shift 2 ;;
          -h | --help)
               printHelp ;
               exit 0 ;;
      esac
      case "$1" in
          -s | --sort )
               SORTOGG=1 ;
               shift 1 ;;
      esac
      case "$1" in
          -o | --outdir )
               chkwrt "$2" "die" ;
               OUTDIR="$2" ;
               shift 2 ;;
      esac
fi
if [ "$KILLMP3" == "YES" ] && [ "$ADVISE" -eq 1 ] ; then
   printAdvisory 1
fi
MP3CNT="$#"
# If no user-specified quality is given, then use default value
if [ -z "$TQUAL" ] ; then
    TQUAL="$OGGQUAL"
    encqual "$TQUAL"
fi

if [ "$REPLMODE" -eq 0 ] ; then
     echo "--> Standard Mode Selected"
     if [ "$MP3CNT" -lt 1 ]; then
          echo "EXPECTED USAGE: mp3-ogg [-f|--force ][-q|--quality <n> ][-r|--recurse </path> ][-s|--sort ][-o|--outdir </path> ] /path/to/[mp3 file(s)]"
          echo "    Use -h or --help to print help."
          echo "No files specified...exiting."
          exit 1
     fi
     # Display number of filenames given
     echo "--> $MP3CNT filename(s) given..."
     trap CleanUp 1 2 3  9 15
     # Commence the dance...
     for TRACK in "$@"
     do
          # Check to see whether the file is an MP3 file, skip if not...
          isMP3 "$TRACK"
          if [ "$MP3OK" -eq 1 ] ; then
               OGGDIR=
               SRCDIR=`dirname "$TRACK"`
               # Use source directory if not otherwise specified, else use that
               if [ -z "$OUTDIR" ] ; then
                    OGGDIR="$SRCDIR"
               else
                    OGGDIR="$OUTDIR"
               fi
               # This might seem silly, but it is necessary for cleanup...
               OUTDIR="$OGGDIR"
               # Check to see that output directory exists and is writable, if not then warn and try anyway
               chkwrt "$OGGDIR"
               get_trackinfo "$TRACK"
               # Check if sort is enabled, create sort subdirs if so and append to output dir
               if [ "$SORTOGG" -eq 1 ] ; then
                    echo "--> Sort is enabled..."
                    # CREATE SORT SUB-DIRECTORY STRUCTURE IF NOT ALREADY PRESENT
                    if [ ! -d "$OGGDIR" ]; then
                         mkdir -v "$OGGDIR"
                    fi
                    if [ -n "$TGENRE" ] ; then
                         stripspc_caps "$TGENRE"
                         strippunc "$MOD_NAME"
                         GENREDIR="$MOD_NAME"
                         if [ ! -d "$OGGDIR"/"$GENREDIR" ]; then
                              mkdir -v "$OGGDIR"/"$GENREDIR"
                         fi
                         OGGDIR="$OGGDIR"/"$GENREDIR"
                    fi
                    if [ -n "$TARTIST" ] ; then
                         stripspc_caps "$TARTIST"
                         strippunc "$MOD_NAME"
                         ARTISTDIR="$MOD_NAME"
                         if [ ! -d "$OGGDIR"/"$ARTISTDIR" ]; then
                              mkdir -v "$OGGDIR"/"$ARTISTDIR"
                         fi
                         OGGDIR="$OGGDIR"/"$ARTISTDIR"
                    fi
                    if [ -n "$TALBUM" ] ; then
                         stripspc_caps "$TALBUM"
                         strippunc "$MOD_NAME"
                         ALBUMDIR="$MOD_NAME"
                         if [ ! -d "$OGGDIR"/"$ALBUMDIR" ]; then
                              mkdir -v "$OGGDIR"/"$ALBUMDIR"
                         fi
                         OGGDIR="$OGGDIR"/"$ALBUMDIR"
                    fi
               fi
               # Clean up output filename and append to output dir
               SRCTRACK=`basename "$TRACK"`
               stripspc_caps "$SRCTRACK"
               strippunc "$MOD_NAME"
               OGGTRACK="$OGGDIR/`basename "$MOD_NAME" mp3`ogg"
               TRIED=$((TRIED += 1))
               # Check to see if output file already exists, skip if so
               if [ -f "$OGGTRACK" ] ; then
                    echo "--> $TRACK appears to have already been encoded to ogg...skipping"
                    SKIPPED=$((SKIPPED += 1))
                    continue
               else
                    # Here's the money shot...
                    equalize "$TRACK"
                    echo "--> Encoding `basename "$TRACK"` to ogg  $TFREQ Hz, $TBITRATE Kbps, $TMODE ($TCHAN chan) at quality $TQUAL ($LEVEL)"
                    mpg123 -b "$MP3BUFF" -q -y -s "$TRACK" | oggenc - -r -C "$TCHAN" -R "$TFREQ"  -b "$TBITRATE" -q "$TQUAL" -o "$OGGTRACK" -a "$TARTIST" -c "$TCOMMENT" -G "$TGENRE" -l "$TALBUM" -N "$TRACKNUM" -t "$TTITLE" -d "$TDATE" &
                    wait
                    # Check to see if encoding seems to have completed ok or not, log results
                    if [ $? -eq 0 ]; then
                         SUCCESS=$((SUCCESS += 1))
                         echo "--> Encoding of `basename $TRACK` to `basename $OGGTRACK` completed successfully."
                         killSrc "$TRACK"
                    else
                         FAILED=$((FAILED += 1))
                         echo "--> Encoding of `basename $TRACK` to `basename $OGGTRACK` failed!"
                    fi
               fi
          else
               echo "--> $TRACK does not appear to be an mp3 file...skipping"
               SKIPPED=$((SKIPPED += 1))
               continue
          fi
     done
#  THIS IS THE BEGINNING OF R&R MODE
elif [ "$REPLMODE" -eq 1 ] ; then
     echo "--> Recurse and Replication Mode Selected"
     if [ ! -d "$SRCDIR" ] ; then
          echo "ERROR - Invalid directory!"
          echo "You must specify a source directory for this option."
          echo "quitting..."
          exit
     else
          echo "--> Input Path:  $SRCDIR      Output Path:  $OUTDIR"
     fi
     LSTMP="$TMPDIR/tmpdirlst$$"
     LSTJOB="$TMPDIR/tmpjoblst$$"
     LSTDIR="$TMPDIR/tmpdir1job$$"
     LSTDIR2="$TMPDIR/tmpdir2job$$"
     DIRCNT=0
     MP3CNT=0
     CRTCNT=0
     if [ "$SORTOGG" -eq 1 ] ; then
          echo "--> Sort is enabled but ignored in this mode"
     fi
     if [ -d "$SRCDIR" ] ; then
          echo -e "--> Retrieving directory tree list...\c"
               ls -R1 "$SRCDIR" > """$LSTMP"""
          echo "ok"
     fi
     trap CleanUp 1 2 3  9 15
     echo "--> R&R Mode Phase 1:  Searching for mp3 files and building job lists..."
     while read NXTLN
     do
          if [ ${#NXTLN} -gt 1 ] ; then
               if [ -d "`echo "$NXTLN" | tr -d ":"`" ] ; then
                    #echo "found directory..."
                    DIRCNT=$(($DIRCNT+1))
                    ORGDIR=`echo "$NXTLN" | tr -d ":"`
                    echo "$ORGDIR" >> "$LSTDIR2"
               elif [ -f "$ORGDIR/$NXTLN" ] ; then
                    NXTFILE="$ORGDIR/$NXTLN"
                    isMP3 "$NXTFILE"
                    if [ "$MP3OK" -eq 1 ] ; then
                         MP3CNT=$(($MP3CNT+1))
                         echo "$NXTFILE" >> "$LSTJOB"
                    fi
               else
                    continue
               fi
          else
               continue
          fi
          printCol 1 "-->   $MP3CNT mp3 files found    $DIRCNT directories searched"
     done < "$LSTMP"
     rm -f "$LSTMP"
     echo ""
     # Is it worth it to continue?
     if [ "$MP3CNT" -lt 1 ] ; then
          echo "Whoops!  No MP3 files were found to encode from the specified path"
          echo "Nothing more to do here...quitting."
          CleanUp
     fi
     # Trim Directory List down to those that actually contain MP3 Files...
     CHKCNT=0
     while read CMPDIR
     do
          CHKCNT=$(($CHKCNT+1))
          setSpin "$CHKCNT"
          printCol 1 "--> Cleaning unnecessary directories from list, this may take a while... $SSPIN  "
          if [ "$CHKCNT" -eq 5 ] ; then
               CHKCNT=0
          fi
          if [ -n "`grep -o "$CMPDIR" "$LSTJOB"`" ] ; then
               echo "$CMPDIR" >> "$LSTDIR"
          fi
     done < "$LSTDIR2"
     echo "all clean"
     rm -f "$LSTDIR2" "$LSTMP"
     DIRCNT=`wc -l "$LSTDIR" | gawk '{ print $1}'`
     #echo "--> Dirs to Replicate: $DIRCNT  MP3 Files Found: $MP3CNT"
     echo "--> R&R Mode Phase 2:  Replicating directory tree..."
     chkwrt "$OUTDIR" "die"
     while read NXTLN
     do
          if [ ${#NXTLN} -gt 1 ] ; then
               if [ -d "$NXTLN"  ] ; then
                    #echo "found directory..."
                    DIRCNT=$(($DIRCNT+1))
                    ORGDIR=`echo "$NXTLN" | tr -d ":"`
                    NXTDIR=`echo "$ORGDIR" | gawk  -v hdir="$SRCDIR" -v odir="$OUTDIR" ' {print gensub(hdir, odir, 1, $0)}'`
                    if [ ! -d "$NXTDIR" ] ; then
                         printCol 2 "creating $NXTDIR"
                         if mkdir "$NXTDIR" ; then
                              printCol 75 "ok"
                              CRTCNT=$(($CRTCNT+1))
                         else
                              printCol 75  "failed!"
                         fi
                    elif [ -d "$NXTDIR" ] ; then
                         EXTCNT=$(($EXTCNT+1))
                    fi
               else
                    continue
               fi
          else
               continue
          fi
     done < "$LSTDIR"
     QCNT=`wc -l "$LSTJOB" | gawk '{ print $1}'`
     echo ""
     echo "--> Dirs Replicated: $CRTCNT  Dirs Existing: $EXTCNT  MP3 Files queued for Encoding: $QCNT"
     # Commence the dance...
     echo "--> R&R Mode Phase 3:  Encoding Queued MP3's to OGG Format..."
     while read TRACK
     do
          # Check (again) to see whether the file is an MP3 file, skip if not...
          isMP3 "$TRACK"
          if [ "$MP3OK" -eq 1 ] ; then
               TRKDIR=`dirname "$TRACK"`
               OGGDIR=`echo "$TRKDIR" | gawk -v hdir="$SRCDIR" -v odir="$OUTDIR" ' {print gensub(hdir, odir, 1, $0)}'`
               # Check to see that output directory exists and is writable, if not then warn and try anyway
               chkwrt "$OGGDIR"
               get_trackinfo "$TRACK"
               # Clean up output filename and append to output dir
               SRCTRACK=`basename "$TRACK"`
               stripspc_caps "$SRCTRACK"
               strippunc "$MOD_NAME"
               OGGTRACK="$OGGDIR/`basename "$MOD_NAME" mp3`ogg"
               TRIED=$((TRIED += 1))
               # Check to see if output file already exists, skip if so
               if [ -f "$OGGTRACK" ] ; then
                    echo "--> $TRACK appears to have already been encoded to ogg...skipping"
                    SKIPPED=$((SKIPPED += 1))
                    continue
               else
                    # Here's the money shot...
                    equalize "$TRACK"
                    echo "--> Encoding `basename "$TRACK"` to ogg  $TFREQ Hz, $TBITRATE Kbps, $TMODE ($TCHAN chan) at quality $TQUAL ($LEVEL)"
                    OLDIFS="IFS"
                    IFS=|
                    mpg123 -b "$MP3BUFF" -q -y -s "$TRACK" | oggenc - -r -C "$TCHAN" -R "$TFREQ"  -b "$TBITRATE" -q "$TQUAL" -o "$OGGTRACK" -a "$TARTIST" -c "$TCOMMENT" -G "$TGENRE" -l "$TALBUM" -N "$TRACKNUM" -t "$TTITLE" -d "$TDATE" &
                    wait
                    # Check to see if encoding seems to have completed ok or not, log results
                    if [ $? -eq 0 ]; then
                         SUCCESS=$((SUCCESS += 1))
                         echo "--> Encoding of `basename $TRACK` to `basename $OGGTRACK` completed successfully."
                    else
                         FAILED=$((FAILED += 1))
                         echo "--> Encoding of `basename $TRACK` to `basename $OGGTRACK` failed!"
                    fi
                    IFS="$OLDIFS"
               fi
          else
               echo "--> $TRACK does not appear to be an mp3 file...skipping"
               SKIPPED=$((SKIPPED += 1))
               continue
          fi
     done < "$LSTJOB"
fi
CleanUp
# +------------------------------------------------- END SCRIPT ----------------------------------------+



Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP