Well, more or less. See, I have this collection of music I’ve transferred from a whole lot of CD’s I bought over the years onto my computer. I had an iPhone which I had used to play that music by using iTunes to create a dynamic playlist, and load that playlist onto my phone. Well… it worked, other than the fact that I can’t use iTunes on Linux and such. So… I decided to go with an alternate plan — stream the music and use a music player to listen to it. My problem was, how to make my music playlist with the same functionality that iTunes provided me.
First, I used Firefly Media Server… which became quite a hassle to work with, so I switched to Logitech’s SqueezeBox Server (with an external MySQL database backend). I then built some stored procedures to generate the playlist directly into the database…. which really didn’t work very well. So I built a Google AppEngine web app that would do most of the processing… which worked pretty well but was a pain to keep up. And… SqueezeBox Server died on me, and I didn’t want to mess with it any more. After some searching, I settled on something simple — MusicPlayer Daemon, with its own internal HTTP streaming output. Using this, I could once again access my music as a stream — a continuous stream that works all the time. And, it is driven by a playlist I can control and manipulate with Python (thanks to python-mpd2). After wiring everything up to provide an encrypted channel with login credentials being required to reach the stream (thanks to squid3 acting as a reverse proxy and upgrading http to https traffic automatically), I finally had a solution. I’d just write my playlist generator as a python script.
In comes TagScanner — a beautiful program (if a little cumbersome to learn how it works at first) which lets me clean up and organize my music & all of the music tags easily. It also provides a way for me to export my list of music to XML… which I use as the starting point for my python script. TagScanner lets me build the XML file with the following:
# Tagscanner export script
$file_name TrackList.xml
$file_notes XML file with full information
$file_encoding utf-8
$file_writebom 1
$file_ishtml 1
$file_relativepaths 1
$document_open
<tracklist>
$select %_index%,0
<track>
<discnumber>%disc%</discnumber>
<totaldiscs>%totaldiscs%</totaldiscs>
<tracknumber>%track%</tracknumber>
<totaltracks>%totaltracks%</totaltracks>
<title>%title%</title>
<album>%album%</album>
<year>%year%</year>
<artist>%artist%</artist>
<albumartist>%albumartist%</albumartist>
<genre>%genre%</genre>
<category>%contentgroup%</category>
<flags>%comment%</flags>
<filename>%fullfilenameext%</filename>
<filedate>%_filedate%</filedate>
<length>%_length_sec%</length>
<size>%_filesize_bytes%</size>
<channels>%_channels%</channels>
<samplerate>%_samplerate%</samplerate>
<bitrate>%_bitrate%</bitrate>
<type>%_codec%</type>
<tag>%_tagtype%</tag>
</track>
$endselect
</tracklist>
$document_close
I’m not going to go into details as to what all of this means, but basically it generates the entire list of tracks into an XML file that I can parse. And thus my journey of building my playlist begins.
The next step was to be able to easily update my music list. Which comes down to a nice program called QtdSync, which uses the tried and true rsync algorithm for incremental updates to provide what I need. I simply sync my music folders on my portable hard drive with a directory on my server at home, and it does the nasty work of figuring out how to only update what has changed (because I don’t want to have to re-upload my entire music library every time I make a change). Conveniently, this makes me have the same directory structure on my portable drive as the server, which makes the XML file above provide the same relative paths to my files.
On Part 2, I will explain the process I use for importing the XML file into something usable in my python script…