February 04, 2005
Batch iTunes track conversion with Python and COM

I think that I see now why Apple has kept the iTunes interface simple. It's a simple app that does simple stuff, and it just works. Once you get it into your head that you can do whatever you like, where do you stop? I see that I'm not alone in getting a bit carried away - Garth and Chris have also been having a play with driving iTunes with Python and COM, too.

Anyway, on to my latest folly, batch conversion. I initially ripped all my CDs to MP3 at 192 kbps. I've since discovered that I'm quite happy with plain old 128 kbps, especially for the more raucous stuff in my collection. And I'm running out of room. So I want to convert a bunch of track to a lower bitrate. (And before you tell me, yes, I know that converting from 192 kbps to 128 kbps will give me a somewhat lower quality that I'd have had I ripped to 128 in the first place. I'll probably re-rip at my leisure.)

Now, you can convert from one format and bit rate to another in iTunes, but the process leaves a lot to be desired. For a start off, you end up with both the original and the new track, and you have to remove the original track yourself, which is fiddly - you have to make sure that you get the right one for a start. Also, there's a lot if metadata that doesn't get copied across to the converted track - the rating that you've given the track, the last-played date, that kind of thing. Lastly, if you've put the track into any manual playlists, the newly converted track won't be in them.

So, I came up with a script to do the conversion for me - convert_tracks.py. You just bung the tracks that you want converted into a playlist (called "To Convert" by default), set the conversion rate that you want to use in your iTunes' preferences, and away you go.

This script works OK, but there are a couple of problems with it. Firstly, though you can set the encoder to be used, I can't find any way of programatically setting the bitrate. You have to do it manually via the iTunes preferences dialog. A bit of a shame, but no biggie.

More seriously, you have to be very careful to leave iTunes alone to its thing. If iTunes shows any dialog box, your iTunes COM connection will fail if you make any calls to it. I could just trap the exceptions, but that would be The Wrong Thing. Instead, I think that I need to register for OnCOMCallsDisabledEvent()s. When I get one of these events, I should hold fire on COM calls until I get a OnCOMCallsEnabledEvent(). I've had a bit of a play with registering for iTunes events - see show_playing_track.py - but it's early days, and I've been too busy this week to look at it.

(Also, it would be nice if it were to be driven by command line arguments, a cinfuguration file or even a GUI rather than by hard-coded constants - but since it's pretty much a one-off script, I really can't be bothered.)

Anyway, I hope this is of some use to somebody. (All code runs with iTunes 4.7.1 Python 2.4 and Python for Windows build 202, and may work with earlier versions.)

Posted to Python by Simon Brunning at February 04, 2005 05:05 PM
Comments

If my iPod ever arrives I'm sure it will be of use to me. Grrrrrr.

Posted by: Katherine on February 4, 2005 06:23 PM

Have you found any way to get the file path of an IITTrack? It appears that it isn't possible according to the iTunes documentation with an IITTrack instance, but an IITFileOrCDTrack does have a location property. I just can't figure out how to get an IITFileOrCDTrack from an IITTrack, or from the elements in Playlist. Have you ever tried or had any luck with this?

Posted by: Mike on February 22, 2005 12:36 AM

Yup - use win32com.client.CastTo() to cast the IITTrack to a IITFileOrCDTrack. I do this in convert_tracks.py, so there's an example in there.

Posted by: Simon Brunning on February 22, 2005 09:36 AM

Regarding your show_playing_track.py script, what's the point of "pythoncom.PumpWaitingMessages()" given that pythoncom never connects to anything and commenting it out yields the same results? (Incidentally, how would one go about making it so it actually does do something?)

Thanks,
Orri

Posted by: Orri on November 10, 2006 11:04 PM
Post a comment
Name:


Email Address:


URL:



Comments:


Remember info?