Ihan simppeli asia, mutta tuntuu olevan taas ylitsepääsemättömän vaikea saada toimimaan:
Soittimella on luotu soittolista ja homma pelaa sellaisenaan ok.
Tein soittimeen itse shuffletoiminnon käyttämällä erillistä sekoitettua biisi-indexi-listaa, koska wmp kontrollin oma shuffle on oikeasti vain random.
Shufflen ollessa päällä haluaisin ohittaa wmp kontrollin biisin vaihdon ja siirtyä itse valittuun seuraavaan biisiin.
Ongelmaksi koituu kuitenkin se, että kontrollissa on automatiikka, joka alkaa soittaa seuraavaa biisiä soittolistasta kun edellinen on loppunut, eikä tuota toimintoa voi ohittaa mitenkään kätevästi. Siispä soitin hyppää aina ensin itse käskemääni shuffle biisiin ja sen jälkeen lisäksi siirtyy yhden biisin eteenpäin aiemman (kontrollin oman) käskyn mukaisesti.
Eli, saako tuon automaattisesti seuraavaan biisiin siirtymisen jotenkin pois päältä, vai miten homma kannattaisi toteuttaa?
Alla esimerkki nykyisestä tavasta havaita biisin loppu. Esimerkissä siis soittimen pitäisi mennä stopille, mutta kontrollin sisäiset tapahtumat ohittavat tämän ja soitin siirtyy soittamaan soittolistan seuraavaa biisiä.
(Tuon stop-komennon tilalla minulla siis on käsky soittaa itse määrätty biisi.)
Private Sub player_PlayStateChange(ByVal sender As Object, ByVal e As AxWMPLib._WMPOCXEvents_PlayStateChangeEvent) Handles player.PlayStateChange Select Case e.newState Case 8 ' MediaEnded currentStateLabel.Text = "MediaEnded" player.Ctlcontrols.stop() ' <---- ei pysäytä soitinta?? Case Else currentStateLabel.Text = ("Unknown State: " + e.newState.ToString()) End Select End Sub
Moikka sniiki!
tsekkaa sattuuko stop-nappula oleen käytettävissä...
Dim controls As WMPLib.IWMPControls3 = player.Ctlcontrols If (controls.isAvailable("stop")) Then controls.stop() Else: MessageBox.Show("Stop-nappi ei ole nyt käytettävissä...") End If
Kiitos vinkistä Nea, täytyy tarkistaa tuo.
Ohitin ongelman (tavallaan) rakentamalla oman soittolistajärjestelmän. Tällöin playeriin ladataan yksi biisi kerrallaan ja näin estetään tuo automaattisesti seuraavaan biisiin siirtyminen. 'Media ended' tapahtumaan pistin muuttujan vaihtumaan todeksi ja eräässä ajastimessa tarkastellaan tämän muuttujan tilaa ja syötetään seuraava biisi kun edellinen loppuu. Kankeaa mutta toimii.
Sitten pari kyssäriä soittolistasta.
Oman soittolistan rakentamista puolsi myös seuraavat seikat:
-WMP:n soittolistaa ei pysty sorttaamaan mitenkään?? Ei siis mahdollisuutta järjestää listaa uudelleen aakkosjärjestykseen??
-Soittolistan tallentaminen omaan hakemistoon hankalaa. Lista tallentuu aina "playlistcollectioniin".
-Kunnollisen shufflen vaikea toteutus (alkuperäinen ongelma).
Omaa soittolistaa varten tein rakenteen
Structure Biisi nimi = biisin esittäjä - biisin nimi (stringi) wmpmedia = wmp kontrollin media objekti end structure
Musiikki kansio käydään läpi ja kaikista musiikkitiedostoista muodostetaan tiedot yllä olevaan rakenteeseen. Nämä tallennetaan arraylistiin, josta biisit haetaan käytön aikana.
Soittolista tallennetaan tekstitiedostona johon kirjoitetaan ainoastaan kappaleiden polu, esim c:\mp3\biisi.mp3.
Listaa ladattaessa niistä muodostetaan jälleen arraylist.
Homma toimii sinänsä ok. Sorttaaminen on helppoa kun erillisessä vertailijassa voidaan käyttää Biisi-rakenteen nimi-tietoa vertailuun.
Myös shuffle on helppo toteuttaa.
Listan käsittely on kuitenkin kankeaa ja esim. tallennetun listan lataaminen kestää yhtä kauan kuin tiedostojen hakeminen kokonaan uudelleen. Hitaus johtunee WMPMedia-objektien luomisesta.
EDIT: Miten pystyisin tallentamaan tuon omalla rakenteellani täytetyn arraylistin suoraan levylle ja lataamaan sen takaisin? Täten ohittaen samojen toimenpiteiden toiston.
Eli, onko joku rakennellut monipuolisen ja toimivan soittolistan käsittelyn WMP-kontrollilla? Kunnollinen shuffle-toiminto ja listan järjestely ovat siis asiat joita lähinnä kaipaan.
PS. Tein joskus listan sorttauksen heittämällä biisit wmp.currentplaylist:stä arraylistiin ja sorttaamalla sen räätälöidyllä vertailijalla, mutta muistaakseni soitin sekosi kun yritin siirtää mediaobjekteja arraylististä takaisin soittolistaan. Saattoi olla joku pieni kämmi, en jaksanut asiaan perehtyä sen enempää koska shuffle-toiminnon kanssa oli joka tapauksessa ongelma.
Itse itselleni vastailen.
Soittolistan järjestely onnistui ihan hyvin nyt. Muutin softaa siten, että lataan wmp media objektit listaan (list, ei enää arraylist) ja sorttaan listan alla olevalla vertailijalla.
Public Class SongSorter Implements IComparer(Of WMPLib.IWMPMedia) Dim title1, title2 As String Public Function Compare(ByVal s1 As WMPLib.IWMPMedia, ByVal s2 As _ WMPLib.IWMPMedia) As Integer Implements IComparer(Of WMPLib.IWMPMedia).Compare title1 = s1.getItemInfo("author") & " " & s1.getItemInfo("title") title2 = s2.getItemInfo("author") & " " & s2.getItemInfo("title") Return String.Compare(title1, title2) End Function End Class
Tallennuksen muutin siten, että Lista muunnetaan wmp soittolistaksi ja tallennetaan sen omaan kirjastoon. Kun se ladataan, wmp soittolistan biisit haetaan takaisin omaan listaan. Näin se pelaa nopeasti, ja listan järjestely & shuffletus (ja moni muu asia) on paljon helpompaa.
Nea:
Testasin toimintojen saatavilla oloa ihan perustilanteessa, jossa soitin soittelee jotain rallia
If WMP.Ctlcontrols.isAvailable("next") Then WMP.Ctlcontrols.next() Else : MessageBox.Show("no eihän siellä mikään nappi ei ole nytkään käytettävissä...") End If
Tuon mukaan next toiminto esimerkiksi ei ole koskaan saatavilla?
Soittimen MediaChange-eventinkin huomasin bugaavan ja se lakkaa toisinaan käynnistymästä. Samalla soittolistalla testailin painella seuraavaa biisiä ja ihan satunnaisesti lopetti toiminnan. Joskus ensimmäisellä kappalevaihdolla, joskus toimii kymmeniä kertoja.
Aihe on jo aika vanha, joten et voi enää vastata siihen.