Mittwoch, 28. November 2007

ID3v1 Tags in MP3-Dateien auslesen und verändern / Read and change ID3v1 Tags in MP3 files

Die Position des ID3v1 Tags in einer MP3 Datei ist recht einfach zu ermitteln. Der Offset in der Datei Beträgt -128 Bytes. Wenn also die MP3 Datei eine Grösse von 2500 Bytes besitzt, dann beginnt der Tag bei Byte 2372.

Die ersten drei Bytes stellen den Magic Code, der anzeigt, dass hier auch wirklich ein ID3v1 Tag vorhanden ist. Entsprechen diese 3 Zeichen nicht der Zeichenkette "TAG", dann ist der ID3v1 Tag ungültig und kann nicht verarbeitet werden.

Dem Magic Byte schliessen sich weitere Felder an:

Titel                  30 Bytes
Interpret              30 Bytes
Name des Albums        30 Bytes
Erscheinungsjahr        4 Bytes
Kommentar              30 Bytes
Genre (Rock, POP, ...)  1 Byte

Insgesamt ist die Struktur 3 Byte Magic Code + 125 Byte Informationen = 128 Byte groß.

Unsere erste Aufgabe besteht nun darin, die besagten 128 Bytes zur Bearbeitung in eine Variable zu kopieren. Hierfür bietet sich die Funktion FileToStr() an.

lcMP3File = GETFILE([mp3],[MP3 Audio],[Lesen],0,[Lesen des MP3 ID3 Tags])
lcMP3String = FILETOSTR(lcMP3File)

Den Tag-Block erhalten wir, indem wir die rechten 128 Byte einer eigenen Variablen zuweisen.

lcMP3Tag = RIGHT(lcMP3String,128)

Mit Substr() können wir nun Feld für Feld zur Anzeige bringen. Hierbei ist jedoch zu beachten, dass die unbenutzten Bytes eines Feldes nicht mit Blank sondern mit Chr(0) aufgefüllt sind. Hierbei handelt es sich um ein nicht darstellbares Zeichen und der Fux zeigt diese Positionen somit als Rechteck an.

Da dies optisch nicht so viel hermacht, sollten wir die Chr(0) Positionen herausfiltern.

CHRTRAN(SUBSTR(lcMP3Tag,4,30),CHR(0),[])

Möchten wir nun neue Werte hinterlegen, so können wir dies mit der Funktion Stuff() durchführen. Wichtig hierbei ist das Auffüllen des Feldes mit Chr(0).

lcMP3Tag = STUFF(lcMP3Tag,4,30,PADR([Neuer Titel],30,CHR(0)))

Als letzte Aufgabe bleibt uns nun das Zusammenführen des MP3-Strings mit unserem Tag-Block. Hierzu nehmen wir uns den zu Anfang eingelesenen String und reduzieren ihn um 128 Bytes. Im Anschluss ergänzen wir ihn um unseren Tag-String und schreiben die Daten mit StrToFile() wieder zurück auf die Festplatte. Fertig ist der Editor.

lcMP3String = SUBSTR(lcMP3String,1,LEN(lcMP3String) - 128) + lcMP3Tag
STRTOFILE(lcMP3String,lcMP3File,0)

Natürlich fehlt an dieser Stelle noch eine Bearbeitungsmaske, aber das sollte nun wirklich kein Problem mehr darstellen. Hier nun der komplette Codeblock:

LOCAL lcMP3File as String, lcMP3String as String, lcMP3Tag as String
lcMP3File = GETFILE([mp3],[MP3 Audio],[Lesen],0,[Lesen des MP3 ID3 Tags])

IF FILE(lcMP3File)
    lcMP3String = FILETOSTR(lcMP3File)
    lcMP3Tag    = RIGHT(lcMP3String,128)
 
    IF LEFT(lcMP3Tag,3) == [TAG]
        * Auslesen von ID3v1Tag Informationen
        CLEAR
        ?    CHRTRAN(SUBSTR(lcMP3Tag,  4,30),CHR(0),[])
        ?    CHRTRAN(SUBSTR(lcMP3Tag, 34,30),CHR(0),[])
        ?    CHRTRAN(SUBSTR(lcMP3Tag, 64,30),CHR(0),[])
        ?    CHRTRAN(SUBSTR(lcMP3Tag, 94, 4),CHR(0),[])
        ?    CHRTRAN(SUBSTR(lcMP3Tag, 98,30),CHR(0),[])
        ?ASC(CHRTRAN(SUBSTR(lcMP3Tag,128, 1),CHR(0),[]))

        * Setzen von ID3v1Tag Informationen
        lcMP3Tag    = STUFF(lcMP3Tag,  4,30,PADR([Neuer Titel],    30,CHR(0)))
        lcMP3Tag    = STUFF(lcMP3Tag, 34,30,PADR([Neuer Interpret],30,CHR(0)))
        lcMP3Tag    = STUFF(lcMP3Tag, 64,30,PADR([Neues Album],    30,CHR(0)))
        lcMP3Tag    = STUFF(lcMP3Tag, 94, 4,PADR([1900],            4,CHR(0)))
        lcMP3Tag    = STUFF(lcMP3Tag, 98,30,PADR([Neuer Kommentar],30,CHR(0)))
        lcMP3Tag    = STUFF(lcMP3Tag,128, 1,CHR(16))
        lcMP3String = SUBSTR(lcMP3String,1,LEN(lcMP3String) - 128) + lcMP3Tag
        STRTOFILE(lcMP3String,lcMP3File,0)
    ENDIF
ENDIF

RELEASE lcMP3File, lcMP3String, lcMP3Tag

Keine Kommentare:

Kommentar veröffentlichen