VB.NET - creating a shuffle or random for my media player

Asked By jenn on 03-Sep-10 11:09 AM
good morning guys :)

am working on a media player (music ability only)

I have been trying desperatly to figure out how to make it shuffle...or randomly play the music that is in the "listbox".

have been up and down the net looking for some solution that is tweakable to make this happen and have not had any luck with it as yet!

see, I am using 2 listboxes. Listbox1..is underneath Listbox2..and is not visible to the user. The listbox 1..holds the actual filepaths of the songs being played. (i.e...d:/my music/ArCAnGeLs/I believe in you/yadda yadda yadda.)

and then in listbox2..the one that is seen by the user..will hold just the name of the song (i.e...I Believe In You.Mp3)

what I want it to do is if the user has a whack of songs sitting in the "play box"..(lol) and hits the "shuffle" button..I want that list of music to play in any freakin order the computer feels like playin em in LOL..

I do not have code snippets for this cuz as I said nothing I have tried will even work lol

however, I do have the snippets for the listboxes...maybe that will be enough to tell just what path this little beady brain of mine is on!!....

here are the codes for the listboxes:
'Listbox1 is attached to listbox2, so any changes made in one will affect the other
  
Private Sub ListBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox2.SelectedIndexChanged
    Listbox1.SelectedIndex = ListBox2.SelectedIndex
  
'This is the load button for the listboxes
  
Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoad.Click
    Dim ofd As New OpenFileDialog
    ofd.Multiselect = True
    ofd.ShowDialog()
    For I As Integer = 0 To ofd.FileNames.Count - 1
      Listbox1.Items.Add(ofd.FileNames(I))
      ListBox2.Items.Add(ofd.SafeFileNames(I))
    Next
    If Listbox1.Items.Count = 0 = True Then
      MsgBox("Nothing To Play!", MsgBoxStyle.Critical, "File Error!")
    Else
      Listbox1.SelectedIndex = 0
      ListBox2.SelectedIndex = 0
  
    End If
  
'This is the play button for the listboxes
Private Sub btnPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPlay.Click
    If Listbox1.Items.Count = 0 = True Then
      MsgBox("Nothing To Play", MsgBoxStyle.Critical, "Nothing To Play!")
    Else
      wmp.URL = Listbox1.SelectedItem
    End If
  End Sub
Sasha Kotlo replied to jenn on 03-Sep-10 11:38 AM
It is rather simple using the Random class.

Random rand = new Random();
ListBox1.SelectedIndex = rand.Next(0, ListBox1.Items.Count - 1);

what the second line does is selects the random number between 0 (first song in the list) and the total number of files in the list (-1 since the list starts from 0 not 1).

That's all.

Enjoy.
jenn replied to Sasha Kotlo on 03-Sep-10 11:45 AM
LOL...are you serious??????????????!!! hehhehee..okay, well that is MUCH simpler than what I been tryin to do LOL!
I will give this a whirl and see what happens :), thank you so much for the quick reply and I will let you know just how it went!
Sasha Kotlo replied to jenn on 03-Sep-10 11:47 AM
Yes I'm serious. You will still need to call the play command tho which is the following line as I see from your code:

wmp.URL = Listbox1.SelectedItem

so after assigning the SelectedIndex call the wmp.URL thingy you did here.

Cheers.
jenn replied to Sasha Kotlo on 03-Sep-10 12:07 PM
Okay :), we are for sure getting somewhere! that worked okay, thank you :)

now I have another question, what this code is doing is this: it will pick out a song on the list at random (which is good) but then it will play the next one right after that, instead of shuffling around. I took a look at this, and what keeps coming into my head for some UNGODLY reason is this:

there is nothing wrong with the random (shuffle) code that he gave for you, the problem is in the PLAY ALL code. I have got it set to play the next one in line automatically. I feel that this is somehow overriding the "shuffle" code??

anyway, I am wondering if you would not mind to take a look at it and tell me what you think?? it would be greatly appreciated! :)

here is the code I have for the "play All" Checkbox:

'This is for the play all check box
  
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
  
If CheckBox1.Checked = True Then
  
If wmp.playState = WMPPlayState.wmppsPlaying = True Then
  
ElseIf wmp.playState = WMPPlayState.wmppsStopped = True Then
  
Listbox1.SelectedIndex = Listbox1.SelectedIndex + 1
  
ListBox2.SelectedIndex = ListBox2.SelectedIndex + 1
  
wmp.URL = Listbox1.SelectedItem
  
ElseIf CheckBox1.Checked = False Then
  
wmp.URL = Listbox1.SelectedItem
  
End If
  
End If
  
End Sub
  
#End Region
jenn replied to Sasha Kotlo on 03-Sep-10 12:08 PM
forgot ta flag the helpful post!! sowwwwwy!!
Sasha Kotlo replied to jenn on 03-Sep-10 12:32 PM
ok jenn. let's say you have 2 radio buttons on your form. 1 is shuffle the other is continuous. Both can't be on at the same time for obvious reasons. when you set that up you can also declare an application wide variable named isShuffle. It needs to be boolean of course. I will be writing C# variants here but you can convert it to VB.NET easily:

bool IsShuffle = false;

Now when you click the Shuffle checkbox you set the value of IsShuffle to true as well. When you uncheck it you set the variable to false too. So now let's move on:

if(wmp.playState == WMPlayState.wmppsPlaying)
{
// do nothing in this case since song is still playing
}
else
{
if(IsShuffle)
{
// in case shuffle is on use the random code given before
Random rand = new Random();
ListBox1.SelectedIndex = rand.Next(0, ListBox1.Items.Count - 1);
}
else
{
// its continuous play so play next song
if(ListBox1.SelectedIndex + 1 <= ListBox1.Items.Count - 1)
{
// it means we are not playing the last song in the list so you can tell it to move to the next one
ListBox1.SelectedIndex = ListBox1.SelectedIndex + 1;
}
else
{
// it's the last song in the list so either move to index 0 from here or stop the music completely
ListBox1.SelectedIndex = 0;
}
}

// now when you're done deciding which song needs to be selected set the URL to currently selected item
wmp.URL = ListBox1.SelectedItem;
}

Hope this helped you.

Cheers.
jenn replied to Sasha Kotlo on 03-Sep-10 01:10 PM
okay, I do understand bout cant be Going and stopping at the same time LOL..confuses the hell out of the computer for sure! hehheehehee

will give your example a try and let you know how it went :), wont be til monday tho cuz well...you..know..the weekend heheeee

and thank you for all of your help, it was greatly needed!

jenn replied to Sasha Kotlo on 08-Sep-10 02:25 PM
I dunno :(

lol..there is just something that I just seem to be missing (besides my brain, that is!) ;)~

when I load 4 or 5 songs, and I check the "play All" checkbox, it does play all the songs.
when I load a couple of songs, and chck the "play All" checkbox..and then Hit the "Shuffle" Button..it just doesnt do right LOL

it will skip down to a song and play the song, and then immediatly at the end of the song, it will play the list in order.
when it finishes the list, instead of starting over at the top..it gives me out of range error. I know that this error is cuz I dont have any code to tell it what to do when it hits the bottom of the list.

but I do not understand where I am buggering up this freakin "shuffle button" at!

do I have to maybe make the "shuffle" button a checkbox as well?? like the play all box?? i mean, maybe because the "shuffle" is a button, you have to click it each time you want to random the songs in the list..where as a checkbox can be set on a time like the "play all"??

at any rate Sasha Kotlo, here is the code that i now have set for my "shuffle button" (which maybe should be a checkbox...) when you have some time and are feeling generous, could you once again take a look at it??

thanxxXXX :)

Private Sub btnShuffle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShuffle.Click
    Dim IsShuffle As Boolean
    If wmp.playState = WMPPlayState.wmppsPlaying Then
    Else
      If IsShuffle Then
        ' in case shuffle is on use the random code given before
        Dim rand As New Random()
        Listbox1.SelectedIndex = rand.[Next](0, Listbox1.Items.Count - 1)
        ListBox2.SelectedIndex = rand.[Next](0, ListBox2.Items.Count - 1)
      Else
        ' its continuous play so play next song
        If Listbox1.SelectedIndex + 1 <= Listbox1.Items.Count - 1 Then
          If ListBox2.SelectedIndex + 1 <= ListBox2.Items.Count - 1 Then
            ' it means we are not playing the last song in the list so you can tell it to move to the next one
            Listbox1.SelectedIndex = Listbox1.SelectedIndex + 1
            ListBox2.SelectedIndex = ListBox2.SelectedIndex + 1
          Else
            ' it's the last song in the list so either move to index 0 from here or stop the music completely
            Listbox1.SelectedIndex = 0
            ListBox2.SelectedIndex = 0
          End If
        End If
        End If
  
  
      ' now when you're done deciding which song needs to be selected set the URL to currently selected item
      wmp.URL = Listbox1.SelectedItem
    End If
  End Sub
Sasha Kotlo replied to jenn on 08-Sep-10 02:47 PM
Hey Jenn,

I didn't review your entire code but I see 1 thing is wrong right away. This line:

Dim IsShuffle As Boolean

This needs to be a Page wide variable (so that means outside of any method or event). The way you did it the value is lost immediately after the event where you instantiated it is complete. So for example this is what it should look like (C#):

bool IsShuffle = false;
protected void Page_Load(object sender, EventArgs e)
    {
        
    }

You see how in my code it is not inside any method but inside the codebehind file directly? This is how you need to do it.

Regards.
jenn replied to Sasha Kotlo on 08-Sep-10 02:55 PM
yes, i think you are trying to tell me that the Dim IsShuffled as Boolean needs to be way up at the top of the form, right under the "Public Class Frm 1" or even above that, under all the IMPORTS i have LOL..so that it goes form wide instead of just in one instance. okay I will try moving that line around a bit :)