ID3 batch editing

Some of my music had no interpreter and title tags set thus I wrote a little shell script to batch edit these ID3 tags. The filenames of the songs looked like “01 Interpret – Song Title.mp3″. In a few moments I wrote the following php script1 which split the filename into the interpreter and the title.

All the python scripts listed here are using the library pytagger.




Unfortunately I forgot to strip the digits so all the interpreters had two leading digits afterwards.

I had to iterate over the files again. As id3.py creates new tag frames I had to write another script (fix_interpreters.py) that reads the old frames to get the old values.


#!/usr/bin/env python

from tagger import *
import sys, os, fnmatch, pickle, re

filename = sys.argv[1]

print "Processing '", filename, "'"

try:
  id3 = ID3v2(filename)
   
  if id3.tag_exists():
    interpret_frame = None
    for frame in id3.frames:
      interpretfid = 'TPE1'
      if id3.version == 2.2:
        interpretfid = 'TP1'
  
      if frame.fid == interpretfid:
        interpret_frame = frame
        break


    interpret = interpret_frame.strings[0]
    repaired = re.sub('^\d\d\s', '', interpret)

    print "Repairing \"", interpret, "\" => \"",repaired,"\""      
    interpret_frame.set_text(repaired)

    # replace interpret frame
    id3.frames = [frame for frame in id3.frames if frame.fid != interpretfid]
    id3.frames.append(interpret_frame)
    id3.commit(pretend=0)
  
except ID3Exception, e:
  print("ID3 exception: %s" % str(e))

I didn’t want to rewrite the php script above because I thought that typing a loop in the shell would be easier (or at least faster).


for file in `ls -1 *.mp3`; do ./fix_interpreters.py $file; done

I tried it with this loop but ls -1 *.mp3 doesn’t list each mp3 file one per line as expected. Instead it splits the filenames after each whitespace. Thankfully to Greg Miller’s post about Handling Filenames With Spaces this wasn’t no problem anymore. I changed the loop into


find ./ -name '* *' | while read filename; do ls -ld "$filename"; ./fix_interpreters.py "$filename"; done

and ta-da, it worked.

  1. PHP scripts can be executed in a shell. Use php -f script.php to execute a file or use -r instead of -f to run inline code.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>