After Hours

Convert Windows Media Player playlists to Winamp format using XSLT

Edmond Woychowsky tried to copy Windows Media Player playlists to his MP3 player, but the device was expecting Winamp playlists. Feeling a bit rebellious, he decided to write some XSLT to convert the .wpl files to .m3u format.

I have a number of multi-disc albums and box sets by Led Zeppelin, Creedence Clearwater Revival, Jethro Tull, The Grateful Dead, Pink Floyd, The Moody Blues, and Emerson, Lake & Palmer. With a computer, I can rip these CDs using Windows Media Player and then create playlists for the entire box set. It's all nicely organized in folders; each group has a folder, and all of the associated discs are in their own sub folder.

Unfortunately, this organization structure quickly breaks down when I attempt to copy my hierarchical file structure onto my MP3 player. The folders and files drop and drag easily enough, but the MP3 player doesn't know what to do with a Windows Media Player playlist because it's expecting a Winamp playlist.

I came up with three ways that I could solve this problem:

  1. Download Winamp and spend the better part of a week redoing all of my playlists.
  2. Give up and live with each disc being separate from the related discs.
  3. Since the majority of my music is from the 60s and the 70s, consider an era appropriate solution -- in other words, find a way to stick it to the man.

I quickly ruled out the first option as being too ambitious; I ruled out the second option because I'm not that lazy; and I decided to go with the third option because it appealed to the rebel in me.

Let the rebellion begin

I began my personal rebellion by using Notepad to open the .wpl file (Windows Playlist) for the Led Zeppelin Box Set, and I was shocked by what I saw (Listing A). Listing A

Contents of Led Zeppelin - Box Set.wpl

<?wpl version="1.0"?>

<smil>

<head>

<meta name="Generator" content="Microsoft Windows Media Player -- 11.0.5721.5268"/>

<meta name="AverageRating" content="5"/>

<meta name="TotalDuration" content="17416"/>

<meta name="ItemCount" content="54"/>

<meta name="ContentPartnerListID"/>

<meta name="ContentPartnerNameType"/>

<meta name="ContentPartnerName"/>

<meta name="Subtitle"/>

<author/>

<title>Led Zeppelin - Box Set</title>

</head>

<body>

<seq>

<media src="C:\Documents and Settings\woychowsky\My Documents\My Music\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\01 Whole Lotta Love.mp3" cid="{B74906CA-72F9-4351-97BF-A6CE6747699D}" tid="{301C14C6-055A-4A01-B473-BE13A64E01C2}"/>

<media src="C:\Documents and Settings\woychowsky\My Documents\My Music\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\02 Heartbreaker.mp3" cid="{A78808F0-F943-48C4-885F-14B5393F41AC}" tid="{0AE5F094-3CC9-4CE6-99EB-EC2624D3BCCA}"/>

<media src="C:\Documents and Settings\woychowsky\My Documents\My Music\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\03 Communication Breakdown.mp3" cid="{B0DC58CF-48C5-448C-B61C-9CF1398E99BF}" tid="{9937B18F-B0DE-4B30-99AE-B0218EE72052}"/>

<media src="C:\Documents and Settings\woychowsky\My Documents\My Music\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\04 Babe I&apos;m Gonna Leave You.mp3" cid="{36C5B60D-8122-4907-9BE6-C33F83B4A07E}" tid="{E5DD7D8F-3BC6-4881-9FA7-6F72EF9DF4EC}"/>

<media src="C:\Documents and Settings\woychowsky\My Documents\My Music\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\05 What Is and What Should Never Be.mp3" cid="{8C5CA370-34E8-49FE-9275-16F813D0E3CA}" tid="{16EC3078-B602-4D92-8DA8-699CAF639DFA}"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\06 Thank You.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\07 I Can&apos;t Quit You Baby.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\08 Dazed and Confused.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\09 Your Time Is Gonna Come.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\10 Ramble On.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\11 Travelling Riverside Blues [#].mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\12 Friends.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\13 Celebration Day.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\14 Hey Hey What Can I Do.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 1\15 White Summer-Black Mountain Side [#].mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\01 Black Dog.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\02 Over the Hills and Far Away.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\03 Immigrant Song.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\04 The Battle of Evermore.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\05 Bron-Y-Aur Stomp.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\06 Tangerine.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\07 Going to California.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\08 Since I&apos;ve Been Loving You.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\09 D&apos;Yer Mak&apos;er.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\10 Gallows Pole.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\11 Custard Pie.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\12 Misty Mountain Hop.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\13 Rock and Roll.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\14 The Rain Song.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 2\15 Stairway to Heaven.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\01 Kashmir.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\02 Trampled Under Foot.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\03 For Your Life.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\04 No Quarter.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\05 Dancing Days.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\06 When the Levee Breaks.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\07 Achilles Last Stand.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\08 The Song Remains the Same.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\09 Ten Years Gone.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 3\10 In My Time of Dying.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\01 In the Evening.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\02 Candy Store Rock.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\03 The Ocean.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\04 Ozone Baby.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\05 Houses of the Holy.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\06 Wearing and Tearing.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\07 Poor Tom.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\08 Nobody&apos;s Fault But Mine.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\09 Fool in the Rain.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\10 In the Light.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\11 The Wanton Song.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\12 Moby Dick-Bonzo&apos;s Montreux.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\13 I&apos;m Gonna Crawl.mp3"/>

<media src="..\Led Zeppelin\Led Zeppelin [Box Set] Disc 4\14 All My Love.mp3"/>

</seq>

</body>

</smil>

It looks surprisingly like XML because Windows Media Player uses the XML dialect Synchronized Multimedia Integration Language (SMIL) to store playlists.

I made a concerted effort not to get my hopes up, and I looked up the Winamp playlist format (.m3u) using the 21st century's version of The Anarchist Cookbook (okay, it was Wikipedia, but I'm going for a theme here, so please allow me my delusions). I learned that .m3u files are plain text, start with #EXTM3U, and consist of either absolute or relative path names or a URI. There is also #EXTINFO, which further describes the MP3 file, but they're optional, so I ignored them.

So, knowing this information and assuming that the playlist would be in the disc folder, the .m3u playlist for Jethro Tull's Aqualung would look like Listing B. Listing B

Jethro Tull's Aqualung as a .m3u playlist

#EXTM3U

01 Aqualung.mp3

02 Cross-Eyed Mary.mp3

03 Cheap Day Return.mp3

04 Mother Goose.mp3

05 Wond'ring Aloud.mp3

06 Up to Me.mp3

07 My God.mp3

08 Hymn 43.mp3

09 Slipstream.mp3

10 Locomotive Breath.mp3

11 Wind Up.mp3

With multi-disc albums, the playlist would be stored at the group level and would therefore have the disc folder as part of the path. So, starting at the group level, the Aqualung playlist would look Listing C. Listing C

Jethro Tull's Aqualung as a .m3u playlist

#EXTM3U

Aqualung\01 Aqualung.mp3

Aqualung\02 Cross-Eyed Mary.mp3

Aqualung\03 Cheap Day Return.mp3

Aqualung\04 Mother Goose.mp3

Aqualung\05 Wond'ring Aloud.mp3

Aqualung\06 Up to Me.mp3

Aqualung\07 My God.mp3

Aqualung\08 Hymn 43.mp3

Aqualung\09 Slipstream.mp3

Aqualung\10 Locomotive Breath.mp3

Aqualung\11 Wind Up.mp3

Once I knew what the input and the output would look like, I just needed to write the code to do the conversion. Since the input was XML, I decided to use XSLT. (This may sound a little odd, especially since the output will be a plain text file, but it does work.) I ended up with the XSL in Listing D. Listing D

The .wpl to .m3u conversion XSLT

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" encoding="utf-8"/>

<xsl:template match="/">

<xsl:text>#EXTM3U</xsl:text>

<xsl:call-template name="crlf"/>

<xsl:apply-templates select="./descendant::media"/>

</xsl:template>

<xsl:template match="media">

<xsl:call-template name="folder">

<xsl:with-param name="path" select="./@src"/>

</xsl:call-template>

</xsl:template>

<!-- Only output the disc folder and file name -->

<xsl:template name="folder">

<xsl:param name="path"/>

<xsl:choose>

<xsl:when test="contains(substring-after($path,'\'),'\')">

<xsl:call-template name="folder">

<xsl:with-param name="path" select="substring-after($path,'\')"/>

</xsl:call-template>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select="$path"/>

<xsl:call-template name="crlf"/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<!-- Carriage Return/Line Feed -->

<xsl:template name="crlf">

<xsl:text>&#x0D;&#x0A;</xsl:text>

</xsl:template>

</xsl:stylesheet>

The code simply writes #EXTM3U followed by a carriage return/line feed and then writes the text for each media element's src attribute after the second from the last back slash (\). This is accomplished by the folder named template, which is recursively called with value of the src attribute, each time removing one back slash until either one, or less, remain.

In case you are wondering, the &#x0D; is the escape code for carriage return, and the &#x0A; is the escape code for line feed.

Also, the xsl:output element is extremely important; it identifies the output as text, and it defines the encoding as UTF-8. I made the mistake of leaving the encoding off, and it took me 20 minutes to figure out why the playlist didn't work even though it looked alright. In the end, I was able to apply the XSLT from Listing D to the Windows Media Player playlist from Listing A to produce the Winamp playlist in Listing E. Listing E

Contents of Led Zeppelin - Box Set.m3u

#EXTM3U

Led Zeppelin [Box Set] Disc 1\01 Whole Lotta Love.mp3

Led Zeppelin [Box Set] Disc 1\02 Heartbreaker.mp3

Led Zeppelin [Box Set] Disc 1\03 Communication Breakdown.mp3

Led Zeppelin [Box Set] Disc 1\04 Babe I'm Gonna Leave You.mp3

Led Zeppelin [Box Set] Disc 1\05 What Is and What Should Never Be.mp3

Led Zeppelin [Box Set] Disc 1\06 Thank You.mp3

Led Zeppelin [Box Set] Disc 1\07 I Can't Quit You Baby.mp3

Led Zeppelin [Box Set] Disc 1\08 Dazed and Confused.mp3

Led Zeppelin [Box Set] Disc 1\09 Your Time Is Gonna Come.mp3

Led Zeppelin [Box Set] Disc 1\10 Ramble On.mp3

Led Zeppelin [Box Set] Disc 1\11 Travelling Riverside Blues [#].mp3

Led Zeppelin [Box Set] Disc 1\12 Friends.mp3

Led Zeppelin [Box Set] Disc 1\13 Celebration Day.mp3

Led Zeppelin [Box Set] Disc 1\14 Hey Hey What Can I Do.mp3

Led Zeppelin [Box Set] Disc 1\15 White Summer-Black Mountain Side [#].mp3

Led Zeppelin [Box Set] Disc 2\01 Black Dog.mp3

Led Zeppelin [Box Set] Disc 2\02 Over the Hills and Far Away.mp3

Led Zeppelin [Box Set] Disc 2\03 Immigrant Song.mp3

Led Zeppelin [Box Set] Disc 2\04 The Battle of Evermore.mp3

Led Zeppelin [Box Set] Disc 2\05 Bron-Y-Aur Stomp.mp3

Led Zeppelin [Box Set] Disc 2\06 Tangerine.mp3

Led Zeppelin [Box Set] Disc 2\07 Going to California.mp3

Led Zeppelin [Box Set] Disc 2\08 Since I've Been Loving You.mp3

Led Zeppelin [Box Set] Disc 2\09 D'Yer Mak'er.mp3

Led Zeppelin [Box Set] Disc 2\10 Gallows Pole.mp3

Led Zeppelin [Box Set] Disc 2\11 Custard Pie.mp3

Led Zeppelin [Box Set] Disc 2\12 Misty Mountain Hop.mp3

Led Zeppelin [Box Set] Disc 2\13 Rock and Roll.mp3

Led Zeppelin [Box Set] Disc 2\14 The Rain Song.mp3

Led Zeppelin [Box Set] Disc 2\15 Stairway to Heaven.mp3

Led Zeppelin [Box Set] Disc 3\01 Kashmir.mp3

Led Zeppelin [Box Set] Disc 3\02 Trampled Under Foot.mp3

Led Zeppelin [Box Set] Disc 3\03 For Your Life.mp3

Led Zeppelin [Box Set] Disc 3\04 No Quarter.mp3

Led Zeppelin [Box Set] Disc 3\05 Dancing Days.mp3

Led Zeppelin [Box Set] Disc 3\06 When the Levee Breaks.mp3

Led Zeppelin [Box Set] Disc 3\07 Achilles Last Stand.mp3

Led Zeppelin [Box Set] Disc 3\08 The Song Remains the Same.mp3

Led Zeppelin [Box Set] Disc 3\09 Ten Years Gone.mp3

Led Zeppelin [Box Set] Disc 3\10 In My Time of Dying.mp3

Led Zeppelin [Box Set] Disc 4\01 In the Evening.mp3

Led Zeppelin [Box Set] Disc 4\02 Candy Store Rock.mp3

Led Zeppelin [Box Set] Disc 4\03 The Ocean.mp3

Led Zeppelin [Box Set] Disc 4\04 Ozone Baby.mp3

Led Zeppelin [Box Set] Disc 4\05 Houses of the Holy.mp3

Led Zeppelin [Box Set] Disc 4\06 Wearing and Tearing.mp3

Led Zeppelin [Box Set] Disc 4\07 Poor Tom.mp3

Led Zeppelin [Box Set] Disc 4\08 Nobody's Fault But Mine.mp3

Led Zeppelin [Box Set] Disc 4\09 Fool in the Rain.mp3

Led Zeppelin [Box Set] Disc 4\10 In the Light.mp3

Led Zeppelin [Box Set] Disc 4\11 The Wanton Song.mp3

Led Zeppelin [Box Set] Disc 4\12 Moby Dick-Bonzo's Montreux.mp3

Led Zeppelin [Box Set] Disc 4\13 I'm Gonna Crawl.mp3

Led Zeppelin [Box Set] Disc 4\14 All My Love.mp3

Conclusion

I hope you find this how to useful in organizing at least the musical part of your life. At the very least, you might be surprised to learn some of the places where you can find XML.

As for me, I'm going to listen to Led Zepplin's "Dazed and Confused" because that's what I am when I imagine myself a rebel.

1 comments
dms_smith
dms_smith

I converted all of my discs to the flac format, then drag this over to my sansa fuse player, this avoids all the mp3 stuff anf you have a true lossless backup on your harddrive & a playable version on sansa & winamp on your computer