Im ersten Teil haben wir besprochen, wie man die MP3Info einer MP3 ausliest. Allerdings funktioniert dies nur mit der ID3 Version 1. Hier stellt das MP3Info die letzten 255 Zeichen dar. In der ID3v2 ist es jetzt gänzlich anders. Das Info hat keine feste Länge und kann bis zu 255 MB gross sein! Ausserdem befinden sich die Info-Tags irgendwo im Info und nicht an einer bestimmten Stelle! Das MP3Info beginnnt hier am Anfang der MP3 gleich nach dem Header. Es ist auch möglich, dass die Tags der 2 verschiendenen Versionen nebeneinandern existieren! Das verursacht keine Probleme. Nun gut, aber, Wie komme ich also in der ID3v2 an das MP3Info ran?
Was ist der Header der ID3v2?
In der ID3v2 beginnt jedes MP3-File mit den Tags "ID3". Das ist der sogenannte ID-TAG. Danach folgen 2 Bytes, die die Versionnummer darstellen. Dann kommt noch ein Byte für Flags und 4 Byte für die Grösse der Info.
In VB6 könnte die Struktur also wie folgt aussehen!
Public Type MP3Head ID3 As String * 3 MajorVersion As Byte RevisionNumber As Byte Flags As Byte Size As Long ' 4 Byte Sync-Integer!!! End Type |
Die Grösse ist ein 4 Byte Sync-Integer! oder sprichwörtlich ein 7 Bit-Integer. Er verwendet nur 7 Bits, um seine Wertigkeit auszudrücken.
Hier gibts Detailierte Infos...
http://www.id3.org/id3v2.4.0-structure.txt Die Tags haben bestimmte Namen!
Zu mindest die am meist benötigten. Die MP3Info lässt sich nähmlich beliebig erweitern.
Hier habe ich einige Konstanten definiert, die die Namen der bekanntesten Tags beiinhalten.
Public Const TAG_IDTAGv2 As String = "ID3" ' Einleitende Tag für MP3 mit ID3v2 Public Const TAGTITLE As String = "TIT2" Public Const TAGALBUM As String = "TALB" Public Const TAGKUENSTLER As String = "TPE1" Public Const TAGKOMMENTAR As String = "TCON" Public Const TAGJAHR As String = "TYER" |
Am besten Sie laden sich für binäre Daten irgendeinen Hexeditor runter. Und schauen sich das MP3-File mal darin an.
Das ist die ersten Bytes eines MP3 mit ID3v2.Die Tags stehen also wild irgendwo im Info!Allerdings haben die Tags selbst auch eine gewisste Struktur.
Public Type MP3TAG TAG As String * 4 ' Die Tagdefinition ist 4 Byte lang Size As Long ' Die Grösse des Wertes ist ein Long, 4 Bytes Flags As String * 3' Flags, 3 Bytes End Type |
und danach kommt dann endlich der Wert, den wir haben wollen. z.B. Album-Name, Titel-Name usw.
Sample: ID3v2 auslesen mit VB6
hier nur die wichtigsten Code-Schnibbels, der komplette Source-Code ist im Download enthalten.
Private m_byteMP3Info(512) As Byte .... public sub .... Open sFileName For Binary Access Read As #iFile Get #iFile, , tMP3Head ' wenn es eine ID3 der Version 1 ist, dann If tMP3Head.ID3 <> TAG_IDTAGv2 Then ' Code für ID3v1 hier... Else Get #iFile, , m_byteMP3Info ' die ersten 512 Bytes in das ByteArray einlesen. m_sAlbum = GetValueFromTag(TAGALBUM) m_sKuenstler = GetValueFromTag(TAGKUENSTLER) m_sTitel = GetValueFromTag(TAGTITLE) m_sKommentar = GetValueFromTag(TAGKOMMENTAR) m_sJahr = GetValueFromTag(TAGJAHR) End If Close #iFile End Sub |
- Jetzt haben wir die ID3v2 im modulglobalen ByteArray zwischengespeichert.
- GetValueFromTag(TAGALBUM) = ruft die Funktion auf und übergibt den Tag-Namen der ausgelesen werden soll. Die Funktion liefert als Rückgabewert den Wert eines MP3Info-Tags.
Hier die eigentliche Funktion, die die Tag-Value´s filtert.
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Function GetValueFromTag(ByVal sTag As String) As String Dim tMP3TAG As MP3TAG Dim lTagBegin As Long ' Tag-Position ermitteln lTagBegin = InStrB(1, m_byteMP3Info, StrConv(sTag, vbFromUnicode)) If lTagBegin <> 0 Then With tMP3TAG '.TAG = StrConv(MidB(m_byteMP3Info, lTagBegin, 4), vbUnicode) ' Orginal-Tag-ID auslesen On Error GoTo Fehler ' Tag-Value grösse mit CopyMemory in VB-Long kopieren CopyMemory ByVal VarPtr(.Size), ByVal VarPtr(m_byteMP3Info(lTagBegin + 6)), 4 ' Tag-Value auslesen und in BSTR konvertieren GetValueFromTag = StrConv(MidB(m_byteMP3Info, lTagBegin + 11, .Size - 1), vbUnicode) End With Else GetValueFromTag = "" End If Exit Function Fehler: If Err.Number = 9 Then ' Überlauf, wenn byteArray zu klein ist. '--- End If Err.Clear End Function |
StrConv = konvertiert den entsprechenden String in einen Unicode-String oder umgekehrt. Da die Info-Tags als VB-String-Konstanten deklariert sind, müssen diese in Unicode konvertiert werden.
VarPtr = liefert einen Long der einen Pointer auf eine Variable darstellt
CopyMemory = kopiert Speicherbereiche z.B.
00 00 00 0f
wenn man diesen Speicherbereich in einen Long kopiert, hat der Long den Wert 16.
Dieses MP3-Sample zeigt sich mit einer sehr guten Geschwindigkeit. 300 MP3´s in 1 Sekunde.
Warum funktioniert das so schnell?
Dafür gibt es mehrere Gründe.
Die Tags werden nicht Stück für Stück gesucht oder ausgelesen, sondern auf es werden auf 1-mal 512 Bytes ausgelesen, und die Tags mit dem "instrb"-Command gefunden.
Schleifen, Vergleiche brauchen viel Zeit und sind möglichst gering gehalten.
Es finden keine Stringverkettungen statt. Diese nehmen viel CPU-Power in Anspruch und sind allgemein inperformant.