Let the Music Play! (Matt Gertz)

Let the Music Play! (Matt Gertz)

  • Comments 44

Oh, boy.  Sorry I haven’t written any posts lately, but I’ve transitioned to a new job within Visual Studio and have been getting my sea legs there.  One of the job tasks is getting Visual Studio 2008 out to you folks, and while I’ve always been involved with that aspect of the product in the past, it was always to a lesser degree.  I could best describe each day now as “23 hours of nervous tension followed by one hour of utter panic” as we knock down the last few things that would otherwise keep us from shipping on time.

(Incidentally, in the spirit of making sure that the product works properly before we ship it, I’ve switched to writing code against Visual Studio 2008 using a build from last week.  Everything in this post, though, will still work using Visual Studio 2005, provided you have the current Windows Media Player.)

So, anyway, going forward I hope to do a post or two each month.  We’ll see how it goes, but it’s awfully hard to keep me from writing about Visual Basic, so I’m optimistic.  J  And on that note, on to today’s topic!

The problem with shuffling music

I’m a big music fan, with quite a large collection of songs that I’ve ripped onto my computer.  One of the things that I really appreciate about playing music on my PC is that I can listen to random tracks as if I were listening to a radio station (a radio station that always plays what I like and has no chatter) – I don’t hear the same old thing in the same old order every time.   The shuffle function gets a lot of use from me. 

There’s a difference between “shuffle” and “random” function, of course.  “Shuffle” generates a random list from an existing list and then plays that temporary list from beginning to end (so as to avoid replays), whereas with “random,” the next song is calculated on the fly.  Unfortunately, statistics being what they are, you’ve got a good chance in the latter case of hearing the same song twice (or more) in a session before all of the songs have been heard.  

Most good playback engines on PCs and cars do “shuffle” instead of “random” these days because of this, but shuffle isn’t a panacea, either.  The problem is that there are songs which are meant to be played adjacent to another song or else they don’t make sense.  The disc authors will break up two songs on a track which (in the listener’s opinion) are really the part of same song.  Take, for example, Pink Floyd’s excellent “Dark Side of the Moon” album, which is replete with this sort of issue.  Really, is there anyone out there who would listen to track 8 (“Brain Damage”) without listening to track 9 (“Eclipse”)?  Not likely; it’s a jarring experience to just have the first track end abruptly.

So, what happens?  I throw my favorite songs from various artists into a playlist.  I sync that to my music player and head out to mow the lawn, hitting “shuffle” so I'm not always hearing the same thing.  Sure enough, after a few minutes, I'm enjoying the last few lines of Jackson Browne’s “The Load-Out”:

But we’ll be scheduled to appear

A thousand miles away from here…

<pop! disconnect!>

Is this the real life?  Is this just fantasy?

Caught in a landslide…

 

Mentally, I was expecting the track to continue into Jackson Browne’s “Stay” instead of randomly switching to Queen’s “Bohemian Rhapsody,” and, although I do like the latter song, the transition is pretty darn jarring.

What I really want is a way to shuffle my tracks to get that nice sense of randomness, but also keep certain songs together to prevent any jarring playback from inappropriate segues.   I’ll code that solution up in this blog, but first I’ll need to cover some of the basics of how you write code against the Windows Media Player.

Windows Media Player coding concepts

The Windows Media Player control is a very powerful control with a lot of functionality, but understanding its object model involves a bit of a learning curve because there’s quite a lot to it.  Fortunately, once you understand the basics, it’s pretty easy to work with.  There are four really important concepts:

1.       The player itself.  Being a COM control, it gets wrapped for .NET so that you can write code against it without resorting to Declares, etc., and ends up being an object of type AxWMPLib.AxWindowsMediaPlayer.  Properties on the player include which of its controls show and its visibility, whether it auto-plays (via its “Settings” property), actions such as Play and Stop (via the Ctlcontrols property), and so on.

2.       The playlist.  This is the object that tells the player what media it should play.  You don’t “Dim” or “New” a playlist; instead, you ask the player for a new or existing playlist, and it returns an interface of type WMPLib.IWMPPlaylist to the result, on which you can then call methods.

3.       The media.  Again, these are not objects that you create yourself.  There are methods on the player and the playlist which will return interface values (WMPLib.IWMPMedia) for them.  The playlist is made up of media objects.

Once you’ve got that in hand, the rest is pretty easy – honest!  Let’s run through some examples here.

Part 1:  Playing a song

The “Hello, world!” of a music player would be, of course, playing a song.  First, create a new Windows Application and make sure that the toolbox is displayed for the resulting form.  We’ll need to add the Windows Media control to the toolbox, so right-click on the toolbox and select “Choose Items…”  In the resulting dialog, navigate to the “COM Components” tab, scroll down towards the bottom, and check the box to the left of the Windows Media Player.  Press “OK,” and the Windows Media Player (which I will henceforth refer to as the WMP) will be added to your toolbox.  Drag an instance of it over to your form and size it however you like.  (By the way, I’m using the most recent version of WMP, which is version 11 and which you can download for free from Microsoft if you don’t already have it.  Earlier versions of the Windows Media Player might not support this all of this code, depending on how old they are.)

While the WMP is still selected, go to the property grid and change its name to “Player” (as the default name is quite a mouthful otherwise).   Now, double-click on the form background (not the WMP) to create the “Form1_Load” event.

In Form1_Load, we’ll create a new playlist for the WMP to play:

        Dim playlist As WMPLib.IWMPPlaylist

        playlist = Me.Player.newPlaylist("My groovy playlist", "")

 

The first argument to newPlaylist is the name of the new playlist, and the second is a URL to an existing Playlist with whose contents we want to initialize it.  I’ve left it as the empty string because in this example I want to start with an empty playlist.  (Note that the new playlist is not automatically added to your library, so don’t worry about cluttering up your library here.  To actually make the playlist permanent, you’d need to call either importPlaylist or newPlaylist from the IWMPPlaylistCollection returned from Player.playlistCollection property.)

Now, I want to add a song to the new playlist:

        Dim item As WMPLib.IWMPMedia = Player.newMedia("file:///C:\Users\Matt\Music\Dead Can Dance\Spleen and Ideal\08 Avatar.wma")

        playlist.appendItem(item)

 

The argument to newMedia is a URL, so if I’m using a file from disk, I need to use a URL format (basically, prepend “file:/// to the absolute path in this case).  Of course, I normally wouldn’t hardcode this path; I’d read the file name from a file dialog, but I’ve already covered file dialog usage in a previous post so I’ll skip it here for clarity’s sake.

Next, I’ll add the playlist to the player:

        Player.currentPlaylist = playlist

 

Now, let’s press F5.  The application launches and, assuming that there’s no mistake in URL we specified, the music automatically starts playing.   You can use the WMP controls to control volume and so forth.

Now, it’s possible that you don’t want the music to play until the user actually pushes the “Play” button.  This is easy enough to do – simply add this line somewhere *before* you assign the playlist to the player:

Player.settings.autoStart = False

And now you’ve got a way to play any media file (or set of media files) from inside your Windows application, with the user in full control of the playback.  Cool, huh?

Part 2: A smarter shuffle

Let’s start out with the following code in Form1_Load:

        Player.settings.autoStart = False ' Otherwise, playlists will automatically play when added to the player

 

        ' Create a new playlist

        Dim oldplaylist As WMPLib.IWMPPlaylist

        Dim newplaylist As WMPLib.IWMPPlaylist

        oldplaylist = Me.Player.newPlaylist("Original Sorted Playlist", "file:///c:\Users\Matt\Music\Playlists\One True Playlist.wpl")

        newplaylist = Me.Player.newPlaylist("Smart Shuffled Playlist", "")

 

Note that I’m creating two playlists here – one which identically matches a favorite playlist of mine, and one which is empty.  I’ll use the empty one to store my smartly-shuffled playlist.  Note that I could use Player.playlistCollection.getByName(“One True Playlist”).Item(0) to point to the existing playlist instead of a copy, but since I’m going to be removing media items from one list and moving them to another, that would be destructive to the original.  (I could also have sorted within one copied list like I did with card shuffling in an earlier blog post, and avoid even using a second list, but since I’m reusing most of the memory here anyway – that is, the media objects – I’m opting for a more readable implementation this time.  Either would work.)  Again, I would normally use a file dialog to browse to the playlist rather than hard-coding it – I’m just trying to keep it simple here.

I’ll need a random number generator to pick songs to pull over.  If you’ve read my earlier Euchre blog post, you’ll know I usually use a complex one to guarantee the best distribution I can get; however, this being just for a music player, I’ll go with plain-old Random() for brevity’s sake.  For the range of the random number, I’ll need to know how many songs we’ll be moving, which I can get from the playlist count.  For this first attempt, I’ll just shuffle without regard to disjointed songs:

        ' Randomize the values using system time as a seed

        Microsoft.VisualBasic.Randomize()

 

        ' Get the number of songs to use

        Dim numberOfSongs As Integer = oldplaylist.count

 

        ' The value i will keep track of the number of songs left to copy,

        ' which in turn helps us keep track of the range for valid random numbers.

        For songsRemaining As Integer = numberOfSongs - 1 To 0 Step -1

            ' Pick a random song from whatever remains in the old list:

            Dim SongToCopy As Integer = Microsoft.VisualBasic.Rnd() * songsRemaining

            Dim mediaItem = oldplaylist.Item(SongToCopy)

 

            ' Append it to the new list

            newplaylist.appendItem(mediaItem)

 

            ' Remove it from the old list, which will have its count decrease

            oldplaylist.removeItem(mediaItem)

        Next

 

        Player.currentPlaylist = newplaylist

 

The variable “songsRemaining” is pulling double-duty here – it makes sure (via the For loop) that I copy over exactly as many songs as possible, and it also constrains the random variable to however songs are remaining in the initial list.

That code works fine for a simple shuffle (go ahead & try it, using one of your own playlists!), but it doesn’t do anything that Windows Media Player can’t already do.  So, now I want to massage this code into something which keeps certain songs together.  My general plan will be to have some sort of “tag” on songs to indicate that they below with another song, and then if I encounter a random media item which is part of that duo (or trio, or whatever), I’ll bring the others along as well, in the proper order.  The trick will be figuring out what tag to use.  Fortunately, there are some custom fields associated with media items that I can leverage here.

Ideally, the information that gets downloaded with songs would pre-populate some field which would indicate that one song always belongs with another, but that unfortunately isn’t the case.   So, we’ll have to do it ourselves.  If you navigate to your music collection in File Explorer, you can right-click on a song and bring up a property sheet for it.  On the "Details" tab, towards the bottom, you’ll notice a property called “Part of set”.  We’re going to leverage that property to track that “togetherness” for an arc of songs.  (I could just as easily have leveraged the “Comments” property, for example, but using this one made more sense to me and as far as I could tell, none of my other songs were using it for something else.)  To set the property, first find an album which has songs that should play together.  For example, I’m going to use The Moody Blues’ release “Long Distance Voyager ,” which includes an arc of three songs at the end of the album which should always go together (“Painted Smile,” “Reflective Smile,” and “Veteran Cosmic Rocker”).  Right-clicking on the first song in the arc, I’ll set its “Part of set” field to 1 and apply the changes, then bring up the properties for the next song and set the field to 2, and then finally 3 for the last song of the arc.

I’ll then go into Windows Media (the desktop one, not the control you added) and create a playlist called “Test” which includes all of the songs from that album for my experiment.  You can do this by clicking “Create playlist” on the left side of the player, giving it the title "Test," dragging the appropriate songs to the resulting playlist editor on the right, and then clicking "Save playlist."  That’s the playlist I’ll be copying from – you can, of course, start with any playlist you like, but I wanted to keep the number of songs small while debugging the app.  (The playlist I used in the previous example does include the aforementioned Moody Blues tracks, but it also has about 600 other songs and thus is not the best choice to use when stepping through the debugger, as you might imagine.)

Now, in my code, I can check for the presence of one of the “Part of set” values and react by copying the adjacent songs in order as well as the randomly selected song.  Note that I’m assuming  that the original list is sorted in track order per each album (or partial album) included on the playlist – if not, you’ve got to do some additional work to look up the album information and see what should be kept adjacent to each other, whether it's all in the playlist somewhere, etc., all of which is an exercise that I’ll leave to the reader.  For my part, I’ll just check to make sure that the numbers are used contiguously and, if not, default to the “normal” copy behavior.  Here’s the final code; I’ll let the comments speak for themselves:

        Player.settings.autoStart = False ' Otherwise, playlists will automatically play when added to the player

 

        ' Create a new playlist

        Dim oldplaylist As WMPLib.IWMPPlaylist

        Dim newplaylist As WMPLib.IWMPPlaylist

 

        ' You should really use a file dialog to get this path to the existing playlist.

        oldplaylist = Me.Player.newPlaylist("Original Sorted Playlist", _

            "file:///c:\Users\MattGe\Music\Playlists\Test.wpl")

 

        ' This playlist is initially empty, and we’ll fill it with songs. 

        ' You could give the user the option of picking the name for it

        ' by reading it from a label control.

        newplaylist = Me.Player.newPlaylist("Smart Shuffled Playlist", "")

 

        ' Randomize the values using system time as a seed

        Microsoft.VisualBasic.Randomize()

 

        ' Get the number of songs to use

        Dim numberOfSongs As Integer = oldplaylist.count

 

        ' The value songsRemaining will keep track of

        ' the number of songs left to copy,

        ' which in turn helps us keep track of the range

        ' for valid random numbers.

        For songsRemaining As Integer = numberOfSongs - 1 To 0 Step -1

            ' Pick a random song from whatever remains in the old list:

            Dim songToCopy As Integer = _

                 Microsoft.VisualBasic.Rnd() * songsRemaining

            Dim mediaItem As WMPLib.IWMPMedia = oldplaylist.Item(songToCopy)

 

            ' Check the "Part of set" attribute -- see

            ' http://msdn2.microsoft.com/en-us/library/bb248408.aspx

            ' for a list of attributes for different media types.

            Dim sPartOfSet As String = mediaItem.getItemInfo("WM/PartOfSet")

 

            ' See if the value is a number.

            If sPartOfSet <> "" AndAlso IsNumeric(sPartOfSet) Then

                ' It's a number.  We may have an arc of songs here. 

                ' Get the number and rewind to the first one.

                ' If we run into anything unexpected then just

                ' do a normal copy.

 

                Dim iPartOfSet As Integer = sPartOfSet

 

                ' Make sure we don't go past the beginning of the list!

                If songToCopy - (iPartOfSet - 1) >= 0 Then

                    ' Rewind to what should be the beginning of

                    ' the arc and get the song.  (Hopefully, they’re all

                    ' there, but I’m not going to count on them being all

                    ' all there and initially in the right order.  My

                    ' default when confused will be to just copy the

                    ' originally picked song as if it wasn’t part of an arc.)

                    Dim currentSongToCopy As Integer = _

                        songToCopy - (iPartOfSet - 1)

 

                    Dim currentMediaItem As WMPLib.IWMPMedia = _

                        oldplaylist.Item(currentSongToCopy)

 

                    Dim sCurrentPartOfSet As String = _

                        currentMediaItem.getItemInfo("WM/PartOfSet")

 

                    ' Do some error checking here -- the attribute had

                    ' better be "1" – otherwise, do a normal copy instead

                    If Not sCurrentPartOfSet = "1" Then GoTo NormalCopy

 

                    ' OK, we're probably good to go, unless we coincidentally

                    ' got the beginning of another arc instead

                    ' due to discontinuous numbers.  Worse thing that happens

                    ' in that case is that we just copy a different

                    ' arc, and we’ll pick up these pieces later.

                    iPartOfSet = 0

                    While sCurrentPartOfSet <> "" _

                      AndAlso IsNumeric(sCurrentPartOfSet) _

                      AndAlso CInt(sCurrentPartOfSet) = iPartOfSet + 1

                        newplaylist.appendItem(currentMediaItem)

                        oldplaylist.removeItem(currentMediaItem)

                        iPartOfSet = iPartOfSet + 1 ' Copied one song

 

                        ' Check next song if there are any remaining

                        If currentSongToCopy = oldplaylist.count Then

                            Exit While

                        End If

 

                        currentMediaItem = _ oldplaylist.Item(currentSongToCopy)

                        sCurrentPartOfSet = currentMediaItem.getItemInfo("WM/PartOfSet")

                    End While

 

                    If iPartOfSet > 0 Then

                        ' We may have copied more than one song. 

                        ' Update the For loop variable

                        ' appropriately to compensate, since For loop

                        ' will only decrement by one.

                        songsRemaining = songsRemaining - (iPartOfSet - 1)

                    Else

                        ' Didn't copy anything -- must have been a

                        ' discontinuity.  Just copy the original song,

                        ' since user apparently doesn't care.

                        GoTo NormalCopy

                    End If

                Else

                    ' Error -- starting songs not available.  Just copy

                    ' the song, since user apparently doesn't care.

                    GoTo NormalCopy

                End If

            Else

                ' Just copy like normal

NormalCopy:     newplaylist.appendItem(mediaItem)

                oldplaylist.removeItem(mediaItem)

 

            End If

        Next

 

        ' Point player at the new playlist so it can be played

        Player.currentPlaylist = newplaylist

 

Immediately on hitting F5, you can play the songs in the new order on your PC, without fear of bizarre transitions from one song to the other.  However, to "take it on the road," you could also use the following code to add the playlist to your library and your file system:

        ' Save new playlist to library and Music\Playlists

        Player.playlistCollection.importPlaylist(newplaylist)

 

You could then use that playlist to sync to your music player or, if your music is already on a flash card, just copy that resulting WPL file to your flash card so that your Windows Media supporting device can play your songs in the new shuffled order.

So, play your party mixes or head out to jog knowing that you can get a pleasant randomness in your playlists without those jarring segues between unconnected songs!  ‘Til next time…

--Matt--*

Leave a Comment
  • Please add 3 and 6 and type the answer here:
  • Post
  • thank you matt again

    1)can you send how can i get all files names in coding

    .....

    2)i want to ask you about a good skin maker for vb.net programs

    3)how can i handle a keyboard event when my form is minimized

    i mean

    in jetaudio you can next the song by pressing nextmedia button

    and this works even you are working on another program(i.e playing a game like fifa... )

    4)

    i made the owner of vedio a panel on form2

    the problem is panel does not responding to mouse doubleclick event

    but respond to mousedown event

    why do you think this happens

    (i want to maximize vedio form by double clicking not by mousedown)

    another thing

    why when i make my video in  fullscreen

    my form stop responding to any keyboard event

    i mean

    i made form2 closes when press escape

    every thing works very good untill i make the vedio

    in fullscreen mode

    then my form2 never responds again to keypress or keydown events

    even i make it in normal mode

    ........

    finally

    why the vedio owner always be at front

    i mean

    no control you add to your form above the panel(owner) appears above it is always behind(never appear when vedio is playing)

    i tried to add a trackbar above the panel to control video seeking

    it did not work

  • (1) I'm going to post the blog today which will show how you get the filenames.

    (2) Alas, I don't know anything about skin makers.

    (3) Usually, apps that handle keystrokes when minimized aren't actually minimized -- there's still a form up somewhere (possibly invisible) which catches the keystrokes.  It's generally not considered a good thing to do since it confuses the user.

    (4) I haven't noticed the problem, as I really haven't done much with video playback; however, I do know that video involves a painting sequence -- that painting has to be fast, so it might be a bit-blast.  I'm not sure, though -- you might ask the Windows Media team since they own that control.

    --Matt--*

  • (3.5) I've never tried using a panel with media player -- not sure what would be going on here, sorry.

  • (This post assumes that you’ve read my previous post on Windows Media at http://blogs.msdn.com/vbteam/archive/2007/10/30/let-the-music-play-matt-gertz.aspx

  • (This post assumes that you’ve read my previous post on Windows Media at http://blogs.msdn.com/vbteam

  • Saleem, my latest post is up now -- it should answer your questions around the command-line arguments.  Enjoy!

    --Matt--*

  • thank you matt for every thing

  • hi matt

    i asked you befor about handle keyboard events while

    your application is minimized

    you told me that there shoulde be somthing

    not minimized to handle events even i don't see it

    i am thinking to add a new form to my application

    and make its capacity=0

    (because if it is hidden it can't handle events)

    i think it is not a good idea

    because your form should be active to handle keyboard events

    .......

    is not there a way to watch keyboard with every timer tick?

    or somthing like

    onkeypress do.....

    or

    if keypressed do...

    and put it in timer do you think this works?

    and thank you again?

    .......

    can you tell me if you know

    how this is achieved in jetaudio and windows mediaplayer

    is visual c++ better than visual basic?

    i mean does c++ have special tools to do this

    .....

    somthing like assembly code for watching keyboard input or somthing so...

    and thank you again.........

  • Well, that was… intense. You may have noticed the lack of articles coming from my direction. I have been

  • I want to hide WMP on my form and create my own controls for it.  But whether I use WMP on the form or hide it and create my own controls, when I play something from the form, WMP is no longer minimized, but becomes a regular window on the desktop.  Is there any way to keep WMP minimized on the desktop?

  • Hi, JFS,

     Try setting uiMode to invisible on the WMP control (see http://msdn.microsoft.com/en-us/library/dd563546(VS.85).aspx for more details on uiMode) and see if that works.  It might not; if WMP is already launched as a separate app on your OS, I think it's going to preferentially activate it, and I don't know how to stop that.  (I notice a very similar behavior with Office, for example -- if I have a Word document minimized, and then double-click on another Word document's icon, the first document will restore when the second is opened -- kind of annoying, actually.)

  • matt see i made my media player and it plays songs and instead of making a new playlist i made a list box so if i select the song and press a button "PLAY" it plays the selected song once its over it doesnt go ovr to d next song how do i do tat

    2. it doesnt play mpeg4 files

    3 how do i put a burner in it

    4. how do i make sure that if i select a song and press enter it starts playin

    PS: I'm 14 so make it simpler to write d code

  • Hi, Mahir,

     Sorry for the late response -- I've been on vacation for the past couple of weeks.  So, in order:

    (1) Songs will only proceed to the next song automatically if they are part of a playlist.  You could write code to check for the termination of one song and then automatically call the next one, but then you'd essentially be duplicating what playlists already give you, so that's not efficient.  You're already duplicating WMP somewhat by having the listbox, since the full UI mode of WMP will already show you the list of songs.  It seems to me that what you're really asking is "how do I create my own UI on top of WMP, instead of using the default UI" -- if so, you'll need to handle the events that are sent when a trick changes.  Start with the documentation for IWMPEvents at http://msdn.microsoft.com/en-us/library/bb905806.aspx.

    (2) See http://support.microsoft.com/kb/835861 -- maybe this is the issue that you are running into?

    (3) Use the methods on the IWMPCdromBurn interface -- see http://msdn.microsoft.com/en-us/library/dd563081(VS.85).aspx.  You can get a reference to the IWMPCdromBurn interface (which essentially represents your CD burner) from the get_cdromCollection method from the AxWindowsMediaPlayer. (I've never used any of this before and so I am not familiar with it myself.)  

    (4) Remember that you can assign objects to listboxes -- you don't have to just assign strings.  The listbox will use the "ToString" method to determine what it shows.  If the object's ToString method shows something other than what you'd expect, it's best to wrap the object and create your own ToString method.  So, for example:

    Class MyMediaWrapper

     Private m As WMPLib.IWMPMedia

     Sub New(ByVal mediaItem As WMPLib.IWMPMedia)

       m = mediaItem

     End Sub

     Public ReadOnly Property Media() As WMPLib.IWMPMedia

       Get

         return m

       End Get

     Overrides Function ToString() As String

       Dim s As String

       m.get_Name(s)

       Return s

     End Function

    End Class

    So, create a MyMediaWrapper to represent a track, add it to the listbox, and when it's chosen, retrieve the media item using the property Media that you created, and use CtlControls.playItem() on the AxWindowsMediaPlayer to play it.

    Hope this helps!

     --Matt--*

  • I have follwoed your code at the start of the article to write a new playlist to my library. I have used VB2008 (for WMP11) to select track titles, numbers and locations from an MS Access database.

    When I open WMP and try and play the new playlist I get an error message

    "Windows Media Player cannot find the file. If you are trying to play, burn, or sync an item that is in your library, the item might point to a file that has been moved, renamed, or deleted."

    I note that the track number (from the individual WMA files) are not separate but are included  with the title.

    I wonder if using the prepend “file:///” to the track location is the problem?

    Like you I want to be able to write playlists and synch them to my Walkman but not have the fag of dragging and dropping tracks in WMP.

    Any ideas what I am doing wrong?

    Colin Reid

    ickleton@aol.com

  • Hi, Colin,

     A couple of points:

    (1) You mentioned the track number (presumably as a potential cause):  WMP's default (when ripping music from media) is to include the track number as part of the filename when it creates the file.  But once it's in there, it's just part of the string, and no longer has any real relevance otherwise.  (I regularly change the track metadata without bothering to change the corresponding filename -- in fact, even though the filename is initially constructed from the track number and the track name, you can change it to anything you want thereafter -- WMP is usually good about seeing those changes afterwards, though sometimes you have to prod it.)  So, as long as you are pointing to the actual full filename, you should be OK.

    (2) You only need to use the file:/// prefix when loading a playlist to the media player in code.  The tracks within the playlist should not be using it; they are pathed relative to the playlist.  For example, the tracks of a playlist look something like this:

               <media src="..\Pink Floyd\Dark Side of the Moon\08 Brain Damage.wma" cid="{2B680CA5-1A7D-40EC-9188-B25E85D66A9D}" tid="{A2EDDF17-31B5-4379-A364-44F567A71895}"/>

               <media src="..\Pink Floyd\Dark Side of the Moon\09 Eclipse.wma" cid="{479AC96E-A50B-4A89-A187-BF8877C301AD}" tid="{5DE121DE-0E3B-44F9-9573-0450372EE1B5}"/>

               <media src="..\Cake\Comfort Eagle\04_-_Short_SkirtLong_Jacket_(Album_Version).mp3" cid="{76055DB1-0791-4B52-A8B1-9AF0A045459A}" tid="{1F6F67A8-9E1D-4C33-95A3-7B22853A087F}"/>

               <media src="..\Alan Parsons\Valid Path\09 Chomolungma.wma" cid="{D53D322F-67BE-4E78-B9CC-417DC83C6EAA}" tid="{FDF9630F-69C5-4300-B360-9152F0281EF0}"/>

               <media src="..\Dead Can Dance\Spleen and Ideal\08 Avatar.wma" cid="{D82F6E54-973E-4D5C-BE7F-598E37A4C597}" tid="{36DEC1A5-F977-4771-89E5-C9510750692B}"/>

    If you can't get it to work, here's what I'd like you to try:  Launch your homemade program and add a few tracks, saving the resulting playlist.  Now add the same tracks to a new playlist, using WMP to create the playlist.  Now use Notepad to compare the two playlists and see where the difference is.

    --Matt--*

Page 2 of 3 (44 items) 123