id3tag auslesen mit Image

Anfängerfragen zum Programmieren mit PureBasic.
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

id3tag auslesen mit Image

Beitrag von schleicher »

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 ?

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
Purebasic 5.51
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Re: id3tag auslesen mit Image

Beitrag von Fluid Byte »

Wo genau ist denn das Problem? Du kannst nicht einfach Code posten und sagen "Hier, geht nicht" und dann erwarten das dir jemand das ganze Teil mundgerecht serviert. Ohne Eigeninitiative wirst du nicht weit kommen. Außerdem, solltest du 64bit verwenden kann der Code aufgrund der .l Deklarationen nicht funktionieren. Ausgenommen die Stellen wo der ID3 Header explizit LONG benutzt.
Zuletzt geändert von Fluid Byte am 07.02.2018 21:45, insgesamt 1-mal geändert.
Windows 10 Pro, 64-Bit / Outtakes | Derek
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

Re: id3tag auslesen mit Image

Beitrag von schleicher »

Ich habe mich schon soweit ich konnte damit auseinandergesetzt. Feststellen konnte ich , das die neuen PB- Versionen nur noch in unicode compilieren. Also muss an einigen Stellen z.B. das einfügen von #PB_Ascii hier

Code: Alles auswählen

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, #PB_Ascii) 
      If header$ = "TAG"                              ;  3 chars
        With *infos
          \title     = Trim(PeekS(*mem  +   3, 30, #PB_Ascii))   ; 30 chars
          \artist    = Trim(PeekS(*mem  +  33, 30, #PB_Ascii))   ; 30 chars
          \album     = Trim(PeekS(*mem  +  63, 30, #PB_Ascii))   ; 30 chars
          \year      = Trim(PeekS(*mem  +  93,  4, #PB_Ascii))   ;  4 chars
          ; \Comment   = Trim(PeekS(*mem  +  97, 29, #PB_Ascii))   ; 30 chars
          \track     = Trim(PeekS(*mem  + 126,  1, #PB_Ascii))   ;  1 chars
          \genre     = Trim(PeekS(*mem  + 127,  1, #PB_Ascii))   ;  1 chars
        EndWith
        Result = #True
      EndIf
      FreeMemory(*mem)
    EndIf
    CloseFile(0)
  EndIf
  ProcedureReturn Result
EndProcedure

Aber weiter weiß ich halt nicht. Benutze 32bit.
Purebasic 5.51
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: id3tag auslesen mit Image

Beitrag von DarkSoul »

Ascii ist riskant. ID3-Tags enthalten oftmals UTF8 oder auch UTF16 (beides meist mit BOM im jeweiligen Tag) :wink: .

Musst dich hatl mit dem Debugger durcharbeiten. Kannst jetzt nicht von uns verlangen, dass wir ein ganzes Programm für dich debuggen. :wink:

Ein guter Anfang wäre, es herauszufinden, warum nach dem Öffnen einer MP3 gar nichts passiert (ich hätte jetzt erwartet, dass sie in der Liste erscheint, was sie nicht tut). Also läuft bereits ab OpenFileRequester() was falsch, was zunächst nicht viel mit der Zeichenkodierung zu tun haben dürfte. Demnach dürfte das Parsing des Tags gar nicht erst versucht werden. :wink:

Ich weiß, warum nichts passiert, wenn nur eine Datei ausgewählt wird, aber das verrate ich nicht. Tipp: Die Schleife, die die Auswahl aus dem Requester in die Liste einpflegt, ist fehlerhaft. :mrgreen:

Musst halt üben. Ist noch kein Meister vom Himmel gefallen.
Bild
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: id3tag auslesen mit Image

Beitrag von HeX0R »

Ich hatte das auch mal gebraucht und das ist dabei rausgekommen:

Code: Alles auswählen

; --------------------------------------------------------
; V1.01
; last update 30.06.2021
;
; About:
; ID3 v1.0, v1.1 and v2.3 reader
;
; Author:   Joakim L. Christiansen
; Homepage: http://www.myhome.no/jlc_software
; Original-Source: http://www.purebasic.fr/english/viewtopic.php?p=162544
;
; Note:
; v2.3 reader is based on ebs's version from the PB Forum:
; http://www.purebasic.fr/english/viewtopic.php?t=6935
;
; Note2:
; Switched to module version by HeX0R 20.12.2015, used original code from here:
; http://www.purebasic.fr/english/viewtopic.php?p=147211
; --------------------------------------------------------
DeclareModule ID3TAG

	Declare LoadMP3(FileName.s)
	Declare.s GetTitle()
	Declare.s GetArtist()
	Declare.s GetGenre()
	Declare.s GetYear()
	Declare.i GetImage()
	Declare.s GetAlbum()
	Declare.s GetComment()
	Declare.i GetSongNumber()

EndDeclareModule


Module ID3TAG
	EnableExplicit
	
	UseJPEGImageDecoder()
	UsePNGImageDecoder()

	Structure _ID3TAGS_
		Title.s
		Artist.s
		Genre.s
		Album.s
		SongNr.i
		Year.s
		Comment.s
		ImageID.i
	EndStructure
	
	Structure _ID3TAGV31_
		TAG.a[3]
		Title.a[30]
		Artist.a[30]
		Album.a[30]
		Year.a[4]
		Comment.b[30]
		Genre.a
	EndStructure
	
	Structure _ID3TAGV32HEADER_
		Identifier.a[3]
		Version.a[2]
		flags.a
		size.b[4]
	EndStructure
	
	Structure _ID3TAGV32FRAMES_
		FrameID.a[4]
		Size.l
		Flags.a[2]
		Encoding.a
		*Data
	EndStructure

	Global ID3TAGs._ID3TAGS_
	Global Dim Genre.s(125)
		
	Procedure.l SwapLong(Value.l)
		!MOV Eax, [p.v_Value]
		!BSWAP Eax
		ProcedureReturn
	EndProcedure
	
	Procedure LoadMP3(FileName.s)
		;Load MP3 and read all the ID3 Tags
		Protected FID.i, FrameID$, Size.i, FrameSize.i, EndPosition.i, Pos.i, Add.i, *Buffer, i.i, FrameText$, Encoding, Result, PosNow.i
		Protected *ID3V11._ID3TAGV31_, *ID3V23H._ID3TAGV32HEADER_, *ID3V23F._ID3TAGV32FRAMES_

		If Genre(0) = ""
			Restore GENRES
			For i = 0 To 125
				Read.s Genre(i)
			Next i
		EndIf
		
		FID = ReadFile(#PB_Any, FileName)
		If FID
			;we will put the whole file into the memory buffer
			*Buffer = AllocateMemory(Lof(FID))
			If *Buffer
			
				;clear TAGs
				ID3TAGs\Artist  = ""
				ID3TAGs\Title   = ""
				ID3TAGs\Genre   = ""
				ID3TAGs\Year    = ""
				ID3TAGs\Album   = ""
				ID3TAGs\Comment = ""
				ID3TAGs\SongNr  = 0
				If ID3TAGs\ImageID And IsImage(ID3TAGs\ImageID)
					FreeImage(ID3TAGs\ImageID)
					ID3TAGs\ImageID = 0
				EndIf
				
				ReadData(FID, *Buffer, Lof(FID))
				*ID3V23H = *Buffer
				;Check for ID3v2 TAGs
				If PeekS(*ID3V23H + OffsetOf(_ID3TAGV32HEADER_\Identifier), SizeOf(_ID3TAGV32HEADER_\Identifier), #PB_Ascii) = "ID3" And *ID3V23H\Version[0] = 3
					Result   = #True
					Size     = 0
					For i = 3 To 0 Step - 1
						Size + ((*ID3V23H\Size[3 - i] & $7F) << (7 * i))
					Next i
					PosNow = SizeOf(_ID3TAGV32HEADER_)

					Repeat
						*ID3V23F = *Buffer + PosNow
						FrameID$ = PeekS(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\FrameID), SizeOf(_ID3TAGV32FRAMES_\FrameID), #PB_Ascii)
						If FrameID$ = ""
							Break
						EndIf

						FrameSize = *ID3V23F\Size & $FFFFFFFF
						FrameSize = SwapLong(FrameSize)
						EndPosition + FrameSize

						
						Encoding = #PB_Ascii
						Add      = 1
						If *ID3V23F\Encoding = 1
							Encoding = #PB_UTF16
							Add      = 2
						EndIf

						FrameSize - 1
						If Left(LCase(FrameID$), 1) = "t"
							If PeekW(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data)) & $FFFF = $FFFE Or PeekW(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data)) & $FFFF = $FEFF
								;unicode BOM
								FrameText$ = PeekS(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data) + 2, (FrameSize / Add) - 1, #PB_UTF16)
							Else
								FrameText$ = PeekS(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data), FrameSize / Add, Encoding)
							EndIf
						ElseIf LCase(FrameID$) = "comm"
							If PeekW(*ID3V23F + 3 + OffsetOf(_ID3TAGV32FRAMES_\Data)) & $FFFF = $FFFE Or PeekW(*ID3V23F + 3 + OffsetOf(_ID3TAGV32FRAMES_\Data)) & $FFFF = $FEFF
								;unicode BOM
								FrameText$ = PeekS(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data) + 5, (FrameSize / Add) - 4, #PB_UTF16)
							Else
								FrameText$ = PeekS(*ID3V23F + 3 + OffsetOf(_ID3TAGV32FRAMES_\Data), FrameSize / Add, Encoding)
							EndIf
						EndIf
						
						Select LCase(FrameID$)
							Case "tit2"
								ID3TAGs\Title   = FrameText$
							Case "tpe1"
								ID3TAGs\Artist  = FrameText$
							Case "tcon"
								ID3TAGs\Genre   = FrameText$
							Case "tyer"
								ID3TAGs\Year    = FrameText$
							Case "talb"
								ID3TAGs\Album   = FrameText$
							Case "comm"
								ID3TAGs\Comment = FrameText$
							Case "apic"
								;Mime Type, not important
								Pos = MemoryStringLength(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data), #PB_UTF8 | #PB_ByteLength)
								;Pos + Add
								Pos + 1 ;<- 0 Byte
								If PeekB(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data) + Pos) = $03 ;<- $03 = Cover (front)
									Pos + 1
									Pos + (MemoryStringLength(*ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data) + Pos, Encoding) * Add) ;<- Description, also not important.
									Pos + Add
									ID3TAGs\ImageID = CatchImage(#PB_Any, *ID3V23F + OffsetOf(_ID3TAGV32FRAMES_\Data) + Pos, FrameSize - Pos)
								EndIf
								;more?
								;no, not for my needs
						EndSelect
						PosNow + FrameSize + OffsetOf(_ID3TAGV32FRAMES_\Data)
					Until EndPosition >= Size
				EndIf
				;Check for ID3v1 and/or ID3v1.1 TAGs
				*ID3V11 = *Buffer + MemorySize(*Buffer) - 128
				If PeekS(*ID3V11 + OffsetOf(_ID3TAGV31_\TAG), 3, #PB_Ascii) = "TAG"
					Result = #True
					If ID3TAGs\Title = ""
						ID3TAGs\Title = PeekS(*ID3V11 + OffsetOf(_ID3TAGV31_\Title), SizeOf(_ID3TAGV31_\Title), #PB_Ascii)
					EndIf
					If ID3TAGs\Artist = ""
						ID3TAGs\Artist = PeekS(*ID3V11 + OffsetOf(_ID3TAGV31_\Artist), SizeOf(_ID3TAGV31_\Artist), #PB_Ascii)
					EndIf
					If ID3TAGs\Album = ""
						ID3TAGs\Album = PeekS(*ID3V11 + OffsetOf(_ID3TAGV31_\Album), SizeOf(_ID3TAGV31_\Album), #PB_Ascii)
					EndIf
					If ID3TAGs\Year = ""
						ID3TAGs\Year = PeekS(*ID3V11 + OffsetOf(_ID3TAGV31_\Year), SizeOf(_ID3TAGV31_\Year), #PB_Ascii)
					EndIf
					If *ID3V11\Genre >= 0 And *ID3V11\Genre <= 125 And ID3TAGs\Genre = ""
						ID3TAGs\Genre = Genre(*ID3V11\Genre)
					EndIf
					If ID3TAGs\Comment = ""
						If *ID3V11\Comment[28] = 0
							;ID3v1.1!
							ID3TAGs\SongNr = *ID3V11\Comment[29]
							ID3TAGs\Comment = PeekS(*ID3V11 + OffsetOf(_ID3TAGV31_\Comment), 28, #PB_Ascii)
						Else
							ID3TAGs\SongNr = 0
							ID3TAGs\Comment = PeekS(*ID3V11 + OffsetOf(_ID3TAGV31_\Comment), SizeOf(_ID3TAGV31_\Comment), #PB_Ascii)
						EndIf
					EndIf
				EndIf
				FreeMemory(*Buffer)
			EndIf
			CloseFile(FID)
		EndIf
		
		ProcedureReturn Result
	EndProcedure
	
	Procedure.s GetTitle()
		ProcedureReturn ID3TAGs\Title
	EndProcedure
	
	Procedure.s GetArtist()
		ProcedureReturn ID3TAGs\Artist
	EndProcedure
	
	Procedure.s GetGenre()
		ProcedureReturn ID3TAGs\Genre
	EndProcedure
	
	Procedure.s GetYear()
		ProcedureReturn ID3TAGs\Year
	EndProcedure
	
	Procedure GetImage()
		ProcedureReturn ID3TAGs\ImageID
	EndProcedure
	
	Procedure.s GetAlbum()
		ProcedureReturn ID3TAGs\Album
	EndProcedure
	
	Procedure.s GetComment()
		ProcedureReturn ID3TAGs\Comment
	EndProcedure
	
	Procedure.i GetSongNumber()
		ProcedureReturn ID3TAGs\SongNr
	EndProcedure
	
	DataSection
		GENRES:
		Data.s "Blues",           "Classic Rock", "Country",        "Dance",             "Disco",            "Funk",             "Grunge",           "Hip-Hop"
		Data.s "Jazz",            "Metal",        "New Age",        "Oldies",            "Other",            "Pop",              "R&B",              "Rap"
		Data.s "Reggae",          "Rock",         "Techno",         "Industrial",        "Alternative",      "Ska",              "Death Metal",      "Pranks"
		Data.s "Soundtrack",      "Euro-Techno",  "Ambient",        "Trip-Hop",          "Vocal",            "Jazz+Funk",        "Fusion",           "Trance"
		Data.s "Classical",       "Instrumental", "Acid",           "House",             "Game",             "Sound Clip",       "Gospel",           "Noise"
		Data.s "AlternRock",      "Bass",         "Soul",           "Punk",              "Space",            "Meditative",       "Instrumental Pop", "Instrumental Rock"
		Data.s "Ethnic",          "Gothic",       "Darkwave",       "Techno-Industrial", "Electronic",       "Pop-Folk",         "Eurodance",        "Dream"
		Data.s "Southern Rock",   "Comedy",       "Cult",           "Gangsta",           "Top 40",           "Christian Rap",    "PopFunk",          "Jungle"
		Data.s "Native American", "Cabaret",      "New Wave",       "Psychadelic",       "Rave",             "Showtunes",        "Trailer",          "Lo-Fi"
		Data.s "Tribal",          "Acid Punk",    "Acid Jazz",      "Polka",             "Retro",            "Musical",          "Rock & Roll",      "Hard Rock"
		Data.s "Folk",            "Folk-Rock",    "National Folk",  "Swing",             "Fast Fusion",      "Bebob",            "Latin",            "Revival"
		Data.s "Celtic",          "Bluegrass",    "Avantgarde",     "Gothic Rock",       "Progressive Rock", "Psychedelic Rock", "Symphonic Rock",   "Slow Rock"
		Data.s "Big Band",        "Chorus",       "Easy Listening", "Acoustic",          "Humour",           "Speech",           "Chanson",          "Opera"
		Data.s "Chamber Music",   "Sonata",       "Symphony",       "Booty Bass",        "Primus",           "Porn Groove",      "Satire",           "Slow Jam"
		Data.s "Club",            "Tango",        "Samba",          "Folklore",          "Ballad",           "Power Ballad",     "Rhythmic Soul",    "Freestyle"
		Data.s "Duet",            "Punk Rock",    "Drum Solo",      "A capella",         "Euro-House",       "Dance Hall"
		Data.s ""
	EndDataSection

EndModule

;-Example
CompilerIf #PB_Compiler_IsMainFile
	
	Define ImageID.i
	
	ID3TAG::LoadMP3(OpenFileRequester("Open mp3","","Mp3 (*.mp3)|*.mp3",0))
	
	Debug "Artist: " + ID3TAG::GetArtist()
	Debug "Title: " + ID3TAG::GetTitle()
	Debug "Genre: " + ID3TAG::GetGenre()
	Debug "Year: " + ID3TAG::GetYear()
	Debug ""
	Debug "From Album: " + ID3TAG::GetAlbum()
	Debug "Song Nr.: " + ID3TAG::GetSongNumber()
	Debug "Comment:"
	Debug ID3TAG::GetComment()
	
	ImageID = ID3TAG::GetImage()
	If ImageID
		OpenWindow(0, 0, 0, ImageWidth(ImageID) + 10, ImageHeight(ImageID) + 10, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		ImageGadget(0, 0, 0, ImageWidth(ImageID), ImageHeight(ImageID), ImageID(ImageID))
		While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
	EndIf
	
CompilerEndIf
Zuletzt geändert von HeX0R am 30.06.2021 09:30, insgesamt 1-mal geändert.
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Re: id3tag auslesen mit Image

Beitrag von Fluid Byte »

Funktioniert einwandfrei und ist 64bit-kompatibel. Lecker, gleich mal klauen und abspeichern :D
Windows 10 Pro, 64-Bit / Outtakes | Derek
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

Re: id3tag auslesen mit Image

Beitrag von schleicher »

Danke für den Code . Ein plaar kleine Änderungen und es erfüllt perfekt, das was es soll. :allright:
Purebasic 5.51
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: id3tag auslesen mit Image

Beitrag von ts-soft »

Hier noch meine Version, wegen der Vollständigkeit:
http://www.purebasic.fr/english/viewtop ... 32#p420732
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Franky_FR
Beiträge: 53
Registriert: 08.05.2019 10:06

Re: id3tag auslesen mit Image

Beitrag von Franky_FR »

HeX0R hat geschrieben: 07.02.2018 22:06 Ich hatte das auch mal gebraucht und das ist dabei rausgekommen:
So ein Mist, funktioniert mit PB x64 5.73 wunderbar, nur die Coverbilder werden nicht angezeigt: genau das, was ich gerade brauche.
Hat sich irgendwas geändert ?
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: id3tag auslesen mit Image

Beitrag von HeX0R »

Hab's lange nicht mehr gebraucht, aber ein kurzer Test zeigte jetzt keine Auffälligkeiten.
Um welche mp3 geht's denn, kannst Du die irgendwo hochladen?
Antworten