Übersicht Windows Media Player

  • VB.NET

Es gibt 72 Antworten in diesem Thema. Der letzte Beitrag () ist von kafffee.

    kafffee schrieb:

    früher mal tatsächlich so eine DB gab, der Betrieb aber eingestellt wurde. Weiss da jemand vielleicht was drüber?

    Jupp FreeDB. Der Betrieb ist glaub letztes, vorletztes?, Jahr eingestellt worden. Es gibt aber andere alternativen wie zB. musicbrainz.org Hier wird die Schnittstelle dazu beschrieben: musicbrainz.org/doc/MusicBrainz_API
    Mfg -Franky-
    Ja es gab so eine DB, aber beim Suchen zu Infos darüber habe ich gelesen, dass der Betrieb eingestellt worden ist.
    Der WMP versucht ja auch die Infos zu der eingelegten CD zu Bekommen und meldet dann
    kann keine Medieninformationen für diese CD herunterladen.
    Die Meldung bekomme ich immer, auch wenn die CD kein Ladenhüter war.

    Ja, die Zeit ist begrenzt.
    Selber programmieren finde ich auch besser, aber ein Programm was direkt den CD Brenner anspricht und dafür sorgt, dass er eine Audio CD ausspuckt,
    ist viel mehr als ich in akzeptabler Zeit lernen könnte.

    Insofern ist eine DLL wie vom WMP zu verwenden meiner Meinung nach die nächstbessere Lösung.
    Ein Beispielcode der die DLL verwendet spart auch Zeit, wenn ich den Sourcecode verstehe. Irgendetwas in mein Programm kopieren, wovon ich nichts verstehe, ist nicht meine Lösung.
    @-Franky-

    Ja cool. Werd ich mir mal genauer ansehen...

    @Elephant
    Also ich weiss noch, als mein Vater vor ca. nem halben Jahr mein Projekt getestet hat (was grob gesagt ein MP3 Player ist) und er sich deshalb ne CD von sich eingelesen hat mit dem Windows Media Player, er Titelinfos angezeigt bekommen hat... Vielleicht liegts echt an der CD, dass da tatsächlich keine Infos vorhanden sind??

    Ich halte dich auf dem Laufenden bezüglich des CSAudioCDBurner, mal gespannt ob die zurück schreiben...
    Hi

    Hab mal überlegt was so mit dem WMP geht. Herausgekommen ist folgendes. AxWmp ist das WMP-Control auf der Form. Button1 listet nur die verfügbaren Brenner? auf. Button2 ist eher Pseudocode weil ich den WMP nicht nutze und daher dort auch keine Playlisten habe. Hinzukommt das ich schon seit Ewigkeiten keine CD-Rohlinge mehr habe und daher nicht testen kann. Den Rest müsst ihr Euch zusammen suchen. Ist ja alles unter docs.microsoft.com/en-us/windows/win32/wmp/burning-a-cd beschrieben.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports WMPLib
    4. Imports System.Runtime.InteropServices
    5. Public Class Form1
    6. Private Const S_OK As Integer = 0
    7. Private Const IID_IWMPCdromBurn As String = "bd94dbeb-417f-4928-aa06-087d56ed9b59"
    8. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    9. Dim WMPCdromCollection As IWMPCdromCollection = AxWmp.cdromCollection
    10. If WMPCdromCollection IsNot Nothing Then
    11. Dim intWMPCdromCollectionCount As Integer = WMPCdromCollection.count
    12. If intWMPCdromCollectionCount > 0 Then
    13. For intWMPCdromCollectionItem = 0 To intWMPCdromCollectionCount - 1
    14. Dim WMPCdrom As IWMPCdrom = WMPCdromCollection.Item(intWMPCdromCollectionItem)
    15. If WMPCdrom IsNot Nothing Then
    16. Debug.Print(WMPCdrom.driveSpecifier)
    17. Marshal.ReleaseComObject(WMPCdrom)
    18. End If
    19. Next
    20. End If
    21. Marshal.ReleaseComObject(WMPCdromCollection)
    22. End If
    23. End Sub
    24. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    25. Dim WMPCdromCollection As IWMPCdromCollection = AxWmp.cdromCollection
    26. If WMPCdromCollection IsNot Nothing Then
    27. ' Laufwerksbuchstaben vom Brenner der verwendet werden soll!
    28. ' Siehe Button1 zum ermitteln der Laufwerksbuchstaben aller verbauten Brenner.
    29. ' Kann ja sein das mehrere Brenner verbaut sind.
    30. Dim WMPCdrom As IWMPCdrom = WMPCdromCollection.getByDriveSpecifier("E:")
    31. If WMPCdrom IsNot Nothing Then
    32. Dim pIWMPCdromBurn As IntPtr = IntPtr.Zero
    33. ' IWMPCdrom.QueryInterface -> IWMPCdromBurn
    34. ' https://docs.microsoft.com/en-us/windows/win32/wmp/retrieving-the-cd-burning-interface
    35. If Marshal.QueryInterface(Marshal.GetIUnknownForObject(WMPCdrom),
    36. New Guid(IID_IWMPCdromBurn), pIWMPCdromBurn) = S_OK Then
    37. Dim WMPCdromBurn As IWMPCdromBurn = DirectCast(Marshal.GetObjectForIUnknown(pIWMPCdromBurn), IWMPCdromBurn)
    38. If WMPCdromBurn IsNot Nothing Then
    39. Dim WMPPlaylistCollection As IWMPPlaylistCollection = AxWmp.playlistCollection
    40. If WMPPlaylistCollection IsNot Nothing Then
    41. ' nur als Beispiel evtl. neue Playlist erstellen
    42. Dim WMPPlaylist As IWMPPlaylist = WMPPlaylistCollection.newPlaylist("New Playlist")
    43. ' eine vorhandene Playlist verwenden
    44. 'Dim WMPPlaylistArray As IWMPPlaylistArray = WMPPlaylistCollection.getAll()
    45. 'Dim WMPPlaylistArray As IWMPPlaylistArray = WMPPlaylistCollection.getByName("Name")
    46. 'WMPPlaylistArray.count -> WMPPlaylistArray.Item(Index) -> IWMPPlaylist
    47. If WMPPlaylist IsNot Nothing Then
    48. ' hinzufügen neuer Elemente zur Playlist
    49. 'WMPPlaylist.appendItem
    50. 'WMPPlaylist.insertItem
    51. ' Playlist zuweisen -> IWMPCdromBurn
    52. ' https://docs.microsoft.com/en-us/windows/win32/wmp/starting-the-burn-process
    53. WMPCdromBurn.burnPlaylist = WMPPlaylist
    54. ' und das brenne starten
    55. 'WMPCdromBurn.startBurn()
    56. Marshal.ReleaseComObject(WMPPlaylist)
    57. End If
    58. Marshal.ReleaseComObject(WMPPlaylistCollection)
    59. End If
    60. Marshal.ReleaseComObject(WMPCdromBurn)
    61. End If
    62. Marshal.Release(pIWMPCdromBurn)
    63. End If
    64. Marshal.ReleaseComObject(WMPCdrom)
    65. End If
    66. Marshal.ReleaseComObject(WMPCdromCollection)
    67. End If
    68. End Sub
    69. End Class

    Mfg -Franky-

    Also dein Code scheint zu funktionieren. Bloss der tatsächliche Brennvorgang startet nicht (WMPCdromBurn.startBurn()). Fehlermeldung:

    System.AccessViolationException
    HResult=0x80004003
    Nachricht = Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist.
    Quelle = <Die Ausnahmequelle kann nicht ausgewertet werden.>
    Stapelüberwachung:
    <Die Ausnahmestapelüberwachung kann nicht ausgewertet werden.>

    Ich hab mal überprüft ob mein Laufwerk brennen kann und ob die eingelegte CD brennfähig ist, beides mal kam True zurück:

    VB.NET-Quellcode

    1. MessageBox.Show(CStr(WMPCdromBurn.isAvailable("Burn")))
    2. MessageBox.Show(CStr(WMPCdromBurn.isAvailable("Write")))

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kafffee“ ()

    Hi

    kafffee schrieb:

    Also dein Code scheint zu funktionieren. Bloss der tatsächliche Brennvorgang startet nicht

    Ich kann es nicht testen, hab keine CD-Rohlinge mehr. Was ich hier im Code ja nicht komplett zu stehen hatte, war eine Playlist zu erstellen/auszuwählen. Also entweder eine neue Playlist anlegen und dieser Elemente hinzufügen (den Teil hab ich ja nur angedeutet WMPPlaylist.appendItem/insertItem) oder eine vorhandene Playlist aus der IWMPPlaylistArray zu nehmen (auch nur angedeutet). Das ganze Marshal.ReleaseXXX sollte auch erst erfolgen wenn das brennen abgeschlossen ist. Pseudocode halt. Mal kurz gegoogelt: evtl musst Du noch des Format für IWMPCdromBurn festlegen. IWMPCdromBurn.burnFormat = <- docs.microsoft.com/en-us/previous-versions/aa393450(v=vs.85)

    Edit: Der Link funktioniert irgendwie nicht. Egal. Es ist ein Wert aus der Enum WMPBurnFormat. magnumdb.com/search?q=parent:WMPBurnFormat -> wmpbfAudioCD
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Hab das mit der Playlist so gemacht:

    VB.NET-Quellcode

    1. AxWmp.URL = "C:\...\01 Amy MacDonald - A Curious Thing - Don't Tell Me That It's Over.wav"
    2. WMPPlaylist.appendItem(AxWmp.currentMedia)
    3. AxWmp.URL = "C:\...\01 Amy MacDonald - This Is The Life - Mr. Rock 'n' Roll.mp3"
    4. WMPPlaylist.appendItem(AxWmp.currentMedia)


    und dann so:

    VB.NET-Quellcode

    1. WMPCdromBurn.burnPlaylist = WMPPlaylist
    2. WMPCdromBurn.burnFormat = WMPBurnFormat.wmpbfAudioCD


    Kommt aber immer noch der gleiche Fehler. Vielleicht als Administrator ausführen?

    Ansonsten google ich mal weiter...
    @kafffee
    Hab mir mal einen CD-Rohling organisiert und den ganzen Code, nach etwas Recherche, etwas umgebaut. Hoffe es ist alles im Upload vorhanden (hab alles aus dem Bin- und Obj-Ordner gelöscht, auch die Interop-DLLs ). Wie auch immer. Hab mir im WMP eine Playlist erstellt und konnte diese jetzt auch brennen. Was jetzt noch fehlt sind die ganzen Events, Status, sonstige Infos usw.
    Dateien
    • WmpBurn.zip

      (14,79 kB, 90 mal heruntergeladen, zuletzt: )
    Mfg -Franky-
    IHey ich hab mal weiter programmiert:

    Jetzt kann man eine neue Playlist zufügen, da muss man halt noch dann evtl. nen Dateiauswahldialog reinmachen, das hab ich jetzt erstmal weggelassen, darum gehts ja auch nicht... Leider habe ich (noch) keine Möglichkeit gefunden, die temporäre Playlist dann wieder zu entfernen...

    Der Brennfortschritt wird angezeigt in einer ProgressBar und in einem Label wird der aktuelle Brennstatus ausgegeben.

    Leider bleibt diese Fortschrittsanzeige immer bei 99% oder so hängen, das finde ich bisschen komisch... kannst dir ja mal anschauen...

    Option Strict Off hab ich mal "abgeschaltet", da ich beim Abfragen des Brennstatus (in der Select Case-Anweisung) mit dem Datentyp nicht klar gekommen bin. Vielleicht weisst du wie man das macht?

    Ausserdem hab ich noch eine ComboBox eingebaut, mit der man wählen kann, ob eine Audio- oder eine Daten-CD gebrannt werden soll.

    Ich lade es gerne mal hoch. Aber du musst mir sagen wie man die \bin-Ordner leert. Verkraftet das Visual Studio wenn man da einfach manuell mit dem Windows-Datei-Explorer alle Dateien rauslöscht?

    Was wir auch noch machen könnten ist eine Überprüfung, ob die Daten denn überhaupt alle auf die CD passen werden...

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „kafffee“ ()

    Hi

    Da ich den einen CD-Rohling, den ich hatte, ja nun schon verwendet habe, kann ich hier nicht mehr weiter testen. Daher vllt nur ein paar Ideen dazu.

    kafffee schrieb:

    Leider habe ich (noch) keine Möglichkeit gefunden, die temporäre Playlist dann wieder zu entfernen...

    Müsste über IWMPPlaylistCollection::remove(IWMPPlaylist) gehen.

    kafffee schrieb:

    Leider bleibt diese Fortschrittsanzeige immer bei 99% oder so hängen, das finde ich bisschen komisch...

    Glaub man muss den burnProgress im Zusammenhang mit dem burnState sehen. Denke die 99% beziehen sich nur auf das brennen der Playlist. Nicht auf das Prepare und Finalize der CD. 100% müssten daher sein wenn der State = wmpbsStopped, nach State = wmpbsBurning, ist.

    kafffee schrieb:

    mit dem Datentyp nicht klar gekommen bin. Vielleicht weisst du wie man das macht?

    Vllt so?

    VB.NET-Quellcode

    1. Select Case m_WMPCdromBurn.burnState
    2. Case WMPBurnState.wmpbsUnknown
    3. ' usw
    4. End Select

    kafffee schrieb:

    Ich lade es gerne mal hoch. Aber du musst mir sagen wie man die \bin-Ordner leert.

    Ich mache immer eine Kopie des kompletten Projekt-Ordner und lösche dann alles aus dem Bin- und Obj-Ordner um das dann hier hochzuladen.

    kafffee schrieb:

    Was wir auch noch machen könnten ist eine Überprüfung, ob die Daten denn überhaupt alle auf die CD passen werden...

    Keine Ahnung ob die WMP-Interfaces dazu was direkt anbieten. Evtl. die IWMPCdromBurn::getItemInfo(AvailableTime) im Zusammenhang mit IWMPMedia::get_duration verwenden. Letztere darf von allen IWMPMedia in der Summe ja nicht größer sein als die AvailableTime (+ evtl 2 Sekunden Pause zwischen den einzelnen Songs). Vllt gibt es auch eine Möglichkeit die Größe der RAW-PCM Daten der einzelnen IWMPMedia zu ermitteln. Die darf ja auch nicht größer sein als die IWMPCdromBurn::getItemInfo(Free/TotalSpace).
    Mfg -Franky-
    @Elephant
    Vielen Dank für das Angebot. Denke aber das @kafffee ab hier allein weiter kommt. Das brennen ansich funktioniert ja jetzt per WMP. Es sind ja nur noch ein paar Feinheiten reinzuprogrammieren. Für mich sind die WMP-Interfaces nichts.
    Mfg -Franky-
    @Elephant

    So, ich hatte zwar gesagt das dauert bei mir einige Wochen da sind dann aber doch einige Monate daraus geworden, bis ich mich im Detail nochmal um dein Anliegen kümmern kann. Ich bin gerade dabei ein Benutzersteuerlement (DLL) zu entwickeln, das du dann in deiner Applikation bequem verwenden kannst, wenn du willst.

    Wie auch immer, habe ich noch folgende Probleme, und da kommt @-Franky- wieder ins Spiel:

    (1) Zu Prüfen, wie gross der verfügbare Speicher auf dem Rohling ist (Habs mit System.IO.DriveInfo versucht, aber wie erwartet ohne Erfolg). Ich hab deine Links zum Thema IMAPI(2) mal überflogen, aber noch nichts entsprechendes gefunden. ich recherchiere aber weiterhin...
    (2) Das Löschen der temporären Playlist, die zum Brennen verwendet wird.

    Wenn ich das wie folgt mache:

    VB.NET-Quellcode

    1. Private m_WMPPlaylistCollection As IWMPPlaylistCollection
    2. Private TemporärePlaylist As WMPLib.IWMPPlaylist
    3. ...
    4. TemporärePlaylist = AxWmp.playlistCollection.newPlaylist("tempPL") 'Erstellen der Playlist
    5. ...
    6. m_WMPPlaylistCollection.remove(TemporärePlaylist) 'Löschen der Playlist


    Kommt der Fehler: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

    Wenn ich es so mache:

    VB.NET-Quellcode

    1. m_WMPPlaylistCollection.remove(CType(AxWmp.playlistCollection.getByName("tempPL"), IWMPPlaylist))


    kommt:
    Das COM-Objekt des Typs "System.__ComObject" kann nicht in den Schnittstellentyp "WMPLib.IWMPPlaylist" umgewandelt werden. Dieser Vorgang konnte nicht durchgeführt werden, da der QueryInterface-Aufruf an die COM-Komponente für die Schnittstelle mit der IID "{D5F0F4F1-130C-11D3-B14E-00C04F79FAA6}" aufgrund des folgenden Fehlers nicht durchgeführt werden konnte: Schnittstelle nicht unterstützt (Ausnahme von HRESULT: 0x80004002 (E_NOINTERFACE))

    Ich hoffe du kannst mir da bisschen unter die Arme greifen...
    _____________________________


    Übrigens:

    Elephant schrieb:

    Ja es gab so eine DB, aber beim Suchen zu Infos darüber habe ich gelesen, dass der Betrieb eingestellt worden ist.


    Mit der bass.dll bzw. den entsprechenden Add-Ons gibt es noch die Möglichkeit der Abfrage von Titelinformationen einer eingelegten Audio-CD über eine kostenlose Online Datenbank... Hab das erst neulich bei mir implementiert und es funzt :) :)

    un4seen.com/forum/?topic=19647.msg137473;topicseen#msg137473

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „kafffee“ ()

    Ich hab jetzt rausgefunden, wie ich meine temporäre Playlist wieder lösche:

    VB.NET-Quellcode

    1. Dim GefundenePlaylists As IWMPPlaylistArray = AxWmp.playlistCollection.getByName("TemporaryPlaylist")
    2. If GefundenePlaylists.count > 0 Then
    3. Dim ZuLoeschendePlaylist As IWMPPlaylist = GefundenePlaylists.Item(0)
    4. AxWmp.playlistCollection.remove(ZuLoeschendePlaylist)
    5. End If


    Die Sache mit den Events:
    Hab ich zum grössten Teil auch hinbekommen... mehr dazu später...

    Zum Thema freien Speicherplatz auf der CD ermitteln:

    -Franky- hat mir ein Beispielprojekt hochgeladen, in dem man mit Hilfe der IMAPI2 die freien Sektoren auf einem Rohling ermitteln kann. Wen es interessiert kann in diesem Thread nachlesen:

    Hosten eines Windows Media Player-Controls in einer MVVM Application

    @-Franky-

    Bin gestern noch mal zwei Stunden da rangesessen und nicht so ganz auf den grünen Zweig gekommen. Ich bin versucht dein Projekt wie es ist ist eine DLL umzuwandeln und die "Ergebnisse" statt in eine Textbox schreiben einfach in Klasseneigenschaften zu speichern... Weisst du zufällig ob man das machen kann, einfach den (veränderten) Code in eine Sub Main() zu verfrachten und danach einfach die Form löschen?
    @kafffee
    Die Form ansich brauchst Du gar nicht. Erstelle eine ganz normale Klasse mit den benötigten Interfaces, Funktionen usw. und erstelle entsprechende Properties oder weitere Funktionen in der Klasse die Dir die benötigten Infos liefern. Naja und dann die Klasse halt verwenden wie jede andere Klasse auch. Da könnte man schon in der Klasse -> Sub New die vorhandenen CD-Brenner ermitteln (Name, Laufwerksbuchstabe, UniqueID und was man sonst noch so braucht). Ich würde da keine extra DLL drauß machen. Man kann ja alle Interfaces usw. was man benötigt in eine Klasse packen anstatt jedes Interface in eine extra Klasse. Der Code müsste dann aber ein wenig dafür umgebaut werden.
    Mfg -Franky-
    Ob ich jetzt eine Klasse mache oder eine DLL sei jetzt mal Nebensache.

    Ich frage mich bloss ob man einfach so eine Form aus dem Projekt entfernen kann so ohne Nebenwirkungen... Dann könnte ich mir das viele Kopieren und Einfügen in ein neues Projekt sparen...

    Edit: Was müsste ich denn alles umbauen wenn ich alle Interfaces in eine Klasse packen will?

    kafffee schrieb:

    ch frage mich bloss ob man einfach so eine Form aus dem Projekt entfernen kann so ohne Nebenwirkungen...

    Klar kannst Du die Form entfernen. In der sind ja nur Sachen enthalten um die Interfaces anzusprechen und die Ergebnisse anzuzeigen.

    kafffee schrieb:

    Was müsste ich denn alles umbauen wenn ich alle Interfaces in eine Klasse packen will?

    Ich hatte doch seiner Zeit zwei Test-Projekte in der ZIP. Einmal das IMAPI2 Projekt und das IMAPI Projekt. Das IMAPI Projekt ist im Prinzip das gleiche wie das IMAPI2 Projekt nur mit dem Unterschied, das alle Interfaces in einem Modul stecken. Im Prinzip erstellst nun eine Klasse und kopierst alles, was Du an Interfaces, Const, Enums usw. benötigst, aus dem Modul in diese Klasse und baust die entsprechenden Prozeduren (Auflisten der CD_ROM Laufwerke, Auslesen der Eigenschaften der CD-ROM Laufwerke bzw des eingelegten Mediums) aus der Form/Modul ebenfalls in die Klasse. Alles was mit dem DDiscMaster2Events zusammenhängt brauchst ja nicht. Es sei denn Du möchtest auch die Events wenn ein CD-ROM Laufwerk hinzugefügt oder entfernt wurde (portables CD-ROM Laufwerk). Letzteres hab ich aber nie austesten können ob das so auch in .NET funktioniert da ich kein portablen Brenner habe. So ähnlich hab ich die anderen IMAPI2 Event-Interfaces in VB6 implementiert um zb den Brennfortschritt auslesen zu können. Für Audio-CDs wäre das das Interface DDiscFormat2TrackAtOnceEvents.Update -> IDiscFormat2TrackAtOnceEventArgs. Setzt aber auch voraus das das brennen komplett über IMAPI2 abläuft damit man diese Event-Interfaces auch nutzen kann.

    An dieser Stelle wäre es vllt. doch eine Überlegung wert anstatt die Interfaces komplett in einer Klasse einzubauen, ob man nicht doch lieber nur mit den Pointern der Interfaces, entsprechenden Delegates für die benötigten Funktionen eines Interfaces und den Funktionsnummern (VTable) bzw mit dem Pointer auf die benötigte Interface-Funktion arbeitet da Du ja nur ein paar wenige Funktionen aus verschiedenen Interfaces benötigst. Ich hab da diverse Projekte im Unterforum "Sourcecode-Austausch" wo ich genau diesen Weg gehe. zB beim Projekt "Audio- oder Videodatei zu MP3 per Media Foundation konvertieren" oder auch im Projekt "einfache 2D Objekte per Direct2D, ohne Verweis oder NuGet-Pakete, zeichnen".
    Mfg -Franky-
    @kafffee Ich hab da mal was fix zusammen gebaut. Allerdings ist da noch nicht alles enthalten was Du evtl. benötigst. Es soll Dir nur zeigen wie man das ganze in eine Klasse unterbringt und ausschließlich mit den Pointern der Interfaces und nur mit den benötigten Interface-Funktionen arbeitet. Denke das erklärt sich von selbst wie das ganze dann zu erweitern ist.
    Dateien
    • VBN_IMAPI2.zip

      (15,65 kB, 79 mal heruntergeladen, zuletzt: )
    Mfg -Franky-