Click here to Skip to main content
Click here to Skip to main content

Use LINQ to Create Music Playlists

, 29 Aug 2008
Rate this:
Please Sign up or sign in to vote.
See how to utilize LINQ along with Typed-DataSets to quickly build playlists for your music collection.

Introduction

Ever look for a program/code snippet to traverse your MP3 collection and create playlists along the way? The code in this article shows you how an ADO.NET DataSet, LINQ and a little recursion can make this happen quickly and easily.

A Note About the Demo Program

The demo program, once launched, will start from the Working Directory (the directory in which it was started) and traverse each folder hunting for .mp3 files. If it finds a folder containing .mp3 files, it will create a new .m3u playlist file for that directory and all directories/files beneath it. It will also DELETE any existing .m3u files that might already exist! If you download and run the demo program, it will remove (delete) any existing .m3u files.

Background

Like a lot of techie folks out there, I have converted my music collection into the digital world by ripping my CD tracks to MP3. I have my collection on a separate file-server which happens to be running IIS (6.0). Now I can access my music via SMB shares or via the "folder view" provided by IIS since I have the virtual directory configured for folder browsing.

This worked out pretty well for a while. I could access all my music via a web browser from any machine in my house, but something was lacking. After getting tired of having to click every song I wanted to play or manually create a playlist for every album, I got to tinkering around with LINQ...

The Algorithm

The basic algorithm for the program is as follows:

  1. Collect files/folders meta data

    • In order to gain the best possible performance with the least amount of disk utilization, I decided to create then dump all the directory names and files names into a simple, typed DataSet.
      Typed DataSet
    • Also while I'm recursing through the folder structure, I thought it'd be nice to "clean up" any existing .m3u files that might already exist. This is a sneaky cheat to not have to bother with updating existing lists, etc.
    • The last aspect of this chunk of code was to do a check for folders that contain .mp3 files. That's the [HasMp3s] column in the dbFolders DataTable. This is utilized later in LINQ.
  2. Then LINQ walked in...

    • To create the playlist files, I simply iterate through all the folders that [HasMp3s] is true and then use LINQ to query out the info needed to write the .m3u file.

Using the Code

Not a lot of code here! The bulk of the work for the meta data collection is done in the RecursePath(...) function. As you could guess by the name, it recurses through the folder structure doing the various tasks described in the "The Algorithm" section above. This code is pretty self explanatory so I won't cover it in detail here.

The interesting part is using LINQ to pull the info back out of the tables to do something constructive! First, let's iterate the dbFolders DataRows that contain .mp3 files...

// Loop through folders
foreach (var dr in _ds.dbFolders.Where(x => x.HasMp3s == true))
{

Notice the lambda expression to filter out the unwanted columns.

Then we open a StreamWriter...

    using (StreamWriter sr = new StreamWriter(Path.Combine(dr.Path, ALLM3U)))
    {

NOTE: ALLM3U is a string const that is file chosen filename for the output playlist file.

Now the fun part!

        var resSet = from d in _ds.dbFolders
                     join f in _ds.dbFiles on d.FolderId equals f.FolderId
                     where d.Path.StartsWith(dr.Path) && d.HasMp3s == true
                     select new { FullPath = Path.Combine(d.Path, f.Filename) };
            foreach (var item in resSet)
            {
                sr.WriteLine(item.FullPath.Replace(dr.Path + @"\", ""));
            }

We use LINQ to join the two tables together and filter out the records we don't want. Then we iterate the result set writing the lines of text into the current .m3u file.

After each loop, we make sure to close the StreamWriter and move onto the next loop...

    }
}

And that's it!

Points of Interest

IIS + .m3u + Windows Media Player = Cool Playlist Caching

One of the cool "extra's" I learned from this was that once you click the .m3u file and Media Player launches a song from the list, you can close the browser and still enjoy your list! Media Player caches the list so even return trips to Media Player will have the list saved. The list will dissolve if you launch something else with Media Player though...

History

  • 2008-08-25 - Wrote the code (in about an hour) and began creating this article.

To Do:

  • Get rid of the automagic .m3u deletion and update existing playlists instead.
  • Maybe create a WPF GUI and add fancy bells and whistles.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

davehamdan
Software Developer
United States United States
Dave has been working in the software industry for a few years now. Having graduated with his BS in Computer Science & Engineering from the University of Toledo in 2002, Dave enjoys learning about new technologies and likes to apply new programming methods to solve age-old challenges. In his spare time he is addicted to movies (sci-fi, horror, anything good!) and spending time with family and friends. Dave also harbors a secret desire to make it big in the film/music industry—here’s lookin’ at you, kid! ;o)

Comments and Discussions

 
Generalgood stuff Pinmembervegeta4ss3-Sep-08 6:41 
Good article. I needed simple functional examples like this to get me started with LINQ
 
keep up the good work.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 29 Aug 2008
Article Copyright 2008 by davehamdan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid