Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0408: ID3v2-Tag aus MP3s auslesen

 von 

Beschreibung 

Da sich das ID3v1-Format für MP3-Dateien doch als sehr unflexibel erwiesen hat - es hatte eine 30 Zeichen-Beschränkung für Einträge, sowie nur sechs unterschiedliche Einträge (Titel, Künstler, Album, Jahr, Kommentar und Genre) - wurde das erweiterte ID3v2-Format eingeführt, was sich als wesentlich flexibler erwies. Dort hatte man pro Eintrag nahmezu unbegrenzt Speicherplatz, es gab wesentlich mehr Einträge und man konnte sich selbst benutzdefinierte Einträge hinzufügen. ID3v2 gibt es nun bereits in Version 4.0.

Update am 27.04.03: Kleinere Mängel wurden behoben.

Update am 14. Januar 2003 von Marc Ermshaus () und die.muh.kuh: Neben kleineren Bugfixes wurde die Funktion gekapselt.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

keine

Download:

Download des Beispielprojektes [3,74 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Projekt1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Textfeld "Text1"
' Steuerelement: Schaltfläche "Command1"
' Steuerelement: Beschriftungsfeld "Label2"
' Steuerelement: Beschriftungsfeld "Label1"

Option Explicit

Private Sub Command1_Click()
    Dim ID3Tag As ID3TagV2
    
    If GetID3TagV2(Text1.Text, ID3Tag) = True Then
        Label1.Caption = "Künstler: " & ID3Tag.Artist
        Label2.Caption = "Liedtitel: " & ID3Tag.Title
    End If
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'--------- Anfang Modul "Module1" alias Module1.bas ---------

Option Explicit

Public Type ID3TagV2
    Version As String
    TagLength As Long
    ExtendedHeader As Boolean
    PlayCounter As Long
    Track As Long
    Encoder As String
    Link As String
    Copyright As String
    OriginalArtist As String
    Composer As String
    Genre As String
    Comment As String
    Year As String
    Album As String
    Artist As String
    Title As String
    Language As String
    Length As Long
    MediaType As String
    Publisher As String
    DecodingSoftware As String
    UnknownFrames As Long
End Type

Public Function GetID3TagV2(ByVal MP3FileName As String, _
    ID3Tag As ID3TagV2) As Boolean
    
    Dim Mp3FileNumber, Mp3FileContent As String
    Dim ID3Position As Long, ID3Length As String, lngID3Length As Long
    Dim ID3Version As String, ID3V2Tag As String
    
    On Error Resume Next
    
    If Len(Dir(MP3FileName)) = 0 Then
        GetID3TagV2 = False
        Exit Function
    End If
    
    If LCase(Right(MP3FileName, 4)) <> ".mp3" Then
        GetID3TagV2 = False
        Exit Function
    End If
    
    Mp3FileNumber = FreeFile
    
    'MP3 einlesen...
    Open MP3FileName For Binary As Mp3FileNumber
    Mp3FileContent = String$(LOF(Mp3FileNumber), "!")
    Get Mp3FileNumber, , Mp3FileContent
    Close Mp3FileNumber
    
    'ID3V2-Tag suchen
    ID3Position = InStr(Mp3FileContent, "ID3")
    If ID3Position = 0 Then
        GetID3TagV2 = False
        Exit Function
    End If
    
    'Tag gefunden, weiter gehts!
    ID3Version = Mid$(Mp3FileContent, ID3Position + 3, 2)
    
    'Versionkontrolle
    If Asc(Left$(ID3Version, 1)) <> 2 And Asc(Left$(ID3Version, 1)) <> 3 And _
        Asc(Left$(ID3Version, 1)) <> 4 Then
        
        GetID3TagV2 = False
        Exit Function
    End If
    
    'Version anzeigen
    ID3Tag.Version = Str$(Asc(Left$(ID3Version, 1))) & "." & Trim$(Str$(Asc(Right$(ID3Version, 1))))
    
    'Länge bestimmen
    ID3Length = Mid$(Mp3FileContent, ID3Position + 6, 4)
    
    'lngID3Length = 256 * 8 * 8 * Asc(Left$(ID3Length, 1)) + 256 * 8 * Asc(Mid$(ID3Length, _
             2, 1)) + 256 * Asc(Mid$(ID3Length, 3, 1)) + Asc(Mid$(ID3Length, 4, 1))
    
    
    lngID3Length = &H200000 * Asc(Left$(ID3Length, 1)) + &H4000 * Asc(Mid$(ID3Length, _
        2, 1)) + &H80 * Asc(Mid$(ID3Length, 3, 1)) + Asc(Mid$(ID3Length, 4, 1))
    
    
    'Länge ausgeben
    ID3Tag.TagLength = lngID3Length
    
    ID3V2Tag = Mid$(Mp3FileContent, ID3Position, lngID3Length + 10)
    
    Mp3FileContent = ""
    
    'Nach Extended Header suchen...
    If (Asc(Mid$(ID3V2Tag, 6, 1)) And 32) = 32 Then
        ID3Tag.ExtendedHeader = True
        ID3V2Tag = Mid$(ID3V2Tag, 10)
    End If
    ID3V2Tag = Mid$(ID3V2Tag, 11)
    
    'Nun Frame für Frame abarbeiten...
    Dim FrameName As String, FrameLen As String
    Dim FrameFlags As String, Frame As String
    Dim lngFrameLen As Long
    
    ID3Tag.UnknownFrames = 0
    
    Do
        
        'ID3V2.3
        If Asc(Left$(ID3Version, 1)) = 3 Or Asc(Left$(ID3Version, 1)) = 4 Then
            
            'Frame-Header auslesen
            FrameName = Left$(ID3V2Tag, 4)
            
            'Wenn es sich um den Footer handelt, dann sind wir
            'fertig!
            If Left$(FrameName, 3) = "3DI" Then Exit Do
            FrameLen = Mid$(ID3V2Tag, 5, 4)
            lngFrameLen = 256 * 8 * 8 * Asc(Left$(FrameLen, 1)) + 256 * 8 * Asc(Mid$(FrameLen, _
                2, 1)) + 256 * Asc(Mid$(FrameLen, 3, 1)) + Asc(Mid$(FrameLen, 4, 1))
            
            
            
            FrameFlags = Mid$(ID3V2Tag, 9, 2)
            ID3V2Tag = Mid$(ID3V2Tag, 11)
            
            'Frame-Content bestimmen
            Select Case FrameName
            Case "PCNT"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.PlayCounter = Val(Mid$(ID3V2Tag, 2, lngFrameLen - 1))
                Else
                    ID3Tag.PlayCounter = Val(Left$(ID3V2Tag, lngFrameLen))
                End If
                
            Case "TRCK"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Track = Val(Mid$(ID3V2Tag, 2, lngFrameLen - 1))
                Else
                    ID3Tag.Track = Val(Left$(ID3V2Tag, lngFrameLen))
                End If
                
            Case "TENC"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Encoder = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Encoder = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "WXXX"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Link = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Link = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TCOP"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Copyright = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Copyright = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TOPE"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.OriginalArtist = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.OriginalArtist = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TCOM"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Composer = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Composer = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TCON"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Genre = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Genre = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "COMM"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Comment = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Comment = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TYER"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Year = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Year = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TALB"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Album = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Album = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TPE1"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Artist = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Artist = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TIT2"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Title = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Title = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TLAN"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Language = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Language = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TLEN"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Length = Val(Mid$(ID3V2Tag, 2, lngFrameLen - 1))
                Else
                    ID3Tag.Length = Val(Left$(ID3V2Tag, lngFrameLen))
                End If
                
            Case "TMED"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.MediaType = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.MediaType = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TPUB"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Publisher = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Publisher = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TSSE"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.DecodingSoftware = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.DecodingSoftware = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case Else
                ID3Tag.UnknownFrames = ID3Tag.UnknownFrames + 1
            End Select
            
            ID3V2Tag = Mid$(ID3V2Tag, lngFrameLen + 1)
            
            'ID3V2.2
        ElseIf Asc(Left$(ID3Version, 1)) = 2 Then
            
            'Frame-Header auslesen
            FrameName = Left$(ID3V2Tag, 3)
            
            'Wenn es sich um den Footer handelt, dann sind wir
            'fertig!
            If FrameName = "3DI" Then Exit Do
            FrameLen = Mid$(ID3V2Tag, 4, 3)
            lngFrameLen = 256 * 8 * Asc(Left$(FrameLen, 1)) + 256 * Asc(Mid$(FrameLen, 2, _
                1)) + Asc(Mid$(FrameLen, 3, 1))
            
            
            
            ID3V2Tag = Mid$(ID3V2Tag, 7)
            
            'Frame-Content bestimmen
            Select Case FrameName
            Case "TRK"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Track = Val(Mid$(ID3V2Tag, 2, lngFrameLen - 1))
                Else
                    ID3Tag.Track = Val(Left$(ID3V2Tag, lngFrameLen))
                End If
                
            Case "TEN"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Encoder = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Encoder = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TCR"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Copyright = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Copyright = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TOA"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.OriginalArtist = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.OriginalArtist = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TCM"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Composer = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Composer = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TCO"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Genre = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Genre = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "COM"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Comment = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Comment = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TYE"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Year = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Year = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TAL"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Album = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Album = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TP1"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Artist = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Artist = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TT2"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Title = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Title = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TLA"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.Language = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.Language = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TMT"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.MediaType = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.MediaType = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case "TSS"
                If Left$(ID3V2Tag, 1) = Chr$(0) Then
                    ID3Tag.DecodingSoftware = Mid$(ID3V2Tag, 2, lngFrameLen - 1)
                Else
                    ID3Tag.DecodingSoftware = Left$(ID3V2Tag, lngFrameLen)
                End If
                
            Case Else
                ID3Tag.UnknownFrames = ID3Tag.UnknownFrames + 1
            End Select
            
            ID3V2Tag = Mid$(ID3V2Tag, lngFrameLen + 1)
            
        End If
        
    Loop Until Len(ID3V2Tag) = 0
    
    GetID3TagV2 = True
End Function
'---------- Ende Modul "Module1" alias Module1.bas ----------
'-------------- Ende Projektdatei Projekt1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 23 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Ralle am 10.04.2010 um 14:38

Danke für den Hinweis! Werde mir das mal ansehen.

Kommentar von am 15.03.2010 um 13:46

hi ralle!

such mal im AVB-upload nach "MP3TagEditor.zip" - das ist eine lsg mit vba.

Kommentar von Ralle am 12.03.2010 um 11:41

Schöner Code, aber... wie kann man einen ID3TagV2 selber schreiben? Nirgendwo gibt es dafür ein Beispiel. Da es aber jede Menge Mp3Tag Editoren gibt, die das können, sollte das doch in VB auch möglich sein. Hat jemand eine Idee? Wäre sehr dankbar.

Kommentar von Felix.S am 18.09.2009 um 21:38

@Sven: (Sieht aus wie Code ;) )
Es gibt noch seeehr viele Programmierer in VB Classic

Kommentar von Sven am 25.12.2007 um 22:16

sehr hilfreicher code! Keine Ahnung wer noch mit vb6 programmiert aber in vb.net findet man solche beispiele leider nicht so häufig. Die Umwandlung hat aber geklappt.. vielen dank ;)

Kommentar von KALEL am 25.12.2006 um 14:51

Viel schneller geht es, wenn man nur den Anfang der Datei einliest.

'Einlesen der ersten vier Kilobytes um
'den Header der Datei zu finden
Open MP3FileName For Binary As #Mp3FileNumber
Mp3FileContent = Input(4096, #Mp3FileNumber)
Close #Mp3FileNumber

nicht alle Tags die im Modul beschrieben sind, sind auch im ID3Tag enthalten.
z.B. die Titellänge
diese befinden sich an anderer stelle im Header.
schaut euch dazu diesen Tip an
http://www.activevb.de/tipps/vb6tipps/tipp0487.html

Kommentar von THird am 19.11.2005 um 12:54

Nunja,man kann die MP3 öffnen und den ganzen inhalt in einen speicher legen,und den speicher dann für bestimmte anlässe bei einer bestimmten position auslesen.... zwingend notwendig ist das eigentlich nicht... wäre aber doch praktischer

MFG
Third
http://Techware.mine.nu

Kommentar von Eckard Ahlers am 19.11.2005 um 12:23

Ist das richtig, daß für das Tag-lesen das gesamte File eingelesen wird?


Mp3FileNumber = FreeFile

'MP3 einlesen...
Open MP3FileName For Binary As Mp3FileNumber
Mp3FileContent = String$(LOF(Mp3FileNumber), "!")
Get Mp3FileNumber, , Mp3FileContent
Close Mp3FileNumber

Ist das zwingend erforderlich?

Kommentar von Third am 20.07.2005 um 22:11

moin...

nach etlich langem suchen nach einem guten protokoll von id3v2.4 bin ich ausversehen auf diese seite gestoßen....,natürlich sah ich sofort diesen code,und hab ihn mir mal durchgelesen....bis mir aufgefallen war,das das Basic ist,ich wusste aber net sofort was für eine basicversion des war :) naja jedenfalls freuts mich mal einen V-basicler's arbeit zu sehen ;) ich bin PureBasicler :D:D

was mich interesieren würde,wo hast du,das was du brauchst um id3v2.4 auszulesen,gefunden? ich suche schon ewig bei wikipedia,wobei ich da schon alle recourcen auswendig kenne,und google hilft mir auch net weiter :'(

wäre dir sehr dankbar wenn du mir helfen könntest :)

MFG
Ein PureBasic Progger
Third

www.PureBasicGalaxy.de.vu

Kommentar von rock am 23.03.2005 um 17:56

Die Framelängen müssen nach ID3v2.4.x ebenfalls im
Syncsafe 32-Bit Format sein. Auch wenn das für ID3v2.3.x
nicht zutreffen sollte, stimmt der Quellcode hier nicht.
Der Fehler fällt erst bei Framelängen >127 (bzw. >255) auf, die unteren 7 (bzw. 8) Bits werden korrekt interpretiert.

Folgendes wäre im Syncsafe 32-Bit Format, wobei
Bit 7 jedes Bytes generell 0 ist, der Wert also
insgesamt nur 28 Bit (4x7Bit) breit ist:
code
lngFrameLen = &H20000 * Asc(Left$(FrameLen, 1)) + _
&H400 * Asc(Mid$(FrameLen, 2, 1)) + _
&H80 * Asc(Mid$(FrameLen, 3, 1)) + _
Asc(Mid$(FrameLen, 4, 1))
/code

Ansonsten müsste es für reguläre 32-Bit Werte so aussehen:
code
lngFrameLen = &H1000000 * Asc(Left$(FrameLen, 1)) + _
&H10000 * Asc(Mid$(FrameLen, 2, 1)) + _
&H100 * Asc(Mid$(FrameLen, 3, 1)) + _
Asc(Mid$(FrameLen, 4, 1))
/code

Kommentar von guri am 05.02.2005 um 06:29

thank you very much for this code. it really helped me. But I dont know how to save ID3 TAG v2.3.
help is appropriate
thank you very much
sorry for not being able to write in german

guri

Kommentar von Lassi am 26.01.2005 um 22:09

Der Code hat leider einen kleinen Fehler: ES KANN KEINE UMLAUTE LESEN!!!

Kommentar von Paul am 13.12.2004 um 15:59

nachdem das auslesen von ID3v2-Tag funktioniert frag ich mich nur, wie ich diesen verändert wieder abspeichern kann? wäre sehr dankbar für tips.

grüße aus frankfurt

Kommentar von Curry69 am 18.06.2004 um 17:44

@Marco

Versuch's mal mit dieser Beschreibung der ID3V2-Tags.
(Habe selbst aber noch zuwenig Erfahrung mit VB und mit MP3-Files)

http://vbaccelerator.com/home/VB/Code/vbMedia/Audio/Reading_and_Writing_MP3_ID3v1_and_v2_Tags/article.asp


Gruss

Curry

Kommentar von Marco Maier am 11.04.2004 um 16:05

Woher habt ihr die Informationen für den Aufbau der ID3V2-Tags??
Ich suche schon ganz verzweifelt im Internet, aber ich finde einfach nicht gescheites. Das von http://www.id3.org/ kapier ich irdendwie nicht. Kennt jeman eine gute Beschreibung für ID3V2-Tags am besten auf deutsch.
Möchte mir auch so ein Tool in Java schreiben.Nur mangelt es mir an Infomationen.

Vielen Dank

Kommentar von Compy am 04.01.2004 um 11:38

Is ja schön, aber der Link zu den ID3v1-Tags stimmt net :)

Kommentar von Marc Ermshaus am 01.01.2004 um 21:39

Die Zeile

lngID3Length = &H200000 * Asc(Left$(ID3Length$, 1)) + _
&H4000 * Asc(Mid$(ID3Length$, 2, 1)) + _
&H80 * Asc(Mid$(ID3Length$, 3, 1)) + _
Asc(Mid$(ID3Length$, 4, 1))
berechnet die Header-Länge, die in 32-Bits im ID3-Tag gespeichert ist. Die etwas seltsam anmutenden Multiplikationen begründen sich darin, dass die Zahl vom "32 bit synchsafe integer"-Format (siehe ID3v2-Dokumentation) in ein Visual-Basic-taugliches Format konvertiert werden muss.

Was der Abschnitt
' Nach Extended Header suchen...
If Asc(Mid$(ID3V2Tag$, 6, 1)) Or 4 = True Then
lstID3V2Info.AddItem "Extended Header gefunden"
ID3V2Tag$ = Mid$(ID3V2Tag$, 10)
End If
ID3V2Tag$ = Mid$(ID3V2Tag$, 11)
bewirken soll, ist mir ein Rätsel.
Zum einen ist die 'Or'-Bedingung meines Erachtens überflüssig, da '4 = True' immer 'False' zurückgibt und es somit ohnehin nur auf den ersten Teil der Bedingung ankommt, zum anderen prüft der vorliegende Code lediglich, ob das sechste Byte einen Wert ungleich %00000000 besitzt. Die Information über das Vorhandensein eines Extended Headers ist allerdings im sechsten Bit dieses Bytes versteckt, wobei die Bits sieben, fünf und vier andere Informationen enthalten. Man kann also meiner Meinung nach nicht sicher sagen, dass ein Extended Header vorliegt, wenn dieses komplette Byte nicht null ist.

Ohne jedwede Gewähr (es war mir nicht möglich, auf die Schnelle ein Programm zu finden, welches die entsprechenden Bits des sechsten Bytes lesen und schreiben kann) möchte ich hier eine hoffentlich funktionstüchtige Möglichkeit einfügen, die Bits auszulesen. (Der Code kann einfach in das bestehende Modul an den entsprechenden Stellen eingefügt werden.)

Modulkopf:
Private Type TBitSet
Data(0 To 7) As Boolean
End Type

Private m_BitSet As TBitSet

Private Function CreateBitSet(c As String) As TBitSet
Dim i As Integer
Dim k As Integer
Dim ret As TBitSet

k = Asc(Left$(c, 1))

For i = 0 To 7
If (k \ 2 ^ i = 1) Then
ret.Data(i) = True
k = k - 2 ^ i
Else
ret.Data(i) = False
End If
Next i

CreateBitSet = ret
End Function
Private Sub cmdOpen_Click() (ersetzt den Code zum Ermitteln eines Extended Headers):
m_BitSet = CreateBitSet(Mid$(ID3V2Tag$, 6, 1))

If (m_BitSet.Data(7)) Then lstID3V2Info.AddItem "Unsynchronisation Flag gefunden"
If (m_BitSet.Data(6)) Then lstID3V2Info.AddItem "Extended Header gefunden"
If (m_BitSet.Data(5)) Then lstID3V2Info.AddItem "Experimental Indicator gefunden"
If (m_BitSet.Data(4)) Then lstID3V2Info.AddItem "Footer gefunden"

ID3V2Tag$ = Mid$(ID3V2Tag$, 11) 'Zeile nicht löschen
Wie gesagt konnte ich noch keine MP3-Datei finden, bei denen eines der Bits gesesetzt ist, aber jedenfalls sind nun die Fragen in den Anmerkungen einigermaßen beantwortet.

Gruß
Marc

Kommentar von Dominic Griesel am 19.12.2003 um 14:28

Gut, nach langem Überlegen und Dokumentationslesen habe ich folgenden Code verstanden:

lngID3Length = &H200000 * Asc(Left$(ID3Length$, 1)) + _
&H4000 * Asc(Mid$(ID3Length$, 2, 1)) + _
&H80 * Asc(Mid$(ID3Length$, 3, 1)) + _
Asc(Mid$(ID3Length$, 4, 1))


Aber diese Zeile sagt mir rein gar nicht:
'Nach Extended Header suchen...
If Asc(Mid$(ID3V2Tag$, 6, 1)) Or 4 = True Then ...

Was bedeutet das #Or 4# ?

Gruß
Dominic

Kommentar von Matthias Hammel am 09.12.2003 um 14:49

ich wäre ihnen sehr dankbar wenn sie mir folgende rechnung in ihrem programm noch einmal genau erläutern könnten. das kommentar davor sagt leider nicht besonders viel aus. und nach meinen berechnungen kann es so nicht stimmen.


lngID3Length = &H200000 * Asc(Left$(ID3Length$, 1)) + _
&H4000 * Asc(Mid$(ID3Length$, 2, 1)) +_
&H80 * Asc(Mid$(ID3Length$, 3, 1)) + _
Asc(Mid$(ID3Length$, 4, 1))

vielen dank schon mal im vorraus

MFG M.H.

Kommentar von daydreamer am 17.07.2003 um 20:56

Toll gemacht !!
Aber wie kann man MP3-Tags in MP3-Files
reinschreiben ?

Gruß
daydreamer

Kommentar von Pasce am 14.09.2002 um 09:30

Bei mir funzt es eigentlich gut, nur die Felder "Kommentar" und "Link" können nicht ausgelesen werden! kann mir da jemand helfen?

Kommentar von Bully am 22.04.2002 um 20:00

Bei mir zeigt das Ding jedesmal an, das kein Tag vorhanden ist. In seltenen Fällen falsche Version (x). Arbeite mit WinXP und VB6. Bully

Kommentar von Sascha Monetha am 24.12.2001 um 16:52

Ist es möglich in VBA mp3-Datei abzuspielen? Wenn ja wie funktioniert das???