Register
It is currently Sun Apr 20, 2014 11:03 pm

mod2avi - convert JVC Everio .mod files into XviD .avi files


All times are UTC - 6 hours


Post new topic Reply to topic  [ 8 posts ] 
Author Message
 PostPosted: Tue May 13, 2008 1:18 am   

Joined: Tue May 13, 2008 1:04 am
Posts: 4
I figured I'd post this script I wrote, the OSS community has helped me out many times over the years, I figured I should start giving back. :)

My brother owns a JVC Everio HDD camcorder that records in .MOD format. This is a type of MPEG2 stream that most DivX-enabled DVD players won't recognize. I created a bash script that uses ffmpeg to convert MOD files into the much more popular AVI format. I hope it helps someone!

To install, copy/paste the code below and with root permissions save it to /usr/local/bin/mod2avi. Change it to the proper owner ('chown root:root /usr/local/bin/mod2avi'), make it executable ('chmod 755 /usr/local/bin/mod2avi') and you're good to go, so long as you have ffmpeg installed already. Type mod2avi for usage information.

For AVI files that nearly match the original quality (and file size) of the MOD files, use 4500k/192 as your audio/video settings. If you plan on posting the videos on YouTube or e-mailing, try 500k/128 or lower values until you find a file size that works for you.

Code:
#/bin/bash
# mod2avi - convert JVC Everio .mod files into XviD .avi files
# uses ffmpeg to convert video files

# if no parameters are passed, display usage information
if [ "$1" = "" ]; then
  echo "mod2avi - convert JVC Everio .mod files into XviD .avi files"
  echo "usage:";
  echo " mod2avi [video bitrate] [audio bitrate] files.."
  echo "example:"
  echo " mod2avi 1800k 64 mov019.mod mov025.mod"
  echo " mod2avi 4500k 192 *.mod"
  exit 0
fi

# get parameters
videob=$1;
audiob=$2; shift ; shift ;

# error checking
if [ "$1" = "" ]; then
   echo "mod2avi: error: no files given"
   exit 0
fi

# perform the convert operation
for file in $*
  do
  avifile=${file%.mod}.avi
  echo "Converting $file..."
  ffmpeg -i ${file} -b $videob -ab $audiob -acodec mp3 -vcodec xvid $avifile;
  echo "Done!"
done

# done!
exit 0

# EOF


PS: This is my first bash script, if anyone has suggestions or corrections please don't hesitate to reply.


Last edited by Dylan Cooke on Sun May 18, 2008 1:33 am, edited 2 times in total.

Top
 Profile  
 PostPosted: Thu May 15, 2008 11:24 am   

Joined: Tue Apr 01, 2008 10:19 am
Posts: 49
Just as an (insignificant) note: these sort of things should be installed to /usr/local/bin, rather than /usr/bin, according to the FHS. How much this matters is entirely dependant on your system and personal preference.
Regardless of where you put it, you must also chown root:root mod2avi, to make sure it has the correct ownership.

Code:
#!/bin/bash
# mod2avi - convert JVC Everio .mod files into XviD .avi files
# uses ffmpeg to convert video files

if [ $# -lt 3 ]; then
  echo "$(basename $0) - convert JVC Everio .mod files into XviD .avi files"
  echo "Usage:"
  echo " $(basename $0) [video bitrate] [audio bitrate] files.."
  echo "Examples:"
  echo " $(basename $0) 1800k 64 mov019.mod mov025.mod"
  echo " $(basename $0) 4500k 192 *.mod"
  exit 0
fi

videob=$1
audiob=$2
shift 2


# perform the convert operation
for file in $@; do
  if [ ! -r "$file" ]; then
     echo "$(basename $0): error: could not read file '$file'"
     continue
  fi

  avifile=${file%.mod}.avi
  echo "Converting $file..."
  ffmpeg -i "$file" -b $videob -ab $audiob -acodec mp3 -vcodec xvid "$avifile"
  echo "Done!"
done

# done!
exit 0

# EOF


One thing you might want to add is a check to make sure that the target (foo.avi) file does not exist, and if it does, handle it well.
Also, you may wish to hardcode the path to ffmpeg, so that it can't be redirected to another utility. It doesn't matter with this script (in its current form), but it is a good habit to get into.

Hope this helps!


Top
 Profile  
 PostPosted: Sun May 18, 2008 1:25 am   

Joined: Tue May 13, 2008 1:04 am
Posts: 4
Daenyth,

Thanks for the tips! I've edited the post above to say /usr/local/bin, I actually had installed it at that location on my system originally but had a bit of a brain fart when posting.

By the way, thanks for going through my script and tweaking it as you have, I really appreciate it. :) If you don't mind, I'd like to ask a couple questions about how to implement your other suggestions.

What is the best way to check if foo.avi exists? Based on some quick googling, I assume it would be something like this (after the avifile= statement):
Code:
  if [ -f "$avifile" ]; then
     read -p "AVI File exists already, overwrite? (yes/no) -> " UserChoice
     if [ "$UserChoice" = "no"]; then
        echo "Skipping conversion..."
        next
     fi
     continue
  fi


I think that concept will work, I know I'm missing one critical command though. Where I have 'next' above is likely not what I need, what I want to do is skip the conversion of the file that bash is currently working with, so logically (being a BASIC programmer at heart) I typed 'next'. At least I didn't type 'goto'. :)

Daenyth, would you or someone else be able to help me with this? I'm sure I could find the answer after doing some more reading, but I learn much quicker by example and hands-on experience. :)

I also have one other question is regarding the path to ffmpeg. Should I simply enter it as /usr/bin/ffmpeg in the script, or should I use some sort of 'find' command (probably 'which') that finds the proper executable?

Thanks!


Top
 Profile  
 PostPosted: Mon May 19, 2008 11:02 am   

Joined: Tue Apr 01, 2008 10:19 am
Posts: 49
Dylan Cooke wrote:
What is the best way to check if foo.avi exists? Based on some quick googling, I assume it would be something like this (after the avifile= statement):
Code:
  if [ -f "$avifile" ]; then
     read -p "AVI File exists already, overwrite? (yes/no) -> " UserChoice
     if [ "$UserChoice" = "no"]; then
        echo "Skipping conversion..."
        next
     fi
     continue
  fi

I think that concept will work, I know I'm missing one critical command though. Where I have 'next' above is likely not what I need, what I want to do is skip the conversion of the file that bash is currently working with, so logically (being a BASIC programmer at heart) I typed 'next'. At least I didn't type 'goto'. :)


Using "-f" is perfectly correct here. Rather than "next", you would use "continue". I'll also tweak this
Code:
  if [ -f "$avifile" ]; then
     read -p "AVI File exists already, overwrite? (yes/no) [no] -> " UserChoice
       # Using [] to display a default is fairly standard
     if [ "$UserChoice" != "yes" ]; then # Make sure to have a space before ]
          # Better to assume not to overwrite unlss explicitly instructed
        echo "Skipping conversion..."
        continue
     fi
  fi


Quote:
Daenyth, would you or someone else be able to help me with this? I'm sure I could find the answer after doing some more reading, but I learn much quicker by example and hands-on experience. :)
I'm the same way, hopefully this place helps you out. I would also recommend reading this. I always recommend it to new bash scripters. Some of it you won't need, but it is helpful. You can also google for "advanced bash scripting guide" if you're ready to learn more.

Quote:
I also have one other question is regarding the path to ffmpeg. Should I simply enter it as /usr/bin/ffmpeg in the script, or should I use some sort of 'find' command (probably 'which') that finds the proper executable?

Thanks!

The usual method is to hardcode the path (perhaps as a variable), and let the user modify the script as needed. For example:
Code:
ffmpegbin='/usr/bin/ffmpeg'
$ffmpegbin -flags files.foo



Good luck with your coding!


Top
 Profile  
 PostPosted: Tue May 20, 2008 11:59 pm   

Joined: Tue May 13, 2008 1:04 am
Posts: 4
I decided to jump in a bit deeper and give this script a few features. I'm actually planning on putting it on a SourceForge page when it's done so it's more accessible. I've noticed there are many people out there that could use this script so I figured I'd get it out there. :)

I've made the script more configurable and also more along the lines of a traditional conversion script. I'm sure it could use a lot of tweaking though, not to mention a few bug fixes before it's ready for production use. I should add, this is still my first bash script so try to go easy on me, hehehe.

One bug I've identified is the script doesn't handle filenames with spaces, at all. It errors out in the error-checking routine saying it can't read the file. This happens at line 79 and at line 222.

Other than that it seems to work well. I've tested all the options and they all work to my knowledge. I would love if someone could test the script in various instances and provide feedback on it. Don't worry if you don't have any MOD files, the script will work just as well with MPG files.

Here's the full text of the script:
Code:
#!/bin/bash
# mod2avi - convert JVC Everio .mod files into XviD .avi files
# This software is licensed under the GNU General Public License
# For the full text of the GNU GPL, see: http://www.gnu.org/copyleft/gpl.html
# No guarantees of any kind are associated with use of this software.
# requirements: ffmpeg

# known bugs: - filenames with spaces can't be processed


# Script settings (feel free to change these)
ffmpegbin="/usr/bin/ffmpeg"      # Location of FFMpeg binary
vcodec="xvid"                    # Default value: video codec (xvid)
vfps="29.97"                     # Default value: FPS (29.97)
vsize="720x480"                  # Default value: frame size (720x480)
videob="4500k"                   # Default value: video bitrate (4500k)
acodec="mp3"                     # Default value: audio codec (mp3)
audiob="192k"                    # Default value: audio bitrate (192)
audiof="48000"                   # Default value: audio frequency (48000)
noaudio="0"                      # Default value: enable/disable audio (0)
mono="0"                         # Default value: enable/disable stereo by default (0)
deletefiles="0"                  # Default value: enable/disable file deletion (0)
quietmode="0"                    # Default value: enable/disable quiet mode (0)

# Variable initializations (do not change these)
filecount=0                      # Counter for number of files processed
version="v0.3b"                  # Script version number
vdate="May 20th/2008"            # Script date
profile="default"                # Storage for profile name only (not a setting)

# Declare functions before the script begins

help_about()
# This function displays the help/about screen
{
  echo "$(basename $0) $version $vdate"
  echo
  echo "Usage:  $(basename $0) [-options] files.."
  echo "  Converts video files from MOD format into AVI format."
  echo "  -h (show help/about screen)"
  echo "  -r [frame rate] (default 29.97)"
  echo "  -s [frame size] (default 720x480)"
  echo "  -v [video bitrate] (default 4500k)"
  echo "  -a [audio bitrate] (default 192k)"
  echo "  -f [audio frequency] (default 48000)"
  echo "  -n (no audio in resulting file)"
  echo "  -m (mono mode, default is stereo)"
  echo "  -d (delete original MOD files)"
  echo "  -q (quiet mode, suppress output)"
  echo "  -o (only rename files to MPEG, do not re-encode)"
  echo "  -p [profile name] (highqual, youtube, email)"
  echo "  files.mod (wildcards supported)"
  echo
  echo "Profiles:"
  echo "  highqual - 29.97fps, 720x480, 4500kbit video, 192kbit audio, 48khz, stereo"
  echo "  youtube  - 25fps, 320x240, 2500kbit video, 128kbit audio, 44khz, stereo"
  echo "  email    - 12fps, 256x224, 200kbit video, 64kbit audio, 22khz, mono"
  echo
  echo "Examples:"
  echo "  Convert using defaults (makes high quality files):"
  echo "    $ $(basename $0) *.mod"
  echo "  Convert for posting on YouTube (medium quality files):"
  echo "    $ $(basename $0) -p youtube mov014.mod mov015.mod"
  echo "  Convert with custom encoding options:"
  echo "    $ $(basename $0) -r 24 -s 640x480 -v 6500k -a 256k -f 44100 *.mod"
  echo "  Rename to MPG only (do not convert):"
  echo "    $ $(basename $0) -o *.mod"
  exit 1
} #help_about()

mpegonly()
# MPEG only function - if called it ignores the rest of the script and simply renames the MOD files to MPG
{
  if [ "$quietmode" = "0" ]; then
    echo "$(basename $0) $version $vdate"         # Show script name, version and date
    echo "[] `date`"                              # Show current date
    echo "[] Renaming files to .mpg instead of converting..."
  fi

  for file in $@; do
    if [ ! -r "$file" ]; then                     # Can we read the MOD file?
      if [ "$quietmode" = "0" ]; then             # If not, indicate the error if not in quiet mode
        echo "[] Error: could not read file '$file'"
      fi
      continue                                    # Move on to next file
    fi
    mv $file ${file%.mod}.mpg                     # Rename .mod file to .mpg
    ((filecount++))                               # Increase file counter
  done                                            # Proceed until done renaming all .mod files

  if [ "$quietmode" = "0" ]; then
    echo "[] Renamed $filecount files."           # Display done message
  fi

  exit 0                                          # Exit happily :)
} #mpegonly()

set_highqual()
# Set high quality encoding options
{
  vfps="29.97"
  vsize="720x480"
  videob="4500k"
  audiob="192k"
  audiof="48000"
  profile="High quality"
} #set_highqual()

set_youtube()
# Set YouTube quality encoding options
{
  vfps="25"
  vsize="320x240"
  videob="2500k"
  audiob="128k"
  audiof="44100"
  profile="YouTube"
} #set_youtube()

set_email()
# Set E-mail quality encoding options
{
  vfps="12"
  vsize="256x224"
  videob="200k"
  audiob="64k"
  audiof="22050"
  mono="1"
  profile="E-mail"
}

ask_delete()
# Ensure the user wants to delete his/her MOD files after encoding
{
  echo "[] WARNING: Your original MOD files will be deleted after encoding."
  read -p "[] Are you sure you want these files deleted? (yes/no) [no] -> " UserChoice
  case $UserChoice in                             # Only continue if y/yes were entered
           y) continue;;                          # If y, continue
           yes) continue;;                        # If yes, continue
           *)  echo "[] Operation aborted."       # Display aborted message
               exit 0;;                           # Exit script
  esac
}


# Script begins here
if [ "$1" = "" ]; then                            # Was the command typed without any parameters?
  help_about                                      # If so, display help/about screen and exit
fi

# Parse any options passed to the script
while getopts "hr:s:v:a:f:nmdqop:" opt            # Get command-line options
do                                                # Begin analysis loop
        case $opt in                              # Analyze the option detected
                q) quietmode="1";;                # Enable quiet mode if selected
                h) help_about;;                   # Display help/about screen
                r) vfps="$OPTARG";;               # Set video fps
                s) vsize="$OPTARG";;              # Set frame size
                v) videob="$OPTARG";;             # Set video bitrate
                a) audiob="$OPTARG";;             # Set audio bitrate
                f) audiof="$OPTARG";;             # Set audio frequency
                n) noaudio="1";;                  # Disable audio
                m) mono="1";;                     # Disable stereo mode
                d) deletefiles="1";;              # Enable file deletion
                o) shift $(($OPTIND - 1))         # Shift off the options
                   mpegonly $@;;                  # Rename files to MPG
                p) {                              # Enable profile if specified
                   case $OPTARG in                # Check which profile was specified
                      "highqual") set_highqual;;  # High quality profile
                      "youtube") set_youtube;;    # YouTube quality profile
                      "email") set_email;;        # E-mail quality profile
                      "e-mail") set_email;;       # In case someone uses a hyphen
                      *) set_highqual;;           # Missing/invalid specification, use high quality
                   esac                           # Done checking profiles
                   };;                            # End of profile option code
        esac                                      # Done analyzing options
done                                              # End the analysis loop
shift $(($OPTIND - 1))                            # Now we want to work with the files

# Build FFMpeg options
ffmpegopts="-vcodec $vcodec -r $vfps -s $vsize -b $videob -acodec $acodec -ab $audiob -ar $audiof -deinterlace"

# Enable mono mode if specified
if [ "$mono" = "1" ]; then
  ffmpegopts="$ffmpegopts -ac 1"
fi

# Disable audio if specified
if [ "$noaudio" = "1" ]; then
  ffmpegopts="$ffmpegopts -an"
fi

# Display encoding settings if quiet mode is off
if [ "$quietmode" = "0" ]; then
  echo "$(basename $0) $version $vdate"           # Show script name, version and date
  echo "[] `date`"                                # Show current date
  if [ "$profile" != "default" ]; then            # If we are using the non-default profile,
    echo "[] Profile selected: $profile"          # Show the profile name
  fi
  echo "[] Frame rate: $vfps"                     # Show FPS
  echo "[] Frame size: $vsize"                    # Show frame size
  echo "[] Video bitrate: $videob"                # Show video bitrate
  echo "[] Audio bitrate: $audiob"                # Show audio bitrate
  echo "[] Audio frequency: $audiof"              # Show audio frequency
  echo "[] Video codec: $vcodec"                  # Show video codec
  if [ "$noaudio" = "0" ]; then                   # If audio is enabled,
    echo "[] Audio codec: $acodec"                # Show audio codec
  else
    echo "[] Audio codec: disabled"               # Show codec disabled
  fi
  if [ "$mono" = "0" ]; then                      # Display stereo: yes/no
    echo "[] Stereo: yes"
  else
    echo "[] Stereo: no"
  fi
fi                                                # Done listing settings if not in quiet mode

# If the user specified to delete files, ensure they meant it
if [ "$deletefiles" = "1" ]; then                 # If file deletion is enabled
  ask_delete                                      # Make sure the user wants to delete their files
fi

# Begin the conversion operation
for file in $@; do
  if [ ! -r "$file" ]; then                       # Can we read the MOD file?
     if [ "$quietmode" = "0" ]; then
       echo "[] Error: could not read file '$file'"
     fi
     continue                                     # Move on to next file
  fi

  avifile=${file%.mod}.avi                        # Set AVI filename based on MOD filename

  if [ "$quietmode" = "0" ]; then                 # Are we in quiet mode?
    echo "[] Converting $file..."                 # If not, display converting message
    $ffmpegbin -i "$file" $ffmpegopts "$avifile"  # Issue the ffmpeg command to convert
    echo "[] Done converting $file!"              # And display finished message
  else                                            # Otherwise, issue ffpmeg command to convert
    $ffmpegbin -i "$file" $ffmpegopts "$avifile" 2> /dev/null # And supress ffmpeg output
  fi

  if [ "$deletefiles" = "1" ]; then               # Should we delete files?
    rm $file                                      # If so, delete this file
    if [ "$quietmode" = "0" ]; then               # And log the deletion if not in quiet mode
      echo "[] Deleted $file."
    fi
  fi

  ((filecount++))                                 # Increase file counter
done                                              # Continue converting until done

# We're done!
if [ "$quietmode" = "0" ]; then
  echo "[] Number of files converted: $filecount" # Display number of files converted
  echo
fi

exit 0                                            # Exit happily :)

# EOF


Top
 Profile  
 PostPosted: Wed May 21, 2008 3:53 am   
Moderator
User avatar

Joined: Thu Oct 11, 2007 7:12 am
Posts: 224
Location: London - UK
This is almost always caused by not quoting variables correctly, for example...

Code:
  one='my file.txt'
  two='my newfile.txt'
  mv $one $two


the 3rd line would actually translate to...
Code:
  mv my file.txt my newfile.txt


Clearly not what's intended :)
Instead ensure they are quoted appropriately...
Code:
  mv "$one" "$two"


That should now handle spaces correctly, I hope that helps :)


Top
 Profile  
 PostPosted: Wed May 21, 2008 11:03 am   

Joined: Tue Apr 01, 2008 10:19 am
Posts: 49
Dylan Cooke wrote:
I decided to jump in a bit deeper and give this script a few features. I'm actually planning on putting it on a SourceForge page when it's done so it's more accessible. I've noticed there are many people out there that could use this script so I figured I'd get it out there. :)

I've made the script more configurable and also more along the lines of a traditional conversion script. I'm sure it could use a lot of tweaking though, not to mention a few bug fixes before it's ready for production use. I should add, this is still my first bash script so try to go easy on me, hehehe.

One bug I've identified is the script doesn't handle filenames with spaces, at all. It errors out in the error-checking routine saying it can't read the file. This happens at line 79 and at line 222.

Other than that it seems to work well. I've tested all the options and they all work to my knowledge. I would love if someone could test the script in various instances and provide feedback on it. Don't worry if you don't have any MOD files, the script will work just as well with MPG files.

Absolutely fantastic work! Keep it up, you're on to something really good here. Please don't take the following as criticism, because you're doing great!

With the length of the script growing, you might want to start using something other than <code>. Try http://pastebin.ca, as they also offer syntax highlighting. It will also allow easier downloads for people interested in using it, and we can use those to post diffs, so that any tweaks people want to show are easier to find.

One note here that I won't bother changing below: When you are using a literal string in a variable, use ' rather than ", to deny (accidental) variable interpolation. It's mostly a cosmetic/code style thing, but I find that it helps. YMMV
Quote:
Here's the full text of the script:
Code:
#!/bin/bash
# mod2avi - convert JVC Everio .mod files into XviD .avi files
# This software is licensed under the GNU General Public License
# For the full text of the GNU GPL, see: http://www.gnu.org/copyleft/gpl.html
# No guarantees of any kind are associated with use of this software.
# requirements: ffmpeg

# known bugs: - filenames with spaces can't be processed


# Script settings (feel free to change these)
ffmpegbin="/usr/bin/ffmpeg"      # Location of FFMpeg binary
vcodec="xvid"                    # Default value: video codec (xvid)
vfps="29.97"                     # Default value: FPS (29.97)
vsize="720x480"                  # Default value: frame size (720x480)
videob="4500k"                   # Default value: video bitrate (4500k)
acodec="mp3"                     # Default value: audio codec (mp3)
audiob="192k"                    # Default value: audio bitrate (192)
audiof="48000"                   # Default value: audio frequency (48000)
noaudio="0"                      # Default value: enable/disable audio (0)
mono="0"                         # Default value: enable/disable stereo by default (0)
deletefiles="0"                  # Default value: enable/disable file deletion (0)
quietmode="0"                    # Default value: enable/disable quiet mode (0)

# Variable initializations (do not change these)
filecount=0                      # Counter for number of files processed
version="v0.3b"                  # Script version number
vdate="May 20th/2008"            # Script date
profile="default"                # Storage for profile name only (not a setting)

# Declare functions before the script begins

help_about()
# This function displays the help/about screen
{
  echo "$(basename $0) $version $vdate"
  echo
  echo "Usage:  $(basename $0) [-options] files.."
  echo "  Converts video files from MOD format into AVI format."
  echo "  -h (show help/about screen)"
  echo "  -r [frame rate] (default 29.97)"
  echo "  -s [frame size] (default 720x480)"
  echo "  -v [video bitrate] (default 4500k)"
  echo "  -a [audio bitrate] (default 192k)"
  echo "  -f [audio frequency] (default 48000)"
  echo "  -n (no audio in resulting file)"
  echo "  -m (mono mode, default is stereo)"
  echo "  -d (delete original MOD files)"
  echo "  -q (quiet mode, suppress output)"
  echo "  -o (only rename files to MPEG, do not re-encode)"
  echo "  -p [profile name] (highqual, youtube, email)"
  echo "  files.mod (wildcards supported)"
  echo
  echo "Profiles:"
  echo "  highqual - 29.97fps, 720x480, 4500kbit video, 192kbit audio, 48khz, stereo"
  echo "  youtube  - 25fps, 320x240, 2500kbit video, 128kbit audio, 44khz, stereo"
  echo "  email    - 12fps, 256x224, 200kbit video, 64kbit audio, 22khz, mono"
  echo
  echo "Examples:"
  echo "  Convert using defaults (makes high quality files):"
  echo "    $ $(basename $0) *.mod"
  echo "  Convert for posting on YouTube (medium quality files):"
  echo "    $ $(basename $0) -p youtube mov014.mod mov015.mod"
  echo "  Convert with custom encoding options:"
  echo "    $ $(basename $0) -r 24 -s 640x480 -v 6500k -a 256k -f 44100 *.mod"
  echo "  Rename to MPG only (do not convert):"
  echo "    $ $(basename $0) -o *.mod"
  exit 1
} #help_about()

mpegonly()
# MPEG only function - if called it ignores the rest of the script and simply renames the MOD files to MPG
{
  if [ "$quietmode" = "0" ]; then

I see this in many places in your script, but I'll only comment here. "=" is used for string comparison; most of the time it works, but it's good practice to use number comparison:
Code:
  if [ "$quietmode" -eq 0 ]; then

See also: -ne -gt -lt -ge -le

Quote:
Code:
    echo "$(basename $0) $version $vdate"         # Show script name, version and date
    echo "[] `date`"                              # Show current date

Again a style thing, but unless you need sh-compatible scripts (almost never), use $() instead of ``.
Code:
echo "[] $(date)"

Quote:
Code:
    echo "[] Renaming files to .mpg instead of converting..."
  fi

  for file in $@; do
    if [ ! -r "$file" ]; then                     # Can we read the MOD file?
      if [ "$quietmode" = "0" ]; then             # If not, indicate the error if not in quiet mode
        echo "[] Error: could not read file '$file'"
      fi
      continue                                    # Move on to next file
    fi
    mv $file ${file%.mod}.mpg                     # Rename .mod file to .mpg
    ((filecount++))                               # Increase file counter
  done                                            # Proceed until done renaming all .mod files

  if [ "$quietmode" = "0" ]; then
    echo "[] Renamed $filecount files."           # Display done message
  fi

  exit 0                                          # Exit happily :)

I like to use a quit() function or something similar to handle my exit codes; That was any temp-file cleanup is in one routine, and it decreases code duplication. It also allows you to trap signals (kill, ctrl+c, etc)
Code:
function quit {
  remove_temp_files()
  do_other_stuff()
  exit ${1-:0} # If a parameter was supplied, use it; otherwise exit 0
}
function die {
  echo "${1-:ZOMG MASSIV ERRAR}" 1>&2
  quit ${2-:1}
}

Quote:
Code:
} #mpegonly()

set_highqual()
# Set high quality encoding options
{
  vfps="29.97"
  vsize="720x480"
  videob="4500k"
  audiob="192k"
  audiof="48000"
  profile="High quality"
} #set_highqual()

set_youtube()
# Set YouTube quality encoding options
{
  vfps="25"
  vsize="320x240"
  videob="2500k"
  audiob="128k"
  audiof="44100"
  profile="YouTube"
} #set_youtube()

set_email()
# Set E-mail quality encoding options
{
  vfps="12"
  vsize="256x224"
  videob="200k"
  audiob="64k"
  audiof="22050"
  mono="1"
  profile="E-mail"
}

ask_delete()
# Ensure the user wants to delete his/her MOD files after encoding
{
  echo "[] WARNING: Your original MOD files will be deleted after encoding."
  read -p "[] Are you sure you want these files deleted? (yes/no) [no] -> " UserChoice
  case $UserChoice in                             # Only continue if y/yes were entered
           y) continue;;                          # If y, continue
           yes) continue;;                        # If yes, continue
           *)  echo "[] Operation aborted."       # Display aborted message
               exit 0;;                           # Exit script
  esac
}

With case you can do stuff like:
Code:
case foo in
    [Yy]|[Yy]es) dostuff ;; # Accept "y" "Y" "Yes" "yes"
    *) ;;

Quote:
Code:


# Script begins here
if [ "$1" = "" ]; then                            # Was the command typed without any parameters?
  help_about                                      # If so, display help/about screen and exit
fi

You can use -z and -n. -z tests for a zero-length string, -n tests for a non-zero-length string

Quote:
Code:
# Parse any options passed to the script
while getopts "hr:s:v:a:f:nmdqop:" opt            # Get command-line options
do                                                # Begin analysis loop
        case $opt in                              # Analyze the option detected
                q) quietmode="1";;                # Enable quiet mode if selected
                h) help_about;;                   # Display help/about screen
                r) vfps="$OPTARG";;               # Set video fps
                s) vsize="$OPTARG";;              # Set frame size
                v) videob="$OPTARG";;             # Set video bitrate
                a) audiob="$OPTARG";;             # Set audio bitrate
                f) audiof="$OPTARG";;             # Set audio frequency
                n) noaudio="1";;                  # Disable audio
                m) mono="1";;                     # Disable stereo mode
                d) deletefiles="1";;              # Enable file deletion
                o) shift $(($OPTIND - 1))         # Shift off the options
                   mpegonly $@;;                  # Rename files to MPG
                p) {                              # Enable profile if specified
                   case $OPTARG in                # Check which profile was specified
                      "highqual") set_highqual;;  # High quality profile
                      "youtube") set_youtube;;    # YouTube quality profile
                      "email") set_email;;        # E-mail quality profile
                      "e-mail") set_email;;       # In case someone uses a hyphen
                      *) set_highqual;;           # Missing/invalid specification, use high quality
                   esac                           # Done checking profiles
                   };;                            # End of profile option code
        esac                                      # Done analyzing options
done                                              # End the analysis loop
shift $(($OPTIND - 1))                            # Now we want to work with the files

# Build FFMpeg options
ffmpegopts="-vcodec $vcodec -r $vfps -s $vsize -b $videob -acodec $acodec -ab $audiob -ar $audiof -deinterlace"

# Enable mono mode if specified
if [ "$mono" = "1" ]; then
  ffmpegopts="$ffmpegopts -ac 1"
fi

# Disable audio if specified
if [ "$noaudio" = "1" ]; then
  ffmpegopts="$ffmpegopts -an"
fi

# Display encoding settings if quiet mode is off
if [ "$quietmode" = "0" ]; then
  echo "$(basename $0) $version $vdate"           # Show script name, version and date
  echo "[] `date`"                                # Show current date
  if [ "$profile" != "default" ]; then            # If we are using the non-default profile,
    echo "[] Profile selected: $profile"          # Show the profile name
  fi
  echo "[] Frame rate: $vfps"                     # Show FPS
  echo "[] Frame size: $vsize"                    # Show frame size
  echo "[] Video bitrate: $videob"                # Show video bitrate
  echo "[] Audio bitrate: $audiob"                # Show audio bitrate
  echo "[] Audio frequency: $audiof"              # Show audio frequency
  echo "[] Video codec: $vcodec"                  # Show video codec
  if [ "$noaudio" = "0" ]; then                   # If audio is enabled,
    echo "[] Audio codec: $acodec"                # Show audio codec
  else
    echo "[] Audio codec: disabled"               # Show codec disabled
  fi
  if [ "$mono" = "0" ]; then                      # Display stereo: yes/no
    echo "[] Stereo: yes"
  else
    echo "[] Stereo: no"
  fi
fi                                                # Done listing settings if not in quiet mode

# If the user specified to delete files, ensure they meant it
if [ "$deletefiles" = "1" ]; then                 # If file deletion is enabled
  ask_delete                                      # Make sure the user wants to delete their files
fi

# Begin the conversion operation
for file in $@; do
  if [ ! -r "$file" ]; then                       # Can we read the MOD file?
     if [ "$quietmode" = "0" ]; then
       echo "[] Error: could not read file '$file'"
     fi
     continue                                     # Move on to next file
  fi

  avifile=${file%.mod}.avi                        # Set AVI filename based on MOD filename

  if [ "$quietmode" = "0" ]; then                 # Are we in quiet mode?
    echo "[] Converting $file..."                 # If not, display converting message
    $ffmpegbin -i "$file" $ffmpegopts "$avifile"  # Issue the ffmpeg command to convert
    echo "[] Done converting $file!"              # And display finished message
  else                                            # Otherwise, issue ffpmeg command to convert
    $ffmpegbin -i "$file" $ffmpegopts "$avifile" 2> /dev/null # And supress ffmpeg output
  fi

  if [ "$deletefiles" = "1" ]; then               # Should we delete files?
    rm $file                                      # If so, delete this file
    if [ "$quietmode" = "0" ]; then               # And log the deletion if not in quiet mode
      echo "[] Deleted $file."
    fi
  fi

  ((filecount++))                                 # Increase file counter
done                                              # Continue converting until done

# We're done!
if [ "$quietmode" = "0" ]; then
  echo "[] Number of files converted: $filecount" # Display number of files converted
  echo
fi

exit 0                                            # Exit happily :)

# EOF


Great work!


Top
 Profile  
 PostPosted: Sat May 24, 2008 11:08 pm   

Joined: Tue May 13, 2008 1:04 am
Posts: 4
Thanks for the positive replies, Daenyth and DarthWavy. I think the script is nearly ready for production use, I can't find any bugs in it at the moment. I've created a SourceForge webpage and posted the current version (v0.5b) at the site: http://mod2avi.sourceforge.net

If anyone has a chance to test it, let me know how it turns out and if there are any bugs or feature suggestions. Thanks again for all the help and suggestions so far! :)


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 6 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