Skip to content.

plope

Personal tools
You are here: Home » Members » chrism's Home » Transcoding Batches of Ogg Files to MP3
 
 

Transcoding Batches of Ogg Files to MP3

Some Python code that helps transcode a batch of ogg files to mp3.

I have an Apple iPod. I'm not sure why, because most of my music is ripped to Ogg Vorbis format, which the iPod doesn't play natively. Since I've had the iPod, I've had Rockbox on it in order to play all my music. But the Rockbox UI is pretty rough, and I'd like to be able to just plug the thing into my Mac and have it sync with iTunes, which requires actual thought one way or another if it's not running the native iPod OS, and I really have enough thinking to do without thinking about this. So I've decided for better or worse to transcode all my Ogg Vorbis music to MP3 and get rid of Rockbox in favor of running the iPod OS. Yes, I am lame, but I don't care. Here's the Python code I'm using to transcode my music directory into a (shadowed) directory that is Ogg-free. It requires PyOgg as well as system-invocable "oggdec" and "lame" binaries. It probably also has bugs because I haven't actually let it run all the way through my music (this will take a few days) :

  """Usage: transcode <oggdir> <outdir>"""

  import errno
  import os
  import shutil
  import sys
  import tempfile

  def usage():
      print __doc__
      sys.exit(2)

  def normalize(dir):
      return os.path.abspath(os.path.normpath(os.path.expanduser(dir))) + os.sep

  def main(argv):
      try:
          infolder, outfolder = map(normalize, argv[1:])
      except TypeError:
          usage()
      transcoder = MP3Transcoder()
      transcoder.walk(infolder, outfolder)

  class MP3Transcoder:

      def do_ogg(self, name, inpath, outpath):
          from ogg.vorbisutils import getVorbisComments
          if os.path.exists(outpath):
              return
          tempdir = tempfile.mkdtemp()
          vendor, comments = getVorbisComments(inpath)
          comments = dict(comments)
          unknown = 'Unknown'
          if not comments.get('TITLE'):
              comments['TITLE'] = name
          if not comments.get('ARTIST'):
              comments['ARTIST'] = unknown
          if not comments.get('ALBUM'):
              comments['ALBUM'] = unknown
          if not comments.get('TRACKNUMBER'):
              comments['TRACKNUMBER'] = '0'
          if not comments.get('TRACK'):
              comments['TRACK'] = comments['TRACKNUMBER']
          if not comments.get('YEAR'):
              comments['YEAR'] = '1'
          comment = comments.get('COMMENT', '') + ' (retranscoded)'
          comments['COMMENT'] = comment.lstrip()
          try:
              tempwav = os.path.join(tempdir, '%s.wav' % name)
              os.system('oggdec -o "%s" "%s"' % (tempwav, inpath))
              tempmp3 = os.path.join(tempdir, '%s.mp3' % name)
              comments['infile'] = tempwav
              comments['outfile'] = tempmp3
              print comments
              cmd = ('lame '
                     '--preset 192 '
                     '--ignore-tag-errors '
                     '--tt "%(TITLE)s" '
                     '--ta "%(ARTIST)s" '
                     '--tl "%(ALBUM)s" '
                     '--ty "%(YEAR)s" '
                     '--tc "%(COMMENT)s" '
                     '--tn "%(TRACK)s" '
                     '-ms -h "%(infile)s" "%(outfile)s"' % comments)
              print cmd
              os.system(cmd)
              shutil.copyfile(tempmp3, outpath)
          finally:
              shutil.rmtree(tempdir)

      def do_mp3(self, name, inpath, outpath):
          if not os.path.exists(outpath):
              shutil.copyfile(inpath, outpath)

      do_m4a = do_mp3
      do_m4p = do_mp3
      do_flac = do_mp3

      def walk(self, inroot, outroot):
          for root, dirs, files in os.walk(inroot):
              print root, dirs, files
              for dir in dirs:
                  outpath = os.path.join(outroot, root[len(inroot):], dir)
                  try:
                      os.makedirs(outpath)
                  except OSError, why:
                      if why[0] != errno.EEXIST:
                          raise
              for file in files:
                  name, ext = os.path.splitext(file)
                  realext = ext[1:]
                  doer = getattr(self, 'do_%s' % realext, None)
                  if doer is not None:
                      inpath = os.path.join(root, file)
                      outname = name + '.mp3'
                      outpath = os.path.join(outroot, root[len(inroot):], outname)
                      doer(name, inpath, outpath)

  if __name__ == '__main__':
      main(sys.argv)

Created by chrism
Last modified 2008-05-25 12:24 AM