Not macht bekanntlich erfinderisch: Am Anfang stand der Wunsch nach einem kleinen Hilfsprogramm, welches meine zahlreichen WMA-Dateien für die Verwendung mit einem digitalen Mini-Player aufbereiten sollte. Das Lastenheft war schnell erstellt: Suche nach Codebeispielen für die genannten Aufgaben erwies sich jedoch als frustrierend: Seitenlange C++-Listings und kein Wort über die Verwendung der entsprechenden Bibliotheken unter .NET. Was tun?
Konzert der SDKs
Nach einiger Recherchezeit bei guter Musik stellte sich heraus, dass die Arbeit mit Mediendateien durchaus auch unter .NET möglich ist. Unterschiedliche Aufgaben werden dabei von verschiedenen SDKs abgedeckt, die jeweils mit ausführlicher Dokumentation frei verfügbar sind (Kasten SDK-Downloads und Dokumentation):- Abspielen von Dateien: Das Windows Media Player 10 SDK bietet eine Schnittstelle zum Windows Media Player 10. Hiermit lassen sich sehr einfach beliebige Medienfiles in eigenen Anwendungen abspielen.
- Lesen und Editieren von spezifischen Dateiattributen: Das Windows Media Format 9.5 SDK erlaubt unter anderem den Zugriff auf Dateien im ASF-Format, zu denen auch WMA als Subformat gehört. Mit dem SDK lassen sich die in den einzelnen Dateien eingebetteten Metadaten, wie etwa Songtitel, Albumtitel, Interpret, Songnummer oder Genre auslesen und bearbeiten.
- Kodieren und Umkodieren von WMA-Dateien: Das Windows Media Encoder 9 Series SDK bietet Funktionalität zum Umwandeln fast beliebiger Audiofiles in das WMA-Format sowie zur Umwandlung verschiedener WMA-Kodierungsarten untereinander. So lassen sich beispielsweise WMA-Dateien, die mit einer hohen Bitrate kodiert werden, in solche mit einer niedrigeren Bitrate konvertieren (Downsampling).
|
Übrigens überschneidet sich der Funktionsumfang der verschiedenen SDKs teilweise erheblich. So ist es möglich, auch mit dem Media Format SDK Mediendateien zu kodieren, und das Media Player SDK kann ebenfalls Attribute setzen und lesen - zu den Gründen dafür später mehr. Mir war es für diesen Artikel in erster Linie wichtig, einen Überblick der verfügbaren SDKs zu liefern.Gerüstet mit den richtigen Bibliotheken stand einer Implementierung meines kleinen Tools nichts mehr im Wege. Das Ergebnis möchte ich Ihnen im Folgenden vorstellen. Die fertige Applikation samt Quellcode finden Sie wie immer auf der Heft-CD.
Konvertieren statt resignieren
Die Arbeit mit der WMAToolbox gestaltet sich denkbar einfach: Zunächst kann der Benutzer ein Verzeichnis wählen, welches beliebige WMA-Dateien enthält. Das Programm zeigt die Attribute dieser Musikstücke übersichtlich in einer Liste an. Über einen einfachen Mini-Player mit Play/Pause-Knöpfen und einer Spielzeitanzeige lassen sich einzelne Titel probehören.
|
Let the Music Play!
Wie realisiert die WMA Toolbox die einzelnen Programmfeatures? Die einfachste Aufgabe ist die Implementierung des integrierten Mini-WMA-Players. Das Abspielen von Musikdateien und die Steuerung der damit verbunden Elemente des Benutzer-Interfaces übernimmt ein echter Abspiel-Profi - der Windows Media Player 10. Dessen SDK stellt ein leistungsstarkes ActiveX-Control bereit, welches problemlos auch in .NET-Programme eingebunden werden kann. Dabei hat der Programmierer die Wahl, ob das Control eine vollständige Oberfläche anzeigen, sich auf wenige wichtige Bedienelemente beschränken oder sich komplett verstecken soll. Hierzu reicht es aus, die Eigenschaft uiMode entsprechend zu setzen. Im vorliegenden Fall soll die Steuerung über eigene Play- und Stop-Schaltflächen der Hostapplikation geschehen, und das Windows Media Player Control soll kein eigenes Benutzer-Interface anzeigen - uiMode bekommt folglich den Wert invisible.Der Windows Media Player bietet einen riesigen Funktionsumfang, von dem die WMAToolbox jedoch nur einen Bruchteil nutzt. Zunächst wird die abzuspielende Datei festgelegt, indem ein neues Medienobjekt erzeugt und mit dem Namen der WMA-Datei initialisiert wird:Dim CurrentMedia As WMPLib.IWMPMediaCurrentMedia = _PreviewMediaPlayer.newMedia( _"file://" & WMADateiname)PreviewMediaPlayer.currentMedia = CurrentMedia
If (PreviewMediaPlayer.playState = WMPPlayState.wmppsPlaying) ThenPreviewMediaPlayer.Ctlcontrols.pause()ElsePreviewMediaPlayer.Ctlcontrols.play()End If
Listing 1
Private Sub Player_PlayStateChange( _, ByVal e As AxWMPLib._WMPOCXEvents_PlayStateChangeEvent) _Handles PreviewMediaPlayer.PlayStateChangeDim NewPlayerState As WMPPlayState = e.newStateSelect Case NewPlayerStateCase WMPPlayState.wmppsPlayingcmdPlayPause.Text = "Pause"lblPlayTime.Visible = TruecmdPlayPause.Enabled = FalsecmdStop.Enabled = TrueCase WMPPlayState.wmppsStoppedcmdPlayPause.Text = "Play"lblPlayTime.Visible = FalsecmdPlayPause.Enabled = TruecmdStop.Enabled = False
Private Sub PlayTimer_Tick(, ByVal e As System.EventArgs) _Handles PlayTimer.TicklblPlayTime.Text = PreviewMediaPlayer.Ctlcontrols.currentPositionStringEnd Sub
Gut informiert
Die zweite Aufgabe bei der Implementierung der WMAToolbox heißt: Informationen über die zu konvertierenden WMA-Dateien einholen. WMA-Dateien enthalten eine Vielzahl von Metainformationen über ihren musikalischen Inhalt, von offensichtlichen Daten wie Interpret und Titel über etwas ausgefallenere Angaben wie Erscheinungsjahr oder Genre. WMAToolbox liest diese Informationen aus, stellt sie übersichtlich dar und verwendet sie zur Erstellung von sprechenden Dateinamen. Leider ist dies mit etwas Arbeit verbunden, denn der von mir gewählte Weg zu den gewünschten Daten führt über eine weitere, etwas sperrige Bibliothek - das Windows Media Format SDK (WMFSDK).Die Arbeit mit diesem Low-level-SDK ist alles andere als intuitiv. Die Bibliothek ist primär für die Verwendung in C++ gedacht und wird über eine mitgelieferte Wrapper-Bibliothek aus .NET angesprochen. Trotzdem lohnt sich die Beschäftigung damit, denn das Windows Media Format SDK ist die Allzweckwaffe für praktisch alle Arbeiten mit Mediendaten unter Windows. Auch die beiden anderen hier erwähnten SDKs beruhen intern auf dem WMFSDK, was erklärt, warum sich die Funktionalitäten der einzelnen Bibliotheken überschneiden. Deshalb lohnt es sich auch, für die WMAToolbox den harten Weg zu den Metadaten zu wählen - aus pädagogischen Gründen, sozusagen.
|
Beispiele für die Verwendung des WMFSDK in .NET sind rar. Doch wer sucht, der findet: Duncan Mackenzie zeigt in seinem Artikel msdn-Artikel Playing with Music Files wie das Ganze funktioniert [1]: Zunächst wird ein so genanntes Metadata-Editor-Objekt über die Funktion WMCreateEditor erzeugt. Dieses Objekt implementiert das Interface IWMHeaderInfo, über das schließlich der Zugriff auf die entsprechenden Attribute der Musikdatei möglich ist. Im folgenden Beispiel wird die Information über die Bitrate einer WMA-Datei ausgelesen (Listing 2).
Listing 2
uHR = WMFSDKFunctions.WMCreateEditor(Editor)hr = Convert.ToInt32(uHR)If hr = 0 ThenuHR = Editor.Open(FileName)hr = Convert.ToInt32(uHR)If hr = 0 ThenHeaderInfo = DirectCast(Editor, IWMHeaderInfo3)Dim value As Byte()Dim pType As WMT_ATTR_DATATYPEvalue = GetAttributeByName(HeaderInfo, "bitrate", pType)
Dim CurrentWMAFileInfo As WMAFileInfoCurrentWMAFileInfo = WMAEncoder.GetAttributes(CurrentFile)Dim Interpret As String = CurrentWMAFileInfo.Author
Eine Frage des Formats
Die letzte Aufgabe bei der Implementierung der WMAToolbox ist das Umkodieren (Resampling) von WMA-Dateien - und dies bedeutet die Beschäftigung mit einem dritten SDK. Als mittlerweile versierte Experten in der Welt der Windows-Audio-Dateien sind wir aber gut gerüstet ...Für alle Aufgaben, die mit Sampling und Resampling zu tun haben, ist das Windows Media Encoder SDK das Mittel der Wahl. Dieses SDK implementiert eine Pipeline zur Erzeugung von kodierten Medieninformationen. Dabei werden verschiedene Eingabekanäle (Audio, Video und sogar Untertitelinformationen) zu einer Gruppe zusammengefasst, die durch ein SourceGroup-Objekt repräsentiert wird. Ein Encoder-Objekt nimmt die verschiedenen Eingabedaten entgegen, kodiert sie als Windows Media-Datenstrom und schreibt sie auf ein Ausgabemedium oder auch auf mehrere Medien. Dabei werden die verschiedenen Eingabekanäle (beispielsweise Sound und Bild bei einem Konzert) zu einem Datenstrom kombiniert. Die Ausgabe kann in eine Datei erfolgen - oder in Form von Streaming direkt über ein Netzwerk verschickt und live von allen angeschlossenen Empfängern konsumiert werden. Ein Audience-Objekt definiert die Parameter für die Kodierung und ein Profile-Objekt ermöglicht das einfache Speichern aller Konfigurationsdaten für einen bestimmten Anwendungsfall.
Die WMAToolbox hat einfache Ansprüche: Es gibt nur einen Audio-Eingabemedium, die WMA-Quelldatei. Auch das Ausgabemedium ist eine einfache WMA-Datei. Dazwischen wandelt der Encoder den Datenstrom in ein bestimmtes Format. Dabei kann der Encoder auf verschiedene Codecs (Kodier-/Dekodiermodule) zurückgreifen, welche wiederum unterschiedliche Qualitäts- und Kompressionseigenschaften haben. Die Codecs übernehmen die eigentliche Berechnung der kodierten Daten und unterstützen ihrerseits verschiedene Kodierformate mit unterschiedlichen Bit-Raten und Sampling-Frequenzen. Und so sieht der ganze Vorgang in der Praxis aus: Zunächst wird eine Instanz des Encoder-Objekts erzeugt.
'Neuen Encoder erzeugenEncoder = New WMEncoder
Listing 3
'Neue SourceGroupCollection erzeugen und eine SourceGroup hinzufügen</font>EncoderSourceGroupCollection = Encoder.SourceGroupCollectionEncoderSourceGroup = _EncoderSourceGroupCollection.Add("WMAToolboxSourceGroup")'Audio-Source zur Sourcegroup hinzufügen<font>EncoderSource = _EncoderSourceGroup.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO)
'Neues Audio-Encoding-Profile erzeugenEncoderProfile = New WMEncProfile2EncoderProfile.ProfileName = "WMAToolboxProfile"EncoderProfile.ContentType = WMENC_SOURCE_TYPE.WMENC_AUDIO
Dim EncoderAudience As IWMEncAudienceObjEncoderAudience = EncoderProfile.AddAudience(FormatBitrate)EncoderAudience.AudioCodec(0) = CodecIndexEncoderAudience.AudioFormat(0) = FormatIndex
EncoderSource.SetInput(SourceFilename)
Dim OutputFile As IWMEncFile = NothingOutputFile = Encoder.FileOutputFile.LocalFileName = DestinationFilename
Encoder.Start()
Entdecke die Möglichkeiten
Drei SDKs und viele Tricks später steht fest: Mit den richtigen SDKs ist es möglich, aus eigenen Programmen effektiv mit WMA-Audiodateien zu arbeiten. Das hier vorgestellte kleine Hilfsprogramm nützt die Möglichkeiten der verfügbaren SDKs natürlich nur im Ansatz aus. Das Ziel dieses Artikels war es, die verfügbaren Technologien in Aktion zu zeigen. Der Phantasie sind jedoch (fast) keine Grenzen gesetzt: Denkbar wären beispielsweise ein erweiterter Attribut-Editor oder eine Software mit Funktionalität für die neueste Mode in der Online-Welt: Audio-Blogs mit Postings im WMA-Format.Darüber hinaus eignen sich die vorgestellten Bibliotheken nicht nur zum Einsatz mit Audiodaten, sondern können auch für die Arbeit mit Videodaten eingesetzt werden, was aber den Rahmen dieses Artikels definitiv gesprengt hätte. Bleibt mir nur der Rat einer bekannten skandinavischen Möbelkette: Entdecke die Möglichkeiten!Uwe Baumann ist Technologieberater bei der Microsoft Deutschland GmbH und passionierter Musikfan. Er wurde unlängst in einem Elektromarkt dabei beobachtet, wie er gleichzeitig eine Platte von John Denver und eine von Metallica zur Kasse trug. Während des Musikhörens programmiert er hauptsächlich ASP.NET-Seiten in VB.NET. Er ist erreichbar unter uwebaum@microsoft.com.
Links und Literatur
[1] Duncan Mackenzie: Playing With Music Files: msdn.microsoft.com/library/default.asp?url=/library/en-us/dncodefun/html/code4fun01242003.asp


