Estrarre i TAG ID3v1 e ID3v2 dai file MP3 con le funzioni esterne del API di libmpg123

Da Gambas-it.org - Wikipedia.

La libreria libmpg123 consente, fra l'altro, di estrarre i TAG ID3 da un file MP3.

Con il codice, appresso mostrato, sarà possibile estrarre sia i TAG ID3v1 che i TAG ID3v2 .

E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "libmpg123.so.0.48.1 ".

Library "libmpg123:0.48.1"

 Public Struct mpg123_id3v2
   version As Byte           '   0
   title As Pointer          '   8
   artist As Pointer         '  16
   album As Pointer          '  24
   year As Pointer           '  32
   genre As Pointer          '  40
   comment As Pointer        '  48
   comment_list As Pointer   '  56
   comments As Long          '  64
   text As Pointer           '  72
   texts As Long             '  80
   extra As Pointer          '  88
   extras As Long            '  96
   picture As Pointer        ' 104
   pictures As Long          ' 112
 End Struct
 
 Private Const MPG123_OK As Integer = 0
 Private Const MPG123__ID3 As Integer = 3
 
' int mpg123_init (void)
' Function to initialise the mpg123 library.
Private Extern mpg123_init() As Integer

' mpg123_handle * mpg123_new (const char *decoder, int *error)
' Create a handle with optional choice of decoder (named by a string).
Private Extern mpg123_new(decoder As String, errorI As Pointer) As Pointer

' int mpg123_open (mpg123_handle * mh, const char * path)
' Open and prepare to decode the specified file by filesystem path. This does not open HTTP urls.
Private Extern mpg123_open(mh As Pointer, pathFile As String) As Integer

' const char* mpg123_strerror (mpg123_handle * mh)
' Give string describing what error has occured in the context of handle mh.
Private Extern mpg123_strerror(mh As Pointer) As String

' int mpg123_scan (mpg123_handle * mh)
' Make a full parsing scan of each frame in the file.
Private Extern mpg123_scan(mh As Pointer) As Integer

' int mpg123_meta_check (mpg123_handle * mh)
' Query if there is (new) meta info, be it ID3 or ICY.
Private Extern mpg123_meta_check(mh As Pointer) As Integer

' int mpg123_id3 (mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2)
' Point v1 and v2 to existing data structures wich may change on any next read/decode function call.
Private Extern mpg123_id3(mh As Pointer, v1 As Pointer, v2 As Pointer) As Integer

' int mpg123_close (mpg123_handle * mh)
' Closes the source, if libmpg123 opened it.
Private Extern mpg123_close(mh As Pointer) As Integer

' void mpg123_delete (mpg123_handle * mh)
' Delete handle, mh is either a valid mpg123 handle or NULL.
Private Extern mpg123_delete(mh As Pointer)

' void mpg123_exit (void)
' Function to close down the mpg123 library.
Private Extern mpg123_exit()


Public Sub Main()
 
 Dim filemp3 As String
 Dim mpg, v1, v2 As Pointer
 Dim mt As Integer
  
 filemp3 = "/percorso/del/file.mp3"
 
 mpg123_init()
 mpg = mpg123_new(Null, 0)
 
 If mpg123_open(mpg, filemp3) <> MPG123_OK Then Error.Raise("Errore: " & mpg123_strerror(mpg))
 
 mpg123_scan(mpg)
 mt = mpg123_meta_check(mpg)
 
 Print "File audio: "; filemp3
 
 If (mt And MPG123__ID3) And (mpg123_id3(mpg, VarPtr(v1), VarPtr(v2)) == MPG123_OK) Then
   Print "\n====      ID3v1       ====\n"
   If v1 > 0 Then Stampa_v1(v1)
   
   Print "\n====      ID3v2       ====\n"
   If v2 > 0 Then Stampa_v2(v2)
   
   Print "\n==== ID3v2 Raw frames ===="
   If v2 > 0 Then Stampa_raw_v2(v2)
 Else
   Print "\nNessun TAG trovato !" 
 Endif
 
 
 mpg123_close(mpg)
 mpg123_delete(mpg)
 mpg123_exit()
 
End


Private Procedure Stampa_v1(po As Pointer)
 
 Dim st As Stream
 Dim bb As New Byte[128]
 
 st = Memory po For Read
 
 bb.Read(st, 0, 128)
 
 Print "Titolo:   "; bb.ToString(3, 30)
 Print "Artista:  "; bb.ToString(33, 30)
 Print "Album:    "; bb.ToString(63, 30)
 Print "Anno:     "; bb.ToString(93, 4)
 Print "Commento: "; bb.ToString(97, 30)
 Print "Genere:   "; bb[127]
 
 st.Close
 
End


Private Procedure Stampa_v2(po As Pointer)
 
 Dim i As Integer
 Dim v2 As Mpg123_id3v2
 
 v2 = po
 
 For i = 8 To 48 Step 8
   If Byte@(po + i) == 0 Then Continue 
   Select Case i
     Case 8
       Print "Titolo:   "; String@(Pointer@(v2.title))
     Case 16
       Print "Artista:  "; String@(Pointer@(v2.artist))
     Case 24
       Print "Album:    "; String@(Pointer@(v2.album))
     Case 32
       Print "Anno:     "; String@(Pointer@(v2.year))
     Case 40
       Print "Genere:   "; String@(Pointer@(v2.genre))
     Case 48
       Print "Commento: "; String@(Pointer@(v2.comment))
   End Select
 Next
  
End


Private Procedure Stampa_raw_v2(po As Pointer)
 
 Dim i, c As Integer
 Dim v2 As Mpg123_id3v2
 Dim id As String
 
 v2 = po
 
 For i = 0 To v2.texts - 1
   Print String@(v2.text + (i * 56))
   Print String@(v2.text + (i * 56) + 3)
   Print String@(Pointer@(v2.text + (i * 56) + 32))
 Next
 
 For i = 0 To v2.extras - 1
   Print String@(v2.extra + (i * 56))
   Print String@(v2.extra + (i * 56) + 3), "("; String@(Pointer@(v2.extra + (i * 56) + 8)); ")"
   Print String@(Pointer@(v2.extra + (i * 56) + 32))
 Next
 
 For i = 0 To v2.comments - 1
   Print String@(v2.comment_list + (i * 56) + 3), "(";
   For c = 0 To 2
     Print Chr(Byte@((v2.comment_list + (i * 56)) + c));
   Next
   Print ")"; String@(Pointer@(v2.comment_list + (i * 56) + 8))
   Print String@(Pointer@(v2.comment_list + (i * 56) + 32))
 Next
   
End


Riferimenti