fix an audio conversion script to work through multiple directories and convert mp3s to ogg vorbis

Antonio Olivares olivares14031 at gmail.com
Mon May 9 02:01:33 UTC 2011


On Sat, May 7, 2011 at 4:03 PM, Chris Hill <chris at monochrome.org> wrote:
> On Sat, 7 May 2011, Antonio Olivares wrote:
>
>> My question is the following:
>> How can I run the script to recursively find all mp3's and convert them to
>> ogg vorbis(with ogg extension already in place/or rename them in one
>> step[instead of running two scripts] and deleting the mp3's) all in one
>> time?
>
> I had a similar (but not identical) problem, and I wrote a script to solve
> it. I wanted to recursively go through a directory tree, find flac files,
> and make mp3s of them while transferring over the ID3 tags, while keeping a
> duplicate directory structure for the mp3s. And don't do the conversion if
> the file already exists.
>
> My script is based on traverse2.sh by Steve Parker, which is at
> http://steve-parker.org/sh/eg/directories/. His tutorial site is extremely
> helpful, and I recommend it.
>
> My script is at http://pastebin.com/77NRE6SZ - maybe you can adapt it to
> your needs.
>
> HTH.
>
> --
> Chris Hill               chris at monochrome.org
> **                     [ Busy Expunging </> ]
>

Chris,

Thank you for your suggestion.  But I have gotten into a problem I get
errors and too many directories :(, Directories with spaces get
recreated and no ogg files are created :(

=====================================================
#!/bin/sh
#
# Notes:
#
# For each music file in the current directory and its subdirectories,
# convert it to an ogg.
#
# This script traverses directory structures using a mechanism adapted
# from Steve Parker's traverse2.sh script.
#
# I assume that the commands ls, rm, sed, grep, pwd, wc and mkdir exist
# and can be called by those names. But let's make sure this system has
# the necessary third-party software installed, and find the binaries.
# Complain and exit if any one is not found.

OGGENC=`which oggenc`
MPLAYER=`which mplayer`

# Exit if we are missing anything:
if [ -z $MPLAYER ]; then
  echo "mplayer not found! Exiting."
  exit 1
fi

if [ -z $OGGENC ]; then
  echo "oggenc not found! Exiting."
  exit 1
fi

# Where to log errors?
LOGFILE=.conversion_err_log

# Where to put the oggs:
# Create that directory if necessary
OGGROOT=./ogg  # change this to whatever you like
if [ -d $OGGROOT ]; then
  echo "";  # then we're OK
else
  mkdir $OGGROOT
fi

# Parameters for lame - will affect sound quality and file size.
#LAME_PARAMS="-V 0 -h"    # variable bitrate, best quality

# From Steve Parker, only slightly modified:
traverse()
{
  # Traverse a directory

  ls "$1" | while read i
  do
    if [ -d "$1/$i" ]; then
      THISDIR=$1/$i
      # Calling this as a subshell means that when the called
      # function changes directory, it will not affect our
      # current working directory

      if [ -d $OGGROOT/$THISDIR ]; then
        # directory exists, leave it be
        echo "$OGGROOT/$THISDIR already exists, not created."
      else
        mkdir $OGGROOT/$THISDIR
        echo "Copying $THISDIR to $OGGROOT/$THISDIR"
      fi

      traverse "$1/$i" `expr $2 + 1`
    else
      FILE=$1/$i
      MP3FILE=`echo $FILE | grep -i mp3$`

      # Ditch the empty lines:
      if [ -z $MP3FILE ]; then
        echo "" # do nothing!
      else
#        echo $MP3FILE

        OGG="$MP3ROOT/$THISDIR/${i%.mp3}.ogg"

# vvv commented during script debugging vvv
          if [ -f $OGG ]; then
            # ogg already exists; don't overwrite
            if [ -f $LOGFILE ]; then  # if the log file exists, append
              echo "$THISDIR/$OGG" >> $LOGFILE
            else                      # file does not exist; create
              echo "The following ogg files already exist and were not
created:" \
                > $LOGFILE
              echo "" >> $LOGFILE
              echo "$OGGROOT/$OGG" >> $LOGFILE
            fi
          else
            echo "Creating ${OGG}..."
            # Create ogg without tags:
            $MPLAYER -cd "$1" -ao pcm:file="$WAV" && "$MP3FILE" &&
$OGGENC -b 128 "$WAV"
#          else
          if [ -f $LOGFILE ]; then  # if the log file exists, append
            echo "$THISDIR/$MP3FILE" >> $LOGFILE
          else                      # file does not exist; create
            echo "No tags found for the following:" > $LOGFILE
            echo "" >> $LOGFILE
            echo "$THISDIR/$MP3FILE" >> $LOGFILE
          fi
        fi
      fi
    fi
  done
}

traverse . 0
=====================================================

I have modified to above script.  I don't get how the directory
structure is copied?  I don't see a cp -r from_directory/ to
_directory/ then mplayer -ao ....
The option is not the same as I had it before.  I guess if I can't get
it to work, I would need to go individually through each folder and
convert the mp3's with the original scripts.

I made another variation and it does not work either, this of course
before I try it on the machine where the actual songs that I want to
convert:

==================================
#!/bin/sh
#
# Notes:
#
# For each flac file in the current directory and its subdirectories,
# convert it to an mp3, importing the flac's tags. If the flac has
# Vorbis tags, use them. Otherwise look for id3v2 tags and use them
# if found. If the flac has no tags, log that fact and skip
# processing the file.
#
# This script traverses directory structures using a mechanism adapted
# from Steve Parker's traverse2.sh script.
#
# I assume that the commands ls, rm, sed, grep, pwd, wc and mkdir exist
# and can be called by those names. But let's make sure this system has
# the necessary third-party software installed, and find the binaries.
# Complain and exit if any one is not found.

MPLAYER=`which mplayer`
OGGENC=`which oggenc`

# Exit if we are missing anything:
if [ -z $MPLAYER ]; then
  echo "mplayer not found! Exiting."
  exit 1
fi

if [ -z $OGGENC ]; then
  echo "oggenc not found! Exiting."
  exit 1
fi


# Where to log errors?
LOGFILE=.ogg_err_log

# From Steve Parker, only slightly modified:
traverse()
{
  # Traverse a directory

  ls "$1" | while read i
  do
    if [ -d "$1/$i" ]; then
      THISDIR=$1/$i
      # Calling this as a subshell means that when the called
      # function changes directory, it will not affect our
      # current working directory

      traverse "$1/$i" `expr $2 + 1`
    else
      FILE=$1/$i

#	if [ $1 = "" ]; then
#	  echo "Please give an audio extension as argument."
#	  exit 1
#	fi
		for i in `ls | sed 's/ /_123BLANK_/g' | grep .mp3` ;
		do {
		       mp3=$(echo $i | sed 's/_123BLANK_/ /g');
			#fileman wmafile
		       wav=$(echo $1 | sed 's/.mp3/\.wav/g');
			#filenname wavfile
		       ogg=$(echo $1 | sed 's/.mp3/\.ogg/g');
			#filenname ogg
		       mplayer "$1" -ao pcm:file="$wav" && oggenc -b 128 "$wav"
"$ogg" && rm "$wav" && rm "$mp3";
       			}
		 done
    fi
 done
}

traverse . 0
=========================================

I don't need ID3TAGS/ARTIST/... all that information so I removed it.
I just want the script to batch convert the music files, whether
mp3/wma/m4a whatever they are and convert them to ogg vorbis like the
first script I had:

=========================================
#!/bin/bash
#
# Usage: convertoogg fileextention
#
if [ $1 = "" ];then
  echo 'Please give a audio file extention as argument.'
  exit 1
fi

for i in *.$1
do
  if [ -f "$i" ]; then
  rm -f "$i.wav"
  mkfifo "$i.wav"
  mplayer \
   -quiet \
   -vo null \
   -vc dummy \
   -af volume=0,resample=44100:0:1 \
   -ao pcm:waveheader:file="$i.wav" "$i" &
  dest=`echo "$i"|sed -e "s/$1$/ogg/"`
  oggenc -b 128 "$i.wav" "$dest"
  rm -f "$i.wav"
fi
done
=========================================

I hope that I can easily correct one of these variations.  I would
actually prefer to pass a parameter like the script below and convert
wma/mp3/m4a to ogg and do it recursively then eliminate the wav files
and check to see that the oggs get created after they are created
delete the mp3 files.

Thanks for helping.  I am experimenting and trying not to shoot myself
in the foot.

Regards,


Antonio


More information about the freebsd-questions mailing list