id3tag auslesen mit Image
Verfasst: 07.02.2018 14:36
Ich möchte gern diesen alten code verwenden der für PB 4.. geschrieben wurde, aber mein Wissen reicht nicht, um herrauszufinden warum er in PB 5.61 nicht funktioniert.
Kann da jemand helfen ?
Kann da jemand helfen ?
Code: Alles auswählen
; ID3 Example for PB 4.xx
; Coder: 'a14xerus' (http://www.alexander-n.de)
; with friendly support of 'Padde'
; 06.06.2007
; Reference for ID3v2: http://www.id3.org/id3v2.3.0
;EnableExplicit
UseJPEGImageDecoder()
UsePNGImageDecoder()
;- Constants
#ID3_BinaryReturn=0
#ID3_ImageReturn=1
;- Structures
Structure TagV1 ; Only a few Tags, a list of all tags on http://www.id3.org
tag.s
title.s ; "TIT2"
artist.s ; "TPE1"
album.s ; "TALB"
year.s ; ...
genre.s
URL.s
Copyright.s
track.s
EndStructure
Structure TagV2 ; Only a few Tags, a list of all tags on http://www.id3.org
title.s ; "TIT2"
artist.s ; "TPE1"
album.s ; "TALB"
year.s ; ...
genre.s
URL.s
Copyright.s
track.s
lyrics.s
image.l
EndStructure
Global Tags.TagV2
Global TagV1.TagV1
;- ID3 Tag Version 1 Read
Procedure GetID3v1Tag(filename.s,*infos.TagV1)
Protected *mem, header$, Result.l
If ReadFile(0,filename)
*mem = AllocateMemory(128) ; allocate 128 byte
If *mem
FileSeek(0,Lof(0)-128)
ReadData(0,*mem , 128) ; read the last 128 byte
header$ = PeekS(*mem , 3)
If header$ = "TAG" ; 3 chars
With *infos
\title = Trim(PeekS(*mem + 3, 30)) ; 30 chars
\artist = Trim(PeekS(*mem + 33, 30)) ; 30 chars
\album = Trim(PeekS(*mem + 63, 30)) ; 30 chars
\year = Trim(PeekS(*mem + 93, 4)) ; 4 chars
; \Comment = Trim(PeekS(*mem + 97, 29)) ; 30 chars
\track = Trim(PeekS(*mem + 126, 1)) ; 1 chars
\genre = Trim(PeekS(*mem + 127, 1)) ; 1 chars
EndWith
Result = #True
EndIf
FreeMemory(*mem)
EndIf
CloseFile(0)
EndIf
ProcedureReturn Result
EndProcedure
;- ID3 Tag Version 2 Procedures
Procedure frameTXXX(id.s, FrameSize.l, *infos.TagV2)
Protected TextEncoding.b, *mem, Contents.s
TextEncoding = ReadByte(0)&$FF ; TXXX Textencoding
FrameSize - 1 ; subtract TextEncoding-Byte from size
If FrameSize <= 0
ProcedureReturn #False
EndIf
*mem = AllocateMemory(FrameSize)
ReadData(0,*mem, FrameSize)
If TextEncoding = 0
Contents = PeekS(*mem,FrameSize,#PB_Ascii)
ElseIf TextEncoding = 1
Contents = PeekS(*mem+2,FrameSize-2,#PB_UTF16)
EndIf
FreeMemory(*mem)
With *infos
Select id
Case "TIT2"
\title = Contents
Case "TPE1", "TPE1"
\artist = Contents
Case "TALB"
\album = Contents
Case "TYER"
\year = Contents
Case "TCON"
\genre = Contents
Case "TCOP"
\Copyright = Contents
Case "TRCK"
\track = Contents
EndSelect
EndWith
ProcedureReturn #True
EndProcedure
Procedure frameWXXX(id.s, FrameSize.l, *infos.TagV2)
Protected Contents.s
ReadByte(0) ; WXXX Textencoding for Description (URLs are allways ASCII)
FrameSize - 1
If FrameSize <= 0
ProcedureReturn #False
EndIf
Contents = Space(FrameSize)
ReadData(0,@Contents, FrameSize)
*infos\URL = Contents
ProcedureReturn #True
EndProcedure
Procedure frameAPIC(id.s, FrameSize.l, *infos.TagV2)
Protected TextEncoding.b, tmp.l, *mem
tmp = Loc(0)
TextEncoding = ReadByte(0) ; APIC Textencoding
If TextEncoding = 0
ReadString(0,#PB_Ascii) ; APIC MIME (ASCII)
ElseIf TextEncoding = 1
ReadString(0,#PB_UTF16) ; APIC MIME (UTF16 / Unicode)
EndIf
If ReadByte(0)&$FF = $03 ; APIC Picture Typ ($03 = Cover front) (for overview look at http://www.id3.org)
If TextEncoding = 0
ReadString(0,#PB_Ascii) ; APIC Description (ASCII)
ElseIf TextEncoding = 1
ReadString(0,#PB_UTF16) ; APIC Description (UTF16)
EndIf
FrameSize - (Loc(0)-tmp) ; subtract the desciptions from the framesize to get the picturesize
*mem = AllocateMemory(FrameSize)
ReadData(0,*mem, FrameSize)
*infos\image = CatchImage(-1,*mem,FrameSize,#PB_Image_DisplayFormat)
FreeMemory(*mem)
EndIf
EndProcedure
Procedure FrameUSLT(id.s, FrameSize.l, *infos.TagV2) ; Hacked together by Localmotion34 - Props to a14xerus for finding Framseize code that WORKS
Protected TextEncoding.b, tmp.l, *mem
tmp = Loc(0)
TextEncoding = ReadByte(0) ; USLT Textencoding
If TextEncoding = 0
ReadString(0,#PB_Ascii) ; APIC MIME (ASCII)
ElseIf TextEncoding = 1
ReadString(0,#PB_UTF16) ; APIC MIME (UTF16 / Unicode)
EndIf
FrameSize -(Loc(0)-tmp) ; subtract the desciptions from the framesize to get the picturesize
If FrameSize>0
*mem = AllocateMemory(FrameSize)
ReadData(0,*mem, FrameSize)
*infos\lyrics = PeekS(*mem,FrameSize)
FreeMemory(*mem)
Else
*infos\lyrics =""
EndIf
EndProcedure
Procedure GetID3v2Tag(filename.s,*infos.TagV2)
Protected ID3.s, ID3Size, byte.l, Size.l, FrameID.s, FrameSize.l, Location.l
If ReadFile(0,filename)
ID3.s = Space(3)
ReadData(0,@ID3, 3)
If ID3 = "ID3" And ReadByte(0) = $03 ; must be ID3v2.3.x !
ReadByte(0) ; Revision (not needed)
ReadByte(0) ; Flags (not needed)
ID3Size = 0 ; get hole Size of ID3Tag
ID3Size = ReadLong(0)
ID3Size = ((ID3Size&$FF)<<24)+((ID3Size&$FF00)<<8)+((ID3Size&$FF0000)>>8)+((ID3Size>>24)&$FF)
Else
; no ID3v2.3.x tag present
CloseFile(0)
ProcedureReturn #False
EndIf
Size.l = 0
Repeat
; examine All frames
; / Frameheader starts
FrameID.s = Space(4)
ReadData(0,@FrameID, 4) ; Read FrameID (allways 4 chars)
If Asc(Left(FrameID, 1)) = 0
CloseFile(0)
ProcedureReturn #True
EndIf
;;; F*ck you Id3lib.org. your Sh*t documentation makes it IMPOSSIBLE to get correct frame sizes
FrameSize = 0
FrameSize = ReadLong(0) ; get framesize ( the framesize is the size of the values excluding the frameheader)
FrameSize = ((FrameSize&$FF)<<24)+((FrameSize&$FF00)<<8)+((FrameSize&$FF0000)>>8)+((FrameSize>>24)&$FF) ; props to a14xerus
Size + FrameSize
ReadByte(0): ReadByte(0) ; Frame Flags (not needed)
If FrameSize < 1 : ProcedureReturn #False : EndIf
; \ Frameheader ends (Frameheader allways 10 Bytes)
Location = Loc(0) + FrameSize ; set 'location'value to end of the actual frame
; / Framebody starts
Select FrameID ; Read teh FrameID (Overview on http://www.id3.org)
Case "TIT2", "TPE1", "TALB", "TYER", "TCON", "TCOP", "TRCK", "TPE2"
frameTXXX(FrameID, FrameSize, *infos)
Case "WXXX"
frameWXXX(FrameID, FrameSize, *infos)
Case "APIC"
frameAPIC(FrameID, FrameSize, *infos)
Case "USLT"
FrameUSLT(FrameID, FrameSize, *infos)
; Debug "found lyrics"
; Debug FrameSize
EndSelect
; \ Framebody ends
FileSeek(0,Location) ; Jump to the end of the frame.
; (if something went wrong nevertheless you are at the right location in the file)
Until Size >= ID3Size ; stop if tag size reached/exceeded
CloseFile(0)
EndIf
EndProcedure
Procedure GetID3Tag(filename.s,*infos.TagV1, *info.TagV2)
With *info ; delete the old settings
\album = ""
\artist = ""
\Copyright = ""
\genre = ""
\title = ""
\track = ""
\URL = ""
\year = ""
\lyrics=""
If \image
FreeImage(\image)
EndIf
\image = 0
EndWith
If filename=""
ProcedureReturn #False
EndIf
Debug "Datei zum bearbeiten ist "+filename
GetID3v1Tag(filename,*infos) ; if there are old ID3v1 Tags, read them out
GetID3v2Tag(filename,*info) ; read the new Version (ID3v2)
EndProcedure
;- Lower Level Procedures for ID3 Tag Version 2 Reading
Procedure frameAPICReturn(id.s, FrameSize.l, *infos.TagV2, BinaryOrImage)
Protected TextEncoding.b, tmp.l, *mem
tmp = Loc(0)
TextEncoding = ReadByte(0) ; APIC Textencoding
If TextEncoding = 0
ReadString(0,#PB_Ascii) ; APIC MIME (ASCII)
ElseIf TextEncoding = 1
ReadString(0,#PB_UTF16) ; APIC MIME (UTF16 / Unicode)
EndIf
If ReadByte(0)&$FF = $03 ; APIC Picture Typ ($03 = Cover front) (for overview look at http://www.id3.org)
If TextEncoding = 0
ReadString(0,#PB_Ascii) ; APIC Description (ASCII)
ElseIf TextEncoding = 1
ReadString(0,#PB_UTF16) ; APIC Description (UTF16)
EndIf
FrameSize - (Loc(0)-tmp) ; subtract the desciptions from the framesize to get the picturesize
*mem = AllocateMemory(FrameSize)
ReadData(0,*mem, FrameSize)
Select BinaryOrImage
Case 0
ProcedureReturn *mem
Case 1
*infos\image = CatchImage(-1,*mem,FrameSize,#PB_Image_DisplayFormat)
FreeMemory(*mem)
ProcedureReturn *infos\image
EndSelect
EndIf
EndProcedure
Procedure ID3GetImage(filename.s) ; Returns a HBITMAP
Protected ID3.s, ID3Size, byte.l, Size.l, FrameID.s, FrameSize.l, Location.l, *infos.TagV2
If ReadFile(0,filename)
ID3.s = Space(3)
ReadData(0,@ID3, 3)
If ID3 = "ID3" And ReadByte(0) = $03 ; must be ID3v2.3.x !
ReadByte(0) ; Revision (not needed)
ReadByte(0) ; Flags (not needed)
ID3Size = 0 ; get hole Size of ID3Tag
ID3Size = ReadLong(0)
ID3Size = ((ID3Size&$FF)<<24)+((ID3Size&$FF00)<<8)+((ID3Size&$FF0000)>>8)+((ID3Size>>24)&$FF)
Else
; no ID3v2.3.x tag present
CloseFile(0)
ProcedureReturn #False
EndIf
*infos.TagV2=AllocateMemory(SizeOf(TagV2))
Size.l = 0
Repeat
; examine All frames
; / Frameheader starts
FrameID.s = Space(4)
ReadData(0,@FrameID, 4) ; Read FrameID (allways 4 chars)
If Asc(Left(FrameID, 1)) = 0
CloseFile(0)
ProcedureReturn #True
EndIf
FrameSize = 0
FrameSize = ReadLong(0) ; get framesize ( the framesize is the size of the values excluding the frameheader)
FrameSize = ((FrameSize&$FF)<<24)+((FrameSize&$FF00)<<8)+((FrameSize&$FF0000)>>8)+((FrameSize>>24)&$FF) ; props to a14xerus
Size + FrameSize
ReadByte(0): ReadByte(0) ; Frame Flags (not needed)
If FrameSize < 1 : ProcedureReturn #False : EndIf
; \ Frameheader ends (Frameheader allways 10 Bytes)
Location = Loc(0) + FrameSize ; set 'location'value to end of the actual frame
; / Framebody starts
Select FrameID
Case "APIC"
returnimage.l=frameAPICReturn(FrameID, FrameSize, *infos, #ID3_ImageReturn)
Break
EndSelect
; \ Framebody ends
FileSeek(0,Location) ; Jump to the end of the frame.
; (if something went wrong nevertheless you are at the right location in the file)
Until Size >= ID3Size ; stop if tag size reached/exceeded
CloseFile(0)
FreeMemory(*infos)
ProcedureReturn returnimage
EndIf
EndProcedure
Procedure ID3GetImageBinaryData(filename.s);Returns compressed image data--YOU have to decode it and/or write it to a file!!!!!!
Protected ID3.s, ID3Size, byte.l, Size.l, FrameID.s, FrameSize.l, Location.l
If ReadFile(0,filename)
ID3.s = Space(3)
ReadData(0,@ID3, 3)
If ID3 = "ID3" And ReadByte(0) = $03 ; must be ID3v2.3.x !
ReadByte(0) ; Revision (not needed)
ReadByte(0) ; Flags (not needed)
ID3Size = 0 ; get hole Size of ID3Tag
ID3Size = ReadLong(0)
ID3Size = ((ID3Size&$FF)<<24)+((ID3Size&$FF00)<<8)+((ID3Size&$FF0000)>>8)+((ID3Size>>24)&$FF)
Else
; no ID3v2.3.x tag present
CloseFile(0)
ProcedureReturn #False
EndIf
*infos.TagV2=AllocateMemory(SizeOf(TagV2))
Size.l = 0
Repeat
; examine All frames
; / Frameheader starts
FrameID.s = Space(4)
ReadData(0,@FrameID, 4) ; Read FrameID (allways 4 chars)
If Asc(Left(FrameID, 1)) = 0
CloseFile(0)
ProcedureReturn #True
EndIf
FrameSize = 0
FrameSize = ReadLong(0) ; get framesize ( the framesize is the size of the values excluding the frameheader)
FrameSize = ((FrameSize&$FF)<<24)+((FrameSize&$FF00)<<8)+((FrameSize&$FF0000)>>8)+((FrameSize>>24)&$FF) ; props to a14xerus
Size + FrameSize
ReadByte(0): ReadByte(0) ; Frame Flags (not needed)
If FrameSize < 1 : ProcedureReturn #False : EndIf
; \ Frameheader ends (Frameheader allways 10 Bytes)
Location = Loc(0) + FrameSize ; set 'location'value to end of the actual frame
; / Framebody starts
Select FrameID
Case "APIC"
imagemem.l=frameAPICReturn(FrameID, FrameSize, *infos, #ID3_BinaryReturn)
Break
EndSelect
; \ Framebody ends
FileSeek(0,Location) ; Jump to the end of the frame.
; (if something went wrong nevertheless you are at the right location in the file)
Until Size >= ID3Size ; stop if tag size reached/exceeded
CloseFile(0)
FreeMemory(*infos)
ProcedureReturn imagemem
EndIf
EndProcedure
Procedure.s FrameUSLTreturn(id.s, FrameSize.l, *infos.TagV2) ; Hacked together by Localmotion34 - Props to a14xerus for finding Framseize code that WORKS
Protected TextEncoding.b, tmp.l, *mem
tmp = Loc(0)
TextEncoding = ReadByte(0) ; USLT Textencoding
If TextEncoding = 0
ReadString(0,#PB_Ascii) ; APIC MIME (ASCII)
ElseIf TextEncoding = 1
ReadString(0,#PB_UTF16) ; APIC MIME (UTF16 / Unicode)
EndIf
FrameSize -(Loc(0)-tmp) ; subtract the desciptions from the framesize to get the picturesize
If FrameSize>0
*mem = AllocateMemory(FrameSize)
ReadData(0,*mem, FrameSize)
*infos\lyrics = PeekS(*mem,FrameSize)
FreeMemory(*mem)
ProcedureReturn *infos\lyrics
Else
*infos\lyrics =""
ProcedureReturn ""
EndIf
EndProcedure
Procedure.s ID3GetSongLyrics(filename.s)
Protected ID3.s, ID3Size, byte.l, Size.l, FrameID.s, FrameSize.l, Location.l, *infos.TagV2
If ReadFile(0,filename)
ID3.s = Space(3)
ReadData(0,@ID3, 3)
If ID3 = "ID3" And ReadByte(0) = $03 ; must be ID3v2.3.x !
ReadByte(0) ; Revision (not needed)
ReadByte(0) ; Flags (not needed)
ID3Size = 0 ; get hole Size of ID3Tag
ID3Size = ReadLong(0)
ID3Size = ((ID3Size&$FF)<<24)+((ID3Size&$FF00)<<8)+((ID3Size&$FF0000)>>8)+((ID3Size>>24)&$FF)
Else
; no ID3v2.3.x tag present
CloseFile(0)
ProcedureReturn ""
EndIf
*infos.TagV2=AllocateMemory(SizeOf(TagV2))
Size.l = 0
Repeat
; examine All frames
; / Frameheader starts
FrameID.s = Space(4)
ReadData(0,@FrameID, 4) ; Read FrameID (allways 4 chars)
If Asc(Left(FrameID, 1)) = 0
CloseFile(0)
;ProcedureReturn #True
EndIf
FrameSize = 0
FrameSize = ReadLong(0) ; get framesize ( the framesize is the size of the values excluding the frameheader)
FrameSize = ((FrameSize&$FF)<<24)+((FrameSize&$FF00)<<8)+((FrameSize&$FF0000)>>8)+((FrameSize>>24)&$FF) ; props to a14xerus
Size + FrameSize
ReadByte(0): ReadByte(0) ; Frame Flags (not needed)
If FrameSize < 1 : ProcedureReturn "" : EndIf
; \ Frameheader ends (Frameheader allways 10 Bytes)
Location = Loc(0) + FrameSize ; set 'location'value to end of the actual frame
; / Framebody starts
Select FrameID
Case "USLT"
returntext.s=FrameUSLTreturn(FrameID, FrameSize, *infos)
Break
EndSelect
; \ Framebody ends
FileSeek(0,Location) ; Jump to the end of the frame.
; (if something went wrong nevertheless you are at the right location in the file)
Until Size >= ID3Size ; stop if tag size reached/exceeded
CloseFile(0)
FreeMemory(*infos)
If Len(returntext)>0
ProcedureReturn returntext
Else
ProcedureReturn ""
EndIf
EndIf
EndProcedure
;- DEMO Useage
If OpenWindow(0, 259, 217, 855, 388, "ID3 Tags", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
ListIconGadget(20,5,40,200,300,"MP3 File",180,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
hwnd = ImageGadget(40,220,40,300,300,0,#PB_Image_Border) ; AKJ
ButtonGadget(1,240,10,90,25,"Open MP3") ; AKJ Cater for large fonts
ButtonGadget(2,40,10,90,25,"Select Files")
ButtonGadget(3,140,10,90,25,"Get ID3 Image")
ButtonGadget(4,340,10,140,25,"Extract Selected ID3 Image")
ButtonGadget(5,490,10,140,25,"Extract Selected Lyrics")
EditorGadget(50,530,40,300,300,#PB_Editor_ReadOnly)
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case 1 ; Button gadget
MP3File.s = OpenFileRequester("Select MP3 File", "", "MP3 Files (*.mp3)|*.mp3", 0)
Debug MP3File
If MP3File
GetID3Tag(MP3File,@TagV1,@Tags)
With Tags
Debug "Album: "+\album
Debug "Artist: "+\artist
Debug "Copyright: "+\Copyright
Debug "Genre: "+\genre
Debug "Title: "+\title
Debug "Track: "+\track
Debug "URL: "+\URL
Debug "Year: "+\year
Debug \lyrics
EndWith
If Tags\image
ResizeImage(Tags\image,300,300,#PB_Image_Smooth)
SetGadgetState(40,ImageID(Tags\image))
Else
SetGadgetState(40,0)
EndIf
If Tags\lyrics
SetGadgetText(50,Tags\lyrics)
Else
SetGadgetText(50,"")
EndIf
EndIf
Case 2
mp3files$= OpenFileRequester("Select MP3 File", "", "MP3 Files (*.mp3)|*.mp3", 0,#PB_Requester_MultiSelection)
If mp3files$
ClearGadgetItems(20)
While mp3files$
mp3files$ = NextSelectedFileName()
AddGadgetItem(20,-1,mp3files$)
Wend
EndIf
Case 3
MP3File.s = OpenFileRequester("Select MP3 File", "", "MP3 Files (*.mp3)|*.mp3", 0)
pbimage=ID3GetImage(MP3File)
If pbimage
ResizeImage(pbimage,300,300,#PB_Image_Smooth)
SetGadgetState(40,ImageID(pbimage))
EndIf
Case 4
JPEGFile.s = SaveFileRequester("Save ID3 Tag Image To File", "", "JPEG Files (*.jpg)|*.jpg", 0)
If JPEGFile
If GetExtensionPart(JPEGFile)<> LCase("jpg")
JPEGFile+".jpg"
EndIf
MP3File.s=GetGadgetItemText(20,GetGadgetState(20),0)
If FileSize(MP3File)>0
memorybuffer=ID3GetImageBinaryData(MP3File)
If CreateFile(10,JPEGFile)
WriteData(10,memorybuffer, MemorySize(memorybuffer))
CloseFile(10)
EndIf
EndIf
EndIf
Case 5
textFile.s = SaveFileRequester("Save ID3 Lyrics To File", "", "Text Files (*.txt)|*.txt", 0)
If textFile
If GetExtensionPart(textFile)<> LCase("txt")
textFile+".txt"
EndIf
MP3File.s=GetGadgetItemText(20,GetGadgetState(20),0)
If FileSize(MP3File)>0
text.s=ID3GetSongLyrics(MP3File)
If Len(text)>0
If CreateFile(10,textFile)
WriteData(10,@text, Len(text))
CloseFile(10)
EndIf
EndIf
EndIf
EndIf
Case 20
MP3File.s=GetGadgetItemText(20,GetGadgetState(20),0)
GetID3Tag(MP3File,@TagV1,@Tags)
If Tags\image
ResizeImage(Tags\image,300,300,#PB_Image_Smooth)
SetGadgetState(40,ImageID(Tags\image))
Else
SetGadgetState(40,0)
EndIf
If Tags\lyrics
SetGadgetText(50,Tags\lyrics)
Else
SetGadgetText(50,"")
EndIf
EndSelect
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_CloseWindow
Quit=1
EndSelect
Until Quit=1