Writing ID3 Tags for Windows From the Command Line

Published on Monday, November 17, 2014

Photo by Jan Loyde Cabrera on Unsplash

I will preface this by saying the reason I needed to figure this out is a little dumb. See, I'm one of the few remaining people in the world who still has a Windows Phone 7 device. I bought an HTC HD7 back in 2011 and it's still going strong. I've been eyeing the 8.1 phones for a while, but I haven't been able to justify a new phone while this one still works. So here I am, still putting podcasts on my phone with the Zune software, like an animal.

The Zune software is really my only complaint about the experience, and for a while I avoided it completely because the phone is capable of downloading podcasts via wifi; since I wasn't using it for music, I never had to see the Zune logo and all was well. There were just two problems:

  1. There's no way to add an arbitrary RSS feed to the phone's podcast list. If the podcast isn't in the Zune Marketplace, the phone can't get it on its own.

  2. Once in a while, it would be in the process of downloading podcasts right when it lost wifi signal (if I picked it up and walked out the door at the wrong time), and the downloads would get stuck in limbo and require manual cancellation.

Someday I might write about the incident that finally tipped the scales and made us decide to eliminate iTunes from our household; it's a long tale of the woes of those of us who refuse to declare our allegiance entirely to just one of the feudal lords. Suffice it to say that I was already moving to sync my iPod Shuffle using MediaMonkey to a DRM-free music collection stored on our Synology. And the Synology is perfectly capable of handling the podcast downloads (also synced to the iPod). And the Synology is totally comfortable with arbitrary RSS feeds. And the Synology doesn't get stuck in the middle of a download if it loses connectivity. So the problem was now 95% solved; the last 5% is the part which might be useful to other Windows users out there.

The podcasts were on the Synology, and they could be synced over wifi to the phone via the Zune software on my laptop. As long as the phone was connected to wifi and plugged in to charge, it would magically get all of the podcasts synced to it.

But weirdly, the Zune software only seemed to recognize a few of the podcasts as being podcasts; everything else it thought was music. This meant it showed up with incorrect art on the wrong menu of the phone.

After a few blind alleys and a lot of messing around with settings, I figured out the Zune software's problem - it was making the incredible assumption that a file was only a podcast if the ID3 tag had "Podcast" as the genre. Depending on how you look at it, this is either perfectly reasonable or totally crazy. But from a practical perspective, it definitely wasn't functional. Lots of podcasts don't set the genre on their files at all; others set it to something like "talk" or "comedy". And woe to the Windows user, some of them have the audacity to use ID3v2.4 tags, the blindingly bleeding-edge standard from the year 2000!

ID3 (the "standard" metadata container for .mp3 files) is a mess. It's right up there with EXIF for being both staggeringly useful and horrifically inconsistent. It provides tons of useful data (artist names, notes, track info, album art, duration, ratings, and much, much more) in a theoretically cross-platform format which lives right inside the file. I say theoretically because there are disagreements between applications on what to store in which frame, some applications add their own arbitrary data, and not all applications agree on or properly handle the text encoding.

Anyway, the latest version (again, from 2000) is 2.4. But Windows only natively supports 2.3. This is why you can use a tag editor to add, say, a genre to an MP3 file and then look at it in Explorer (under Properties->Details) and see a blank genre. If you force the tag editor to use v2.3 tags, the metadata will show up just fine in Explorer. Why doesn't Windows natively support v2.4? No idea. I did some Googling, but no answers were forthcoming.

The Zune software also requires v2.3 tags (it probably just uses the native info from Windows). Which brings me to the problem: in order for these podcasts to show up correctly on my phone, I needed to set the genre and force the tags to be rewritten in v.2.3 (for the album artwork and other info to work). Preferably in a script.

As with just about anything else you might want to do in this world, there's a Python library for that. In this case, Mutagen, which can do pretty much anything you want with audio metadata. Putting together the actual script to do what I wanted ended up only being slightly harder than "import antigravity":

from mutagen.mp3 import MP3
from mutagen.id3 import ID3, APIC, TCON, TCOP, WOAR, error
import argparse

parser = argparse.ArgumentParser(description='Write the Podcast genre tag')
parser.add_argument('-m', '--mp3', help='Target mp3', required=True)
args = vars(parser.parse_args())

tags = ID3()
try:
	tags.load(args['mp3'], None, True, 3) 
except error:
	tags.save(args['mp3'])

try:
    tags.add(
        TCON(
            encoding=3, 
            text= u'Podcast'
        )
    )

    tags.update_to_v23()    
    tags.save(args['mp3'], 2, 3, '/')
except error:
    pass

I just run each podcast file through that script and it force-sets the genre to "Podcast" and rewrites the metadata as v2.3 tags. After that, everything syncs as expected.

I realize almost no one else in the world will have my exact problem, but I'm hoping this can help someone else who's fighting with ID3 tags on Windows.

By the way, the script works in Python 2.7.6 - I haven't tested on any other version. YMMV.