BlogMatrix
 

pytunes

edit David Janes 2004-10-11 16:12 UTC 5 comments  ·

'pytunes.py' provides a generalized interface for controlling media players, such as Apple's iTunes. This implementation only works with iTunes on Windows but we expect to have a Macintosh implementation later this week and hope to demonstrate a controller for Windows Media Player also (if anyone can help me with the COM interfaces here, I'd be very grateful). This version concentrates on manipulating the playlists, adding songs and so forth rather than playing music, controlling the volume, etc. as this is my immediate need for the Podcasting version of BlogMatrix Jäger.

import pytunes
itunes = pytunes.iTunesWindows()

# list everything in the Playlist 'Recently Played'
playlist = itunes.GetPlaylistByName('Recently Played')
for track in playlist.IterAllTracks():
 pprint.pprint({
  "album" : track.GetAlbum(),
  "title" : track.GetTitle(),
  "composer" : track.GetComposer(),
  "artist" : track.GetArtist(),
 })
 
# list songs with the word 'Love' in the Title
for track in library_playlist.SearchTitles("Love"):
 pprint.pprint({
  "album" : track.GetAlbum(),
  "title" : track.GetTitle(),
  "composer" : track.GetComposer(),
  "artist" : track.GetArtist(),
 })

Comment #1Simon Brunning

2004-10-12 14:02:13
This worked fine - until I made the mistake of running Makepy over iTunes so I could have a look at the COM model. This seems to have broken everything in sight. ;-)

Still, deleting the generated wrapper makes everything work fine again.

I'll have a bit of a play with this - I'd be interested to see if you can *set* track attributes as well as reading them, and if attributes like ratings and play counts are available. If so, this could offer a way of transferring your library from one PC to another along with *all* the meta data.

Cool stuff, David!

Comment #2has

2004-10-12 17:53:49
Apple event-based IPC is relatively expensive, so if you're using iTunes' Apple event interface on the Mac, it's probably good practice to use as few events as you can and lever the Apple Event Object Model to perform more work per event. For example, a straight translation of your example would send 4N+1 events (N = no. of tracks found):

from appscript import *
for track in app('iTunes.app').sources['Library'].playlists['Recently Played'].tracks.get():
pprint((track.album.get(), track.name.get(), track.composer.get(), track.artist.get()))

whereas this sends only 4:

ref = app('iTunes.app').sources['Library'].playlists['Recently Played'].tracks
pprint(zip(ref.album.get(), ref.name.get(), ref.composer.get(), ref.artist.get()))

(The first method also has to assemble and decode object specifiers used to represent every track found - another expense.)

There's little difference when dealing with just a handful of tracks, but the first approach can really bog down your application as the number of tracks being operated on increases - something to bear in mind if designing your API across both COM and Apple event interfaces.

HTH

Comment #3David

2004-10-12 20:29:17
Thanks for the Mac advise. I'll probably be hacking away at that tomorrow or later tonight.

There'll be a source code dump later today.

Comment #4Eric Thompson

2004-10-12 21:44:14
The Python module goodies that spring forth from the Jaeger project
(Jaeger is David Janes' newsreader/aggregator) keep on coming! ...

Comment #5Matt B

2008-03-04 01:27:16

what happened to this project?  is it dead?  can i still get the source code from somewhere?  i'm embarking on something similar right now..

Add Comment