Das folgende Script verwende ich, um sogenannte "APE" Tags aus MP3-Dateien zu entfernen. Für ID3 Tags gibt es ja bereits AutoIt UDFs. Dieses Script ist für die Verwendung von der Kommandozeile ausgelegt, daher ist es für die "Console" zu übersetzen.
Das Script ist nur sehr grob getestet. Da die MP3s direkt geändert werden ist also Vorsicht angesagt. Besser Ihr macht eine Sicherheitskopie von den MP3s bevor ihr das Script darauf ansetzt.
Spoiler anzeigen
#include <WinAPI.au3>
[/autoit] [autoit][/autoit] [autoit]If $CmdLine[0]>0 Then
Local $FileCnt
For $FileCnt=1 To $CmdLine[0]
RemoveAPE($CmdLine[$FileCnt])
Next
Else
ConsoleWrite( _
"Remove_APE" & @CRLF & _
"Entfernt APE-Tags aus MP3-Dateien" & @CRLF & @CRLF & _
"Anwendung:" & @CRLF & _
"remove_ape.Exe <Dateiname1> [<Dateiname2> ....]" & @CRLF & @CRLF & _
"Wildcards werden nicht erkannt." & @CRLF _
)
EndIf
#cs
Entfernt APE Tags aus MP3-Dateien
Achtung: Bitte vorher stets ein Backup der MP3-Dateien anlegen, da dieses Tool die Dateien auch
zerstören könnte.
Vorgehen:
APE Tags werden am Dateiende gesucht. Das ist eine Einschraenkung, aber zumindest die empfohlene
Position.
Siehe:
http://wiki.hydrogenaudio.org/index.php?titl…2_specification
"an APE tag should be placed after the the last frame, just before the ID3v1 tag (if any)."
Dort koennen sich auch ID3V1 Tags befinden (Feste groesse 128 bytes)
diese werden detektiert und ggf. nach dem Kuerzen erneut an die Datei angehaengt
APE Tags enden mit einem speziellen Footer. Dieser wird erkannt und es wird die Version und laenge gelesen.
Ab Version 2000 gibt es noch einen Header welcher zur laenger hinzuaddiert wird.
Da dieser Header (wie auch der Footer) einen speziellen Tag aufweist, wird daraus sicherheitshalber
bei Version 2 (2000) auch geprueft.
#ce
Func RemoveAPE($Filename)
Local $hfile = FileOpen($Filename,16) ;open in binary mode
FileSetPos($hfile,-128,2) ;#128 Bytes vom Dateiende (pruefe auf id3v1tag)
Local $ID3v1Tag = FileRead($hfile)
Local $EndOffs=0;
Local $ID3v1ID = BinaryToString(BinaryMid($ID3v1Tag,1,3))
ConsoleWrite("Remove_APE: " & $FileName & @CRLF)
;MsgBox(0,"ID3v1 Tag ID",$ID3v1ID)
;APE Header/Footer Laenge: 8(id) + 4(ver) + 4(len) + 4(num)+ 4(flags) + 8(res) = 32
If ($ID3v1ID == "TAG") Then ;ID3v1 gefunden?, EndOffs Setzen und davor APE suchen
$EndOffs=128
ConsoleWrite(" ID3V1 Tags wurden erkannt (bleiben erhalten)" & @CRLF)
Else
$ID3v1Tag=""
EndIf
FileSetPos($hfile,-$EndOffs-32,2)
Local $APEFooter = FileRead($hfile,32)
Local $APEID = BinaryToString(BinaryMid($APEFooter,1,8)) ;APETAGEX
If ($APEID == "APETAGEX") Then
Local $APEVer=Number(BinaryMid($APEFooter,9,4)) ;1000 oder 2000 (dez)
Local $APELen=Number(BinaryMid($APEFooter,13,4));Laenge inkl Footer (bei APEV2: Laenge ohne Header)
;Local $APENumTags=Number(BinaryMid($APEFooter,17,4))
If $APEVer>=2000 Then
FileSetPos($hfile,-$EndOffs-$APELen-32,2)
Local $APEHeader = FileRead($hfile,32)
;Man könnte noch auf TagFlag Bit 29 pruefen (1=Header, 0=Footer)
;Machichabbernich
If ($APEID == "APETAGEX") Then
$APELen=$APELen+32
ConsoleWrite(" APE-Tags (v2) werden entfernt." & @CRLF)
Else
ConsoleWrite(" APE-Tags (v2 ohne Header) werden entfernt." & @CRLF)
;(Lt. Wikipedia ist der Header auch bei v2 optional, daher kein Fehler)
;$APELen=0
;ConsoleWrite("Fehler: APEV2 Footer ohne Header");Alternativ: ConsoleWriteError
EndIf
Else
ConsoleWrite(" APE-Tags (v1) werden entfernt." & @CRLF)
EndIf
FileClose($hfile)
If ($APELen>0) Then
;Datei verkuerzen
TruncateFile($FileName,FileGetSize($FileName)-$EndOffs-$APELen)
;ID3v1 wieder anhaengen
If BinaryLen($ID3V1Tag)>0 Then
$hfile = FileOpen($Filename,17)
;FileSetPos($hfile,0,2)
FileWrite($hfile,$ID3V1Tag)
FileClose($hfile)
EndIf
EndIf
Else
ConsoleWrite(" Keine APE Tags in Datei" & @CRLF)
FileClose($hfile)
EndIf
EndFunc
Func TruncateFile($Filename,$NewLength)
Local $hFile = _WinAPI_CreateFile($Filename, 2, 4)
_WinAPI_SetFilePointer($hFile, $NewLength)
_WinAPI_SetEndOfFile($hFile)
_WinAPI_CloseHandle($hFile)
EndFunc