You last visited: Today at 18:59
Advertisement
ID3 Tags - Bilder?
Discussion on ID3 Tags - Bilder? within the AutoIt forum part of the Coders Den category.
09/26/2010, 16:39
#1
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
ID3 Tags - Bilder?
Code:
#include-once
;===============================================================================
;
; Description: Retrieve MP3 tag info
; Parameter(s): File name
; Requirement(s): Autoit Beta 3.104.123+ (DllStruct, Binary, RegExp)
; Return Value(s): On Success - array with data:
; 0 - Title
; 1 - Artist
; 2 - Album
; 3 - Year
; 4 - Comment
; 5 - Track number
; 6 - Genre
; 7 - Length (for V2 only, may be used for determine length for VBR files)
; 8 - Tag version
; On Failure empty string and sets @ERROR:
; 1 - Info not found
; Author(s): YDY (Lazycat)
; Version: 2.5.1
; Date: 06.05.2006
; Note(s): None
;
;===============================================================================
Func _MP3GetTag($sFile)
Local $ret = DllCall("kernel32.dll","int","CreateFile", _
"str",$sFile, _
"int",0x80000000, _
"int",0, _
"ptr",0, _
"int",3, _
"int",0x80, _
"ptr",0)
If @error OR Not $ret[0] Then
SetError(1)
Return ""
Endif
Local $vTag = _MP3GetV2Tag($ret[0])
If not IsArray($vTag) Then $vTag = _MP3GetV1Tag($ret[0], FileGetSize($sFile) - 128)
DllCall("kernel32.dll","int","CloseHandle","int", $ret[0])
If IsArray($vTag) Then Return $vTag
SetError(1)
Return ""
EndFunc
Func _MP3GetV1Tag($hFile, $nTagPos)
Local $pTag = _FileReadToStruct("char[3];char[30];char[30];char[30];char[4];char[30];byte", $hFile, $nTagPos)
If not (_DllStructArrayAsString($pTag, 1, 3) == "TAG") Then Return "" ; ID3v1 tag NOT found
Local $asInfo[9]
$asInfo[0] = _DllStructArrayAsString($pTag, 2, 30) ; Title
$asInfo[1] = _DllStructArrayAsString($pTag, 3, 30) ; Peformer
$asInfo[2] = _DllStructArrayAsString($pTag, 4, 30) ; Album
$asInfo[3] = _DllStructArrayAsString($pTag, 5, 4) ; Year
$asInfo[4] = _DllStructArrayAsString($pTag, 6, 30) ; Comment
$asInfo[5] = "" ; Track number
$asInfo[8] = "1.0"
If DllStructGetData($pTag, 6, 29) = 0 Then ; Version 1.1
$asInfo[5] = DllStructGetData($pTag, 6, 30)
$asInfo[8] = "1.1"
EndIf
$asInfo[6] = _MP3GetGenreByID(DllStructGetData($pTag, 7)) ; Genre
$asInfo[7] = ""
Return($asInfo)
EndFunc
Func _MP3GetV2Tag($hFile)
Local $nTagSize = 1, $nFrameOffset = 10, $nTagInfo
Local $asInfo[9], $sID, $pFrame, $pHeader, $pTemp, $nFrameSize, $sData
$pHeader = _FileReadToStruct("char[3];byte;byte;byte;dword;dword", $hFile, 0)
If not (StringLeft(DllStructGetData($pHeader, 1), 3) = "ID3") Then Return
For $i = 0 To 8
$asInfo[$i] = ""
Next
; Set tag version
$asInfo[8] = StringFormat("2.%d.%d", DllStructGetData($pHeader, 2), DllStructGetData($pHeader, 3))
$nTagInfo = DllStructGetData($pHeader, 4)
$nTagSize = _SSIntToInt(DllStructGetData($pHeader, 5)) + 10
If _IsBitSet($nTagInfo, 4) Then $nTagSize = $nTagSize + 10 ; Footer presented, RARE case
If _IsBitSet($nTagInfo, 6) Then $nFrameOffset = 10 + _SSIntToInt(DllStructGetData($p, 5)) ; ExtHeader presented
$pFrame = DllStructCreate("char[4];dword;short")
While $nFrameOffset < $nTagSize
$pFrame = _FileReadToStruct($pFrame, $hFile, $nFrameOffset)
$sID = DllStructGetData($pFrame, 1)
$nFrameSize = _SSIntToInt(DllStructGetData($pFrame, 2))
If $nFrameSize > $nTagSize Then Exitloop
$pTemp = _FileReadToStruct("byte;byte[" & $nFrameSize - 1 & "]", $hFile, $nFrameOffset + 10)
$sData = _GetDecodedText(DllStructGetData($pTemp, 1), DllStructGetData($pTemp, 2), $nFrameSize)
Select
Case $sID == "TIT2" ; Title
$asInfo[0] = $sData
Case $sID == "TPE1" ; Performer (primary)
$asInfo[1] = $sData
Case $sID == "TPE2" ; Performer (secondary)
If $asInfo[1] == "" Then $asInfo[1] = $sData
Case $sID == "TALB" ; Album
$asInfo[2] = $sData
Case $sID == "TYER" ; Year
$asInfo[3] = $sData
Case $sID == "COMM" ; Required special
If $asInfo[4] == "" Then ; MS ShellExt tag editor add empty COMM at the end of tag...
; Not sure if this is correct method...
If DllStructGetData($pTemp, 2, 4) = 0 Then
If DllStructGetData($pTemp, 2, 5) = 0 Then
$asInfo[4] = _GetDecodedText(DllStructGetData($pTemp, 1), StringTrimLeft(DllStructGetData($pTemp, 2), 5), $nFrameSize)
Else
$asInfo[4] = _GetDecodedText(DllStructGetData($pTemp, 1), StringTrimLeft(DllStructGetData($pTemp, 2), 4), $nFrameSize)
EndIf
EndIf
EndIf
Case $sID == "TRCK" ; Track number
$asInfo[5] = $sData
Case $sID == "TCON" ; Genre
$asInfo[6] = $sData
$sData = StringRegExp($sData, "\((\d{1,3})\)", 1)
If @extended Then $asInfo[6] = _MP3GetGenreByID($sData[0])
Case $sID == "TLEN" ; Length!
$asInfo[7] = Int(Number($sData)/1000)
$asInfo[7] = StringFormat("%d:%02d", Int($asInfo[7] / 60), $asInfo[7] - Int($asInfo[7] / 60) * 60)
Case StringLen($sID) < 4 or not StringIsAlNum($sID)
Exitloop ; Zero-byte padding (end of tag), wrong sID -> Exitloop
EndSelect
$nFrameOffset = $nFrameOffset + $nFrameSize + 10
$pTemp = 0
Wend
Return($asInfo)
EndFunc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Support functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Func _MP3GetGenreByID($iID)
Local $asGenre = StringSplit("Blues,Classic Rock,Country,Dance,Disco,Funk,Grunge,Hip-Hop," & _
"Jazz,Metal,New Age, Oldies,Other,Pop,R&B,Rap,Reggae,Rock,Techno,Industrial,Alternative," & _
"Ska,Death Metal,Pranks,Soundtrack,Euro-Techno,Ambient,Trip-Hop,Vocal,Jazz+Funk,Fusion," & _
"Trance,Classical,Instrumental,Acid,House,Game,Sound Clip,Gospel,Noise,Alternative Rock," & _
"Bass,Soul,Punk,Space,Meditative,Instrumental Pop,Instrumental Rock,Ethnic,Gothic,Darkwave," & _
"Techno-Industrial,Electronic,Pop-Folk,Eurodance,Dream,Southern Rock,Comedy,Cult,Gangsta," & _
"Top 40,Christian Rap,Pop/Funk,Jungle,Native US,Cabaret,New Wave,Psychadelic,Rave,Showtunes," & _
"Trailer,Lo-Fi,Tribal,Acid Punk,Acid Jazz,Polka,Retro,Musical,Rock & Roll,Hard Rock,Folk," & _
"Folk-Rock,National Folk,Swing,Fast Fusion,Bebob,Latin,Revival,Celtic,Bluegrass,Avantgarde," & _
"Gothic Rock,Progressive Rock,Psychedelic Rock,Symphonic Rock,Slow Rock,Big Band,Chorus," & _
"Easy Listening,Acoustic,Humour,Speech,Chanson,Opera,Chamber Music,Sonata,Symphony,Booty Bass," & _
"Primus,Porn Groove,Satire,Slow Jam,Club,Tango,Samba,Folklore,Ballad,Power Ballad,Rhytmic Soul," & _
"Freestyle,Duet,Punk Rock,Drum Solo,Acapella,Euro-House,Dance Hall,Goa,Drum & Bass,Club-House," & _
"Hardcore,Terror,Indie,BritPop,Negerpunk,Polsk Punk,Beat,Christian Gangsta,Heavy Metal,Black Metal," & _
"Crossover,Contemporary C,Christian Rock,Merengue,Salsa,Thrash Metal,Anime,JPop,SynthPop", ",")
If ($iID >= 0) and ($iID < 148) Then Return $asGenre[$iID + 1]
Return("")
EndFunc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Common functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Func _DllStructArrayAsString($p, $index, $size, $start = 1)
Local $sTemp = "", $char
For $i = $start to $size
$char = DllStructGetData($p, $index, $i)
If $char = 0 then Return $sTemp
$sTemp &= Chr($char)
Next
Return $sTemp
EndFunc
Func _SSIntToInt($nSSInt)
Local $nRet = 0
For $i = 0 To 3
$nRet = $nRet + BitShift(BitAND(BitShift($nSSInt, 8 * (3-$i)), 0xFF), -7 * $i)
Next
Return($nRet)
EndFunc
Func _IsBitSet($nNum, $nBit)
Return BitAND(BitShift($nNum, $nBit), 1)
EndFunc
Func _FileReadToStruct($vStruct, $hFile, $nOffset)
If not DllStructGetSize($vStruct) Then $vStruct = DllStructCreate($vStruct)
Local $nLen = DllStructGetSize($vStruct)
Local $ret = DllCall("kernel32.dll","int","SetFilePointer", _
"int",$hFile, _
"int",$nOffset, _
"int",0, _
"int",0) ; FILE_BEGIN
Local $pRead = DllStructCreate("dword")
$ret = DllCall("kernel32.dll","int","ReadFile", _
"int",$hFile, _
"ptr",DllStructGetPtr($vStruct), _
"int", $nLen, _
"ptr",DllStructGetPtr($pRead), _
"ptr",0)
If @error Then
SetError(1)
EndIf
Local $nRead = DllStructGetData($pRead, 1)
$pRead = 0
SetExtended($nRead)
If not ($nRead = $nLen) Then SetError(2)
Return $vStruct
EndFunc
Func _GetDecodedText($nType, $sText, $nSize)
Switch $nType
Case 0 ; ASCII
If ($nSize - 1) = 1 Then Return Chr($sText)
Return $sText
Case 0x1, 0x2 ; Unicode
Return _Unicode2Asc($sText)
Case 0x3 ; UTF-8
Return _Unicode2Asc(_Utf82Unicode($sText))
EndSwitch
EndFunc
;;;;;;;;;;;;;;;;;;;;;;;; Unicode conversion functions originally written by Arilvv ;;;;;;;;;;;;;;;;;;;;;;;
Func _Unicode2Asc($UniString)
Local $lb, $hb, $InpBuf
Local $BufferLen = StringLen($UniString)
Local $Input = DllStructCreate("ubyte[" & $BufferLen & "]")
DllStructSetData($Input, 1, $UniString)
$lb = DllStructGetData($Input, 1, 1)
$hb = DllStructGetData($Input, 1, 2)
If (($lb = 0xFF) and ($hb = 0xFE)) or (($lb = 0xFE) and ($hb = 0xFF)) Then ; BOM found
$BufferLen -= 2
$InpBuf = DllStructCreate("byte[" & $BufferLen & "]", DllStructGetPtr($Input) + 2)
Else
$InpBuf = DllStructCreate("byte[" & $BufferLen & "]", DllStructGetPtr($Input))
EndIf
Local $Output = DllStructCreate("char[" & $BufferLen & "]")
Local $Return = DllCall("kernel32.dll", "int", "WideCharToMultiByte", _
"int", 0, _
"int", 0, _
"ptr", DllStructGetPtr($InpBuf), _
"int", $BufferLen / 2, _
"ptr", DllStructGetPtr($Output), _
"int", $BufferLen, _
"int", 0, _
"int", 0)
Return DllStructGetData($Output, 1)
EndFunc
Func _Utf82Unicode($Utf8String)
Local $BufferSize = StringLen($Utf8String) * 2
Local $Buffer = DllStructCreate("byte[" & $BufferSize & "]")
Local $Return = DllCall("Kernel32.dll", "int", "MultiByteToWideChar", _
"int", 65001, _
"int", 0, _
"str", $Utf8String, _
"int", StringLen($Utf8String), _
"ptr", DllStructGetPtr($Buffer), _
"int", $BufferSize)
Return StringLeft(DllStructGetData($Buffer, 1), $Return[0] * 2)
EndFunc
;===============================================================================
;
; Description: Retrieve MP3 (MP2, MPA) basic information
; Parameter(s): File name
; Requirement(s): None
; Return Value(s): On Success - array with data:
; 0 - MPEG version
; 1 - Layer
; 2 - Bitrate
; 3 - Frequency
; 4 - Channel Mode
; 5 - Duration
; 6 - Frames
; 7 - CRC protected
; 8 - Copyrighted
; 9 - Original
; On Failure empty string and sets @ERROR:
; 1 - Info not found
; Author(s): YDY (Lazycat) < >
; Version: 1.2.00
; Date: 30.12.2004
; Note(s): None
;
;===============================================================================
Func _GetMP3Info($file)
Local $data[10], $offset = 1, $isValid = 0, $isVBR = 0
Local $aVersion = StringSplit("MPEG 2.5|Undefined|MPEG 2.5|MPEG 1", "|")
Local $aLayer = StringSplit("Undefined|Layer III|Layer II|Layer I", "|")
Local $sBitrate = ""
Local $sFrequency = ""
Local $aChanMode = StringSplit("Stereo|Joint stereo|Dual channel|Mono", "|")
Local $aFlags = StringSplit("No|Yes", "|")
Local $head, $nVer, $nLay
If _FileReadAtOffsetHEX ($file, 1, 3) = "494433" Then ; ID3v2 tag found
$offset = _HEXToSSInt(_FileReadAtOffsetHEX ($file, 7, 4)) + 10 ; End of ID3v2 tag
Endif
For $ic = $offset to 4096 + $offset
$marker = _FileReadAtOffsetHEX ($file, $ic, 2)
$marker = StringLeft($marker, 3)
If StringInStr("FFF,FFE", $marker) Then ; Assume that is frame start
$head = _HexToBin(_FileReadAtOffsetHEX ($file, $ic, 4))
$nVer = _GetRBits($head, 19, 2)
$nLay = _GetRBits($head, 17, 2)
If ($nVer <> 1) and ($nLay <> 0) Then
If _FileReadAtOffsetHEX ($file, $ic+36, 4) = "58696E67" Then $isVBR = 1 ; Is this a right way?..
$isValid = 1
Exitloop
Endif
Endif
Next
If not $isValid Then
SetError(1) ; Frame not found (not mp3 data?)
Return ("")
Endif
Select
Case $nVer = 3
$sFrequency = "44100|48000|32000|Undefined"
Case $nVer = 2
$sFrequency = "22050|24000|16000|Undefined"
Case $nVer = 0
$sFrequency = "11025|12000|8000|Undefined"
EndSelect
Local $aFrequency = StringSplit($sFrequency, "|")
$data[3] = _GetData($aFrequency, _GetRBits($head, 10, 2))
Local $pad = 0, $bitrate, $framesize, $frames, $length, $fps
If _GetRBits($head, 9, 1) Then $pad = 1
If $isVBR Then
$data[2] = "Variable"
Else
Select
Case $nVer = 3 and $nLay = 3
$sBitrate = "Free|32|64|96|128|160|192|224|256|288|320|352|384|416|448|Undefined"
Case $nVer = 3 and $nLay = 2
$sBitrate = "Free|32|48|56|64|80|96|112|128|160|192|224|256|320|384|Undefined"
Case $nVer = 3 and $nLay = 1
$sBitrate = "Free|32|40|48|56|64|80|96|112|128|160|192|224|256|320|Undefined"
Case $nVer = 2 and $nLay = 3
$sBitrate = "Free|32|48|56|64|80|96|112|128|144|160|176|192|224|256|Undefined"
Case ($nVer = 2 and $nLay = 2) or ($nVer = 2 and $nLay = 1)
$sBitrate = "Free|8|16|24|32|40|48|56|64|80|96|112|128|144|160|Undefined"
EndSelect
Local $aBitrate = StringSplit($sBitrate, "|")
$data[2] = _GetData($aBitrate, _GetRBits($head, 12, 4))
$bitrate = 1000 * $data[2]
If $nLay = 3 Then
$framesize = (((12 * $bitrate) / $data[3]) + $pad) * 4
$fps = $data[3]/384
Else
$framesize = ((144 * $bitrate) / $data[3]) + $pad
$fps = $data[3]/1152
Endif
$frames = FileGetSize($file) / $framesize
$length = $frames / $fps
Endif
$data[0] = _GetData($aVersion, $nVer)
$data[1] = _GetData($aLayer, $nLay)
$data[4] = _GetData($aChanMode, _GetRBits($head, 6, 2))
$data[5] = StringFormat("%d:%02d", Int($length / 60), $length - Int($length / 60) * 60)
$data[6] = Int($frames)
$data[7] = _GetData($aFlags, not _GetRBits($head, 16, 1)) ; CRC
$data[8] = _GetData($aFlags, _GetRBits($head, 3, 1)) ; Private
$data[9] = _GetData($aFlags, _GetRBits($head, 2, 1)) ; Original
Return($data)
EndFunc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Support functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Func _GetRBits($str, $pos, $size)
Local $ic, $res = 0, $bStr = StringMid($str, 33 - $pos - $size, $size)
For $ic = 0 to $size-1
If StringMid($bStr, $size-$ic, 1) == "1" Then $res = $res + 2^$ic
Next
Return ($res)
EndFunc
Func _GetData(ByRef $array, $val)
If $val > UBound($array)-1 Then Return("Undefined")
Return ($array[$val+1])
EndFunc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Common functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Func _HEXToSSInt($sHexStr)
Local $iCnt, $iLen, $sTempStr = "", $iReturn = 0
For $iCnt = 1 to StringLen($sHexStr) Step 2
$sTempStr = $sTempStr & StringTrimLeft(_HexToBin(StringMid($sHexStr, $iCnt, 2)), 1)
Next
$iLen = StringLen($sTempStr)
For $iCnt = 0 To $iLen - 1
$iReturn = $iReturn + Number(StringMid($sTempStr, $iLen - $iCnt, 1)) * 2^$iCnt
Next
Return($iReturn)
EndFunc
Func _HexToBin($str)
Local $res="", $i
While StringLen($str) > 0
$val = Dec(StringRight($str, 1))
$str = StringTrimRight($str, 1)
For $i = 1 to 4
$res = String(Mod($val, 2)) & $res
$val = Int($val/2)
Next
Wend
Return ($res)
EndFunc
Func _FileReadAtOffsetHEX ($file, $offset, $bytes)
Local $tfile = FileOpen($file, 0)
Local $tstr = "", $i
FileRead($tfile, $offset-1)
For $i = $offset To $offset + $bytes - 1
$tstr = $tstr & Hex(Asc(FileRead($tfile, 1)), 2)
Next
FileClose($tfile)
Return ($tstr)
Endfunc
Hab 2 UDFs von Lazycat zusammengemixt. Alles schön und gut, aber was ist mit den Bildern? xD
Hab in der kernel32.dll nix gefunden :x
09/26/2010, 18:20
#2
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
Achja, warum nimmst du fürs auslesen nicht die BassTags.dll mit der dazugehörigen UDF?
09/26/2010, 18:30
#3
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
kA, arbeite mit der hier schon ne Weile und wirkliche Unterschiede gibts nich xD
09/26/2010, 20:00
#4
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
Performance und Geschwindigkeit?
09/26/2010, 20:31
#5
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
Quote:
Originally Posted by
pinguin94
Performance und Geschwindigkeit?
Beim einmaligen Auslesen? Ich glaubs auch xD
09/26/2010, 22:03
#6
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
Quote:
Originally Posted by
mipez
Beim einmaligen Auslesen? Ich glaubs auch xD
Jede ms zählt!
09/26/2010, 22:22
#7
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
ns ;D
Aber eine wirkliche Antwort kannste mir nich liefern? q_q
09/27/2010, 16:16
#8
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
Ne momentan nicht, da müsste ich mich länger in den Code einarbeite, hab ich nur grad keine Lust zu, weil ich nen Programm bis Freitag für ne Firma gemacht haben muss
09/27/2010, 17:01
#9
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
Ok, anders: In welcher Windoof oder WMP dll sind die Befehle gespeichert? ;D
09/27/2010, 18:06
#10
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
Welche Befehle?
09/27/2010, 18:22
#11
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
Quote:
Originally Posted by
pinguin94
Welche Befehle?
Auslese der ID3 Daten^^
09/27/2010, 18:38
#12
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
Von Bildern?
09/27/2010, 20:22
#13
elite*gold: 0
Join Date: Apr 2008
Posts: 1,079
Received Thanks: 438
Hier die UDF:
Die ID "APIC Attached picture" hält das Bild.
09/27/2010, 20:37
#14
elite*gold: 0
Join Date: Jul 2009
Posts: 2,241
Received Thanks: 848
Öhm ja, schon probiert, und die wirft kein Bild aus ;D
Array bleibt an der Stelle schlicht leer... egal ob spezifisch oder gesamte IDs...
Und SetTagField funzt auch nich ;D
09/27/2010, 21:34
#15
elite*gold: 2
Join Date: Mar 2008
Posts: 1,778
Received Thanks: 1,222
Ach jetzt check ich deine Frage
Ich schau mal was ich so hab
Similar Threads
Wie macht man bei YouTube extra Tags???
08/06/2010 - Off Topic - 3 Replies
Hi Leute,
hab ne frage:
Wie macht in der beschreibung extra tags???
einfach da wörter hinschreiben oder muss man nen code oder so eingeben?
würde mich riesig über antworten freuen.
Guild tags with simbols?
07/11/2009 - Dekaron - 6 Replies
Was wondering if theres a way to make a guild using "&" simbol within its name.
Thanks to anyone that replies.
New Rule ?? add tags
04/18/2009 - GunZ - 0 Replies
i think a new rule should be added to stop confustion. add the game version tag to thread title.
e.g.
LawnMower v2.1
GODMODE
ect ect
All times are GMT +2. The time now is 19:00 .