Page 3 sur 3

Re: Lire et ecrire les tags des fichiers mp3

Publié : mer. 19/janv./2011 16:44
par Parole De JOJO
je n'ai pas reussi
est ce que quelqu'un pourrait m'aider s'il vous plait?

en fait je bugge surtout sur l'image et la lecture et l'ecriture de la taille exacte du tag

Re: Lire et ecrire les tags des fichiers mp3

Publié : mar. 14/juin/2016 9:51
par Zorro
revoici ma lib Tag_mp3

je propose 6 procedures :


procedure read_tag_mp3(file$); lit le tag ID3 V1 (celui qui est en fin de fichier)

procedure read_tag_mp3v2(file$); lit le tag ID3 V2 (celui qui est en debut de fichier)
je conseille de les utiliser toutes les 2...
car le plus courant reste le ID3 V1
Le tag ID3V2 peut contenir une image,(pochette de disque) ;si c'est le cas
l'image est sauvé avec comme nom "temp.jpg" a coté de l'emplacement du prg
(sauvegardez le code avant de lancer la première fois) , sinon l'image risque de s'écrire dans le dossier compiler


procedure write_tag_mp3(file$,titre$,interprete$,album$,annee$,commentaire$,numero_piste$,genre_musical$)
;Ecrit le Tag format ID3V1 (celui de fin de fichier)

procedure write_tag_mp3v2(file$,album$,composeur$,interprete$,titre$,copyright$,annee$,numero_piste$,lien$,commentaire$, genre$, longueur$,path_image$) ;

;Ecrit le Tag format ID3V2 (celui du debut de fichier)


cette procedure supprime automatiquement tout tag ID3V2 , et en refait un a neuf !
elle gere l'incorporation d'image !

procedure delete_tagV1(file$) ; supprime le Tag ID3V1

procedure delete_tagV2(file$) ; supprime le tag ID3V2 ; cette procedure est appelé
par la procedure d'ecriture de tag ID3V2 , si un tel tag existe dans le fichier..


vous pouvez lancer le code tel quel et choisir un Mp3 pour voir

Code : Tout sélectionner

; By Dobro
; créé en pure basic 4.51
;***********************************************
;Titre  :*lecture_ecriture_tag_mp3
;Auteur  : Dobro
;Date  :19/08/2015
;Heure  :20:13:41
;Version Purebasic :  PureBasic 5.31 (Windows - x86)
;Version de l'editeur :EPB V2.62
; Libairies necessaire : Aucune 
;***********************************************

Declare.S read_tag_mp3(file$)
Declare.S read_tag_mp3v2(file$)
Declare.l to_little_indian(valeur.l)
; ***** write_tag_mp3(file$,title$,interpret$,album$,year$,comment$,piste_number$,style_musical$) ****
Declare write_tag_mp3(file$,titre$,interprete$,album$,annee$,commentaire$,numero_piste$,genre_musical$)
; ********************************************************************************************************
; **** write_tag_mp3v2(file$,album$,composer$,interpret$,title$,copyright$,year$,piste_number$,lien$,comment$, style_music$, music_long$,path_image$)
Declare  write_tag_mp3v2(file$,album$,composeur$,interprete$,titre$,copyright$,annee$,numero_piste$,lien$,commentaire$, genre$, longueur$,image$)
Declare delete_tagV1(file$)
Declare delete_tagV2(file$)
Declare to_little_indian_w(valeur.l)
Enumeration
	; enumeration Tag MP3 ID3Vx
	#file
	#image_file
	#file2
	#file_image
EndEnumeration

file$=OpenFileRequester("ouvrir un mp3","C:\","*.mp3",1)
	
	
	; **************** exemple d'ecriture ID3V1 ****************************²
	; 
	; titre$="D'ont play that song"
	; interprete$="Adriano Celentano"
	; album$="Adriano Celentano"
	; annee$="1975"²
	; commentaire$="belle reprise"
	; numero_piste$="1"
	; genre_musical$="1"
	; ;
	; write_tag_mp3(file$,titre$,interprete$,album$,annee$,commentaire$,numero_piste$,genre_musical$)
	; ********************************************************************
	;;²
	; ceci ouvre le Tag ID3 v1 en lecture
	retour$=read_tag_mp3(file$)
	Debug "************* ID3 V1 *********************"
	Debug "titre= "+StringField(retour$,1,",")
	Debug "interprete= "+StringField(retour$,2,",")
	Debug "album= "+StringField(retour$,3,",")
	Debug "année= "+StringField(retour$,4,",")
	Debug "commentaires= "+StringField(retour$,5,",")
	Debug "numero piste= "+StringField(retour$,6,",")
	Debug "genre musical= "+StringField(retour$,7,",")
	Debug ""
	Debug ""
	Debug ""
	Debug ""
	;******************************exemple  ecriture Tag ID3 v2 *************************************
	; ; ; ; 
	; album$="le bel Album"
	; composeur$="le compositeur"
	; interprete$="Mr l'interprete"
	; titre$="Le titre qui tue sa race"
	; copyright$="@ Dobro"
	; annee$="2010"
	; numero_piste$="8"
	; lien$="Http://michel.dobro.free.fr/"
	; commentaire$="un petit exemple fait en pure Basic"
	; genre$="Country Music"
	; longueur$="88888"
	; image$="C:\Dobro\Mes_Photos\Sv101108.jpg" ; mettre ici le chemin vers une images valide !!!
	; write_tag_mp3v2(file$,album$,composeur$,interprete$,titre$,copyright$,annee$,numero_piste$,lien$,commentaire$, genre$, longueur$,image$)
	; ; 
	;**************************************************************************************²²²²²
	; ceci ouvre le Tag ID3 v2 en lecture
	retour$=read_tag_mp3v2(file$) 
	Debug "************* ID3 V2 *********************"
	Debug "album= "+StringField(retour$,1,",")
	Debug "compositeur= "+StringField(retour$,2,",")
	Debug "interprete= "+StringField(retour$,3,",") 
	Debug "titre= "+StringField(retour$,4,",")
	Debug "Copyright= "+StringField(retour$,5,",") 
	Debug "année= "+StringField(retour$,6,",")
	Debug "numero piste= "+StringField(retour$,7,",")
	Debug "Lien= "+StringField(retour$,8,",")
	Debug "commentaires= "+StringField(retour$,9,",") 
	Debug "genre musical= "+StringField(retour$,10,",")
	Debug "Longueur= "+StringField(retour$,11,",")
	
	End
	
	; ********************** Zone des Procedures ******************************************
	
	Procedure.S read_tag_mp3(file$)
		; By Dobro 
		; purebasic 4.51
		; lecture des tag MP3 id3V1
		
		If  OpenFile(#file,file$)
			FileSeek(#file, Lof(#file)-128) ; ruse de guerre , on saute a la fin du fichier , puis on recul de 128 octets !
			For i=1 To 3
				tag$= tag$+Chr(ReadCharacter(#file) ) 
			Next i
			; determine si le tag Mp3 existe
			If tag$="TAG"
				tag_present=#true
				Debug "Le tag est présent"
			Else
				tag_present=#False
				Debug "Le tag est absent"
				Goto suite: 
			EndIf
			; ********** recuperation du titre **************************** ; Grab Title
			For i=1 To 30
				titre$= titre$+Chr(ReadCharacter(#file) )
			Next i 
			;*************************************************************
			;**************** recperation de l'interprete ***************** ; Grab name of Singer
			For i=1 To 30
				interprete$= interprete$+Chr(ReadCharacter(#file) )
			Next i
			; ***********************************************************
			; ****************** recuperation de l'album *********************** ; Grab name of Album
			For i=1 To 30
				album$= album$+Chr(ReadCharacter(#file) )
			Next i
			; *****************************************************************
			;***************** recuperation de l'année ************************** ; Grab Year
			For i=1 To 4
				annee$= annee$+Chr(ReadCharacter(#file) )
			Next i
			; *****************************************************************
			; ******************** recuperation des commentaires ***************** ; Grab Comment
			For i=1 To 28
				commentaire$= commentaire$+Chr(ReadCharacter(#file) )
			Next i
			; ********************************************************************
			; ******************** recuperation octet nul *****************
			For i=1 To 1
				nul$= nul$+Chr(ReadCharacter(#file) )
			Next i
			; ********************************************************************
			; ******************** recuperation numero de piste***************** ;Grab piste number
			For i=1 To 1
				numero_piste$= Str(ReadCharacter(#file) )
			Next i
			; ********************************************************************
			; ************************ recuperation du genre musicale ****************** ; Grab Style Music (pop,rock,techno...etc)
			For i=1 To 1
				genre_musical$=  Str(ReadCharacter(#file)  )
			Next i
			; ***************************************************************************
			suite:
		CloseFile(#file)
		Restore  genre:
		For i=0 To Val(genre_musical$)
			Read.S genre.S
			if genre.S="-1"
				genre.S="UnNow"
				break
			endif
		Next 
	Else 
		ProcedureReturn "Erreur"
	EndIf
	
	retour$=titre$+","+interprete$+","+album$+","+annee$+","+commentaire$+","+Str(Val( numero_piste$))+","+genre.S
	ProcedureReturn retour$
	DataSection 
		genre:
		Data.S "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal" 
		Data.S "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial" 
		Data.S "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk" 
		Data.S "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise" 
		Data.S "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic" 
		Data.S "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta" 
		Data.S "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes" 
		Data.S "Trailer", "Lo-Fi", "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", "Celtic", "Bluegrass" 
		Data.S "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic" 
		Data.S "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove" 
		Data.S "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle" 
		Data.S "Duet", "Punk Rock", "Drum Solo", "Acapella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "indie", "Brit Pop", "Negerpunk" 
		Data.S "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Comteporary Christian" 
		Data.S "Christian Rock", "Merengue", "Salsa", "Trash Metal", "Anime", "JPop", "Synth Pop" ,"-1"
	EndDataSection 
EndProcedure

Procedure.S read_tag_mp3v2(file$)  ; Read Mp3Tag
	; By Dobro 
	; purebasic 4.51
	; lecture des tag MP3 id3V2
	
	If OpenFile(#file,file$)
		For i=0 To 2
			tag$= tag$+Chr(ReadCharacter(#file) ) 
		Next i
		; determine si le tag Mp3 V2 existe
		If tag$="ID3"
			tag_present=#true
			Debug "Le tag  V2 est présent"
		Else
			tag_present=#False
			Debug "Le tag V2 est absent"
		CloseFile(#file)
		ProcedureReturn ""
	EndIf
	version$= Str(ReadByte(#file) ) ;$03 majeur version
	ReadByte(#file)  ; mineure version 
	flag$= Str(ReadByte(#file) )
	; x1=ReadByte(#file) 
	; x2=ReadByte(#file) 
	; x3=ReadByte(#file) 
	; x4=ReadByte(#file) 
	; long_id3=((x3 * Pow(128,3)) + (x2 *Pow(128,2)) + (x1 * Pow(128,1)) + (x0 * Pow(128,0)))-10
	long_id3=ReadLong(#file)
	long_id3= to_little_indian(long_id3)-10
	Repeat
		tag$=""
		; Tag Frame
		FileSeek(#file,Loc(#file)-3) ; ceci sert a ne pas louper de frames !! ne pas toucher !
		For i=1 To 4
			tag$=tag$+Chr(ReadCharacter(#file))
		Next i
		Select tag$ 
			Case "TALB" ; Album  ; Validé
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file)
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				album$=album$+Chr(ReadCharacter(#file))
			Next i
			Case "TCOM" ; compositeur
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file)
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				composeur$=composeur$+Chr(ReadCharacter(#file))
			Next i
			Case "TPE1" ; interprete ; Validé
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file)
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				interprete$=interprete$+Chr(ReadCharacter(#file))
			Next i
			Case "TIT2" ; titre ; Validé
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file)
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				titre$=titre$+Chr(ReadCharacter(#file))
			Next i
			Case "TCOP"
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file)
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				copyright$=copyright$+Chr(ReadCharacter(#file))
			Next i
			Case "TYER" ; Validé
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-1
			For i=1 To 3
				nul=ReadByte(#file) ; 3Xnull
			Next i
			For i=1 To long_frame 
				annee$=annee$+Chr(ReadCharacter(#file))
			Next i
			Case "TRCK" ; Validé
			For i=1 To 8
				numero_piste$=Chr(ReadCharacter(#file))
			Next i 
			Case "WXXX"
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file)
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				lien$=lien$+Chr(ReadCharacter(#file))
			Next i
			Case "COMM"  ; Validé
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-10
			null=ReadLong(#file) ; ?
			null=ReadLong(#file) ; ?
			null=ReadLong(#file) ; ?
			For i=1 To long_frame
				commentaire$=commentaire$+Chr(ReadCharacter(#file))
			Next i
			Case "TCON"
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file)
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				genre$=genre$+Chr(ReadCharacter(#file))
			Next i
			Case "TLEN"
			; long_frame
			long_frame=ReadLong(#file)   
			long_frame= to_little_indian(long_frame)-3
			nul=ReadByte(#file); null
			fin_entete_frame=ReadLong(#file)
			For i=1 To long_frame
				longueur$=longueur$+Chr(ReadCharacter(#file))
			Next i
			
			Case "APIC" ; une image est presente  
			; long_frame 
			For i=1 To 13
				ReadByte(#file)
			Next i
			; recupe le type d'image
			For i=1 To 3
				type_image$=type_image$+Chr(ReadCharacter(#file))
			Next i
			; saute 3 x0 avant debut image
			For i=1 To 3
				ReadByte(#file)
			Next i
			; ici debut image
			If type_image$="jpg" Or type_image$="jpe"
				;;;;;path$=PathRequester("ou mettre l'image ?",GetCurrentDirectory())
				OpenFile(#image_file,path$+"temp.jpg")
					While(tt.w <>$00D9) ;;;;;and (tt.w <>$00D8)
						tt.w=ReadWord(#file)
						WriteWord(#image_file,tt.w) 
					Wend
				EndIf 
				Debug "une image du nom de (Temp.jpg) a été sauvée....."
				RunProgram(path$+"temp.jpg")
			CloseFile(#image_file)
		EndSelect 
		pointeur.q=Loc(#file)
	Until pointeur>long_id3
Else
	ProcedureReturn "Erreur"
EndIf
retour$=album$+","+composeur$+","+interprete$+","+titre$+","+copyright$+","+annee$+","+numero_piste$+","+lien$+","+commentaire$+","+ genre$+","+ longueur$
ProcedureReturn retour$
EndProcedure

Procedure write_tag_mp3v2(file$,album$,composeur$,interprete$,titre$,copyright$,annee$,numero_piste$,lien$,commentaire$, genre$, longueur$,image$)
	;
	; By Dobro 
	; purebasic 4.51
	; ecriture des tag MP3 id3V2 
	;
	; **** efface le tag id3v2 s'il existe  ********************
	delete_tagV2(file$) ; efface l'ancien tag ID3V2    
	; *********************************************************  
	;
	; OpenFile(#file2,file$)
	If ReadFile(#file2, file$)<>0
		Size = FileSize(file$)
		*Buffer = AllocateMemory(Size) 
		If *Buffer
			ReadData(#file2,*Buffer, Size)
		CloseFile(#file2)
		; le fichier est dans  *Buffer
	EndIf
EndIf
If OpenFile(#file,file$)
	WriteByte(#file,Asc("I"))
	WriteByte(#file,Asc("D"))
	WriteByte(#file,Asc("3"))
	WriteByte(#file,$03)  ;$03
	WriteLong(#file,$0)  ; 0,0,0,0
	WriteWord(#file,$0)  ;ne pas oublier d'ajouter ça a la fin !!! (longueur de l'entete)
	
	If album$<>"" 
		tag_frame$="TALB" ; ici nikel !! 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(album$)*2)+3 :compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		;WriteLong(#file,long.l) ; long du champ
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		;
		For i=1 To Len(album$)
			car$=Mid(album$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If composeur$<>"" 
		tag_frame$="TCOM" ; ici nikel !! 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(composeur$)*2)+3:compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		; WriteLong(#file,long.l) ; long du champ
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		;
		For i=1 To Len(composeur$)
			car$=Mid(composeur$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If interprete$<>"" 
		tag_frame$="TPE1" ; ici nikel !! 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(interprete$)*2)+3:compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		; WriteLong(#file,long.l) ; long du champ
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		;
		For i=1 To Len(interprete$)
			car$=Mid(interprete$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If titre$<>"" 
		tag_frame$="TIT2" ; 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(titre$)*2)+3:compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		For i=1 To Len(titre$)
			car$=Mid(titre$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	
	If copyright$<>"" 
		tag_frame$="TCOP" ; 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(copyright$)*2)+3:compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		; WriteLong(#file,long.l) ; long du champ
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		;
		For i=1 To Len(copyright$)
			car$=Mid(copyright$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If annee$<>"" 
		tag_frame$="TYER" ; 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=5:compteur_long.l=compteur_long.l+long
		WriteByte(#file,$0)
		WriteByte(#file,$0)
		WriteByte(#file,$0)
		WriteByte(#file,$5) 
		For i=1 To 3
			WriteByte(#file,$0) ; null
		Next i
		;
		For i=1 To 4
			car$=Mid(annee$,i,1)
			WriteCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If numero_piste$<>"" 
		tag_frame$="TRCK" ; 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=8:compteur_long.l=compteur_long.l+long 
		WriteLong(#file,$8) 
		If Len(numero_piste$)<4
			numero_piste$=RSet(numero_piste$,4,"0")
		EndIf
		For i=1 To Len(numero_piste$)
			car$=Mid(numero_piste$,i,1)
			WriteCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If commentaire$<>"" 
		tag_frame$="COMM" ; 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(commentaire$)*2)+10 :compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		WriteLong(#file,$0) ; ?
		WriteLong(#file,$0) ; ?
		WriteLong(#file,$0) ; ?
		;
		For i=1 To Len(commentaire$)
			car$=Mid(commentaire$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If lien$<>"" 
		tag_frame$="WXXX" ; 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(lien$)*2)+3:compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		; WriteLong(#file,long.l) ; long du champ
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		;
		For i=1 To Len(lien$)
			car$=Mid(lien$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	If genre$<>"" 
		tag_frame$="TCON" ; 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		long.l=(Len(genre$)*2)+3:compteur_long.l=compteur_long.l+long
		to_little_indian_w(long.l)
		; WriteLong(#file,long.l) ; long du champ
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		;
		For i=1 To Len(genre$)
			car$=Mid(genre$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	
	If longueur$<>"" 
		tag_frame$="TLEN" 
		For i=1 To 4
			car$=Mid(tag_frame$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i 
		long.l=(Len(longueur$)*2)+3:compteur_long.l=compteur_long.l+long
		total.S=Hex(long.l) 
		If Len(total.S)<8
			total.S= RSet(total.S, 8,"0") 
		EndIf 
		octet1.S=Mid(total.S,1,2) 
		octet2.S=Mid(total.S,3,2)
		octet3.S=Mid(total.S,5,2)
		octet4.S=Mid(total.S,7,2) 
		WriteByte(#file,Val("$"+octet1.S))
		WriteByte(#file,Val("$"+octet2.S))
		WriteByte(#file,Val("$"+octet3.S))
		WriteByte(#file,Val("$"+octet4.S)) 
		WriteByte(#file,$0) ; null
		; ecriture fin champ
		WriteByte(#file,$0)
		WriteByte(#file,$1)
		WriteByte(#file,$FF)
		WriteByte(#file,$FE)
		;
		For i=1 To Len(longueur$)
			car$=Mid(longueur$,i,1)
			WriteUnicodeCharacter(#file,Asc(car$)) 
		Next i 
	EndIf
	
	If image$<>"" 
		If ReadFile(#file_image, image$)<>0
			Size = FileSize(image$)
			*Buffer_image = AllocateMemory(Size) 
			If *Buffer_image
				ReadData(#file_image,*Buffer_image, Size)
			CloseFile(#file_image)
			; le fichier est dans  *Buffer_image
		EndIf
	EndIf 
	tag_frame$="APIC" 
	For i=1 To 4
		car$=Mid(tag_frame$,i,1)
		WriteByte(#file,Asc(car$)) 
	Next i 
	long.l=Size+3:compteur_long.l=compteur_long.l+long
	total.S=Hex(long.l) 
	If Len(total.S)<8
		total.S= RSet(total.S, 8,"0") 
	EndIf 
	octet1.S=Mid(total.S,1,2) 
	octet2.S=Mid(total.S,3,2)
	octet3.S=Mid(total.S,5,2)
	octet4.S=Mid(total.S,7,2) 
	WriteByte(#file,Val("$"+octet1.S))
	WriteByte(#file,Val("$"+octet2.S))
	WriteByte(#file,Val("$"+octet3.S))
	WriteByte(#file,Val("$"+octet4.S)) 
	
	WriteByte(#file,$0) ; null
	WriteByte(#file,$0) ; null
	WriteByte(#file,$0) ; null 
	For i=1 To Len("image/jpeg")
		car$=Mid("image/jpeg",i,1)
		WriteCharacter(#file,Asc(car$)) 
	Next i 
	; ecriture fin champ
	WriteByte(#file,$0) ; fin de chaine
	WriteByte(#file,$03) ; type image ($12=illustration) 
	;{ type d'images possible
	; $00  Other
	; $01  32x32 pixels 'file icon' (PNG only)
	; $02  Other file icon
	; $03  Cover (front)
	; $04  Cover (back)
	; $05  Leaflet page
	; $06  Media (e.g. label side of CD)
	; $07  Lead artist/Lead performer/soloist
	; $08  artist/performer
	; $09  Conductor
	; $0A  Band/Orchestra
	; $0B  Composer
	; $0C  Lyricist/text writer
	; $0D  Recording Location
	; $0E  During Recording
	; $0F  During performance
	; $10  Movie/video screen capture
	; $11  A bright coloured fish
	; $12  Illustration
	; $13  Band/artist logotype
	; $14  Publisher/Studio logotype
	;}
	WriteByte(#file,$0) ; encodage ?
	;ajoute l'image
	If *Buffer_image
		WriteData(#file,*Buffer_image, Size)
		FreeMemory(*Buffer_image) 
	EndIf
EndIf
; *********************************************************************
; *********************************************************************
; ********************************************************************* 
; *********************************************************************
; on ecrit le fichier a la suite de l'entete ID3    
If *Buffer
	WriteData(#file,*Buffer, Size)
	FreeMemory(*Buffer) 
EndIf

; ajoute la longueur du tag ID3 V2
FileSeek(#file,8)
total.S=Hex(compteur_long.l,#PB_Word) 
If Len(total.S)<4
	total.S="0"+total.S
EndIf 
octet1.S=Mid(total.S,1,2) 
octet2.S=Mid(total.S,3,2)
WriteByte(#file,Val("$"+octet2.S))
WriteByte(#file,Val("$"+octet1.S))
CloseFile(#file)
EndIf 
EndProcedure

Procedure.l to_little_indian(valeur.l)
	;by Dobro
	total.S=Hex(valeur.l,#PB_Long) 
	If Len(total.S)<8
		total.S="0"+total.S
	EndIf
	octet1.S=Mid(total.S,1,2)
	octet2.S=Mid(total.S,3,2)
	octet3.S=Mid(total.S,5,2)
	octet4.S=Mid(total.S,7,2) 
	total.S="$"+octet4.S+octet3.S+octet2.S+octet1.S 
	sorti.l=Val(total.S)
	ProcedureReturn sorti.l 
EndProcedure
Procedure to_little_indian_w(valeur.l)
	;by Dobro
	total.S=Hex(valeur.l) 
	If Len(total.S)<8
		total.S= LSet(total.S, 8,"0") 
	EndIf 
	octet1.S=Mid(total.S,1,2) 
	octet2.S=Mid(total.S,3,2)
	octet3.S=Mid(total.S,5,2)
	octet4.S=Mid(total.S,7,2) 
	WriteByte(#file,Val("$"+octet4.S))
	WriteByte(#file,Val("$"+octet3.S))
	WriteByte(#file,Val("$"+octet2.S))
	WriteByte(#file,Val("$"+octet1.S)) 
EndProcedure

Procedure write_tag_mp3(file$,titre$,interprete$,album$,annee$,commentaire$,numero_piste$,genre_musical$)
	; By Dobro 
	; purebasic 4.51
	; ecriture des tag MP3 id3V1
	delete_tagV1(file$) ; efface le Tag present 
	If  OpenFile(#file,file$)
		FileSeek(#file, Lof(#file)) ; on se place a la fin du fichier pour ajouter le tag ID3V1 
		WriteByte(#file,Asc("T"))
		WriteByte(#file,Asc("A"))
		WriteByte(#file,Asc("G"))
		
		; ********** ecriture du titre ****************************
		For i=1 To 30
			car$=Mid(titre$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i 
		;*************************************************************
		;**************** ecriture de l'interprete *****************
		For i=1 To 30
			car$=Mid(interprete$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		; ***********************************************************
		; ****************** ecriture de l'album ***********************
		For i=1 To 30
			car$=Mid(album$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		; *****************************************************************
		;***************** ecriture de l'année **************************
		For i=1 To 4
			car$=Mid(annee$,i,1)
			WriteByte(#file,Asc(car$)) 
		Next i
		; *****************************************************************
		; ******************** ecriture des commentaires *****************
		For i=1 To 28
			car$=Mid(commentaire$,i,1)
			WriteByte(#file,Asc(car$))
		Next i
		; ********************************************************************
		; ******************** ecriture octet nul *****************
		WriteByte(#file,0)
		; ********************************************************************
		; ******************** ecriture numero de piste***************** 
		car$=Mid(numero_piste$,1,1)
		WriteByte(#file,Val(car$))
		; ********************************************************************
		; ************************ ecriture du genre musicale ****************** 
		car$=genre_musical$
		WriteByte(#file,Val(car$)) 
		; ***************************************************************************²
	CloseFile(#file) 
Else 
	ProcedureReturn 0
EndIf 
EndProcedure
Procedure delete_tagV1(file$)
	; by Dobro
	; Purebasic 4.51
	If  OpenFile(#file,file$)
		FileSeek(#file, Lof(#file)-128) ; ruse de guerre , on saute a la fin du fichier , puis on recul de 128 octets !
		For i=1 To 3
			tag$= tag$+Chr(ReadCharacter(#file) ) 
		Next i 
		; determine si le tag Mp3 existe
		If tag$="TAG"
			tag_present=#true
			FileSeek(#file,Lof(#file)-129)
			TruncateFile(#file)
		CloseFile(#file) 
		Debug "Tag V1 effacé"
	Else
		tag_present=#False
		Debug "Le tag est absent , on ne peux l'effacer"
	EndIf
EndIf
EndProcedure
Procedure delete_tagV2(file$)
	; by Dobro
	; Purebasic 4.51 
	If OpenFile(#file,file$)
		tag$=""
		For i=0 To 2
			tag$= tag$+Chr(ReadCharacter(#file) ) 
		Next i
		; determine si le tag Mp3 V2 existe
		If tag$="ID3"
			tag_present=#true
			Debug "Le tag  V2 est présent, et va etre effacé" 
			Chemin$ = GetPathPart(file$)
			nom$ = GetFilePart(file$)
			nom$=Left(nom$,Len(nom$)-4)
			Extension$ = GetExtensionPart(file$)
			nom2$=Chemin$+nom$+"xx"+"."+Extension$ 
		CloseFile(#file)
		RenameFile(file$,nom2$) 
		OpenFile(#file,nom2$)
			While Eof(#file)=0 
				test=ReadLong(#file)
				
				test$=Hex(test,#PB_Long)
				test$=RSet(test$,8,"0")
				If test$="FBFF0000" ; recherche debut mp3
					beep_(440,200)
					pos=Loc(#file)-2 ; note la position du debut du mp3
					ok=1
					Break 
				Else
					FileSeek(#file,Loc(#file)-3)
				EndIf 
			Wend 
		CloseFile(#file)
		If tag_present=#true And ok=1
			OpenFile(#file,nom2$)  ; origin
				OpenFile(#file2,file$) ; destination 
					FileSeek(#file,pos)
					While Eof(#file)=0 
						mot.l=ReadLong(#file) 
						WriteLong(#file2,mot.l) 
					Wend 
				CloseFile(#file2) 
			CloseFile(#file) 
			DeleteFile(nom2$)
			Debug "Le Tag V2 est effacé !"
		EndIf
	Else
		tag_present=#False
		Debug "Le tag V2 est absent et ne sera donc pas effacé , cte bonne bague..."
	EndIf
EndIf

EndProcedure


; Epb 


Re: Lire et ecrire les tags des fichiers mp3

Publié : mer. 15/juin/2016 18:08
par venom
Merci zorro,

C'est un code à mettre de côté :wink:






@++

Re: Lire et ecrire les tags des fichiers mp3

Publié : ven. 17/juin/2016 18:00
par JohnJohnsonSHERMAN
Pas mal tout ca! Enfin vous avez oublié FMOD... bon c'est vrai que ca rajoute du poids a l'exe, parcequ'il y a une DLL, mais bon, je trouve Fmod trés pratique, d'autant que la lecture des mp3 se fait si possible via Fmod ou un autre moyen (en tout cas avec la lib Movie de PB la qualité est horrible, ca crache de partout...). Enfin ce code est en tout cas trés interessant (quoique assez long), a garder quelquepart bien au chaud :lol:

Re: Lire et ecrire les tags des fichiers mp3

Publié : ven. 17/juin/2016 19:08
par Zorro
JohnJohnsonSHERMAN a écrit :Pas mal tout ca! Enfin vous avez oublié FMOD... bon c'est vrai que ca rajoute du poids a l'exe, parcequ'il y a une DLL, mais bon, je trouve Fmod trés pratique, d'autant que la lecture des mp3 se fait si possible via Fmod ou un autre moyen (en tout cas avec la lib Movie de PB la qualité est horrible, ca crache de partout...). Enfin ce code est en tout cas trés interessant (quoique assez long), a garder quelquepart bien au chaud :lol:
j'ai rien oublié , ici il s'agit de pouvoir maitriser l'ecriture et la lecture des TAGs !!!

pour la lecture, plutot que de passer par une librairie Tierce, (DLL )
le plus simple pour lire un mp3 c'est d'utiliser MCI (sous windows )
et la qualité est au rendez vous ;)

voici une librairie complete faite par GPI

ya plus qu'a ;)

Code : Tout sélectionner

; German forum: http://robsite.de/php/pureboard/viewtopic.php?t=2786&highlight=
; Author: GPI
; Date: 09. November 2003

;Info: MCI-MP3-Commands
Enumeration 0
	#MP3_Unknown
	#MP3_Stopped
	#MP3_Playing
	#MP3_Paused
EndEnumeration

;Example

Enumeration 1
	#gadget_File
	#Gadget_VolumeTxt
	#Gadget_Volume
	#Gadget_SpeedTxt
	#Gadget_Speed
	#Gadget_PositionTxt
	#Gadget_Position
	#Gadget_Load
	#Gadget_Play
	#Gadget_Stop
	#Gadget_Pause
	#Gadget_Resume
EndEnumeration
Declare  mp3_getstatus(nb)
Declare  mp3_load(nb,file.s)
Declare  mp3_play(nb)
Declare  mp3_playstart(nb)
Declare  mp3_playpart(nb,start,endpos)
Declare  mp3_pause(nb)
Declare  mp3_resume(nb)
Declare  mp3_stop(nb)
Declare  mp3_free2(nb)
Declare  mp3_setvolume(nb,volume)
Declare  mp3_getvolume(nb)
Declare  mp3_setspeed(nb,tempo)
Declare  mp3_getspeed(nb)
Declare  mp3_getlength(nb)
Declare  mp3_getposition(nb)
Declare  mp3_seek(nb,pos)
Declare.s mp3_timestring(time)
Declare  setvol(x)
Declare  setspeed(x)
Declare  setposition(x,max)



If OpenWindow(0, 100, 200, 310,310 , "Simple MP3-Player",#PB_Window_SystemMenu |#PB_Window_ScreenCentered)
	If CreateGadgetList(WindowID(0))
		top=5
		TextGadget    (#gadget_File       ,5,top,300,20,"File:"):top+25
		TextGadget    (#Gadget_VolumeTxt,  5,top,300,20,"Volume"):top+20
		TrackBarGadget(#Gadget_Volume     ,5,top,300,25,0,100):top+30
		TextGadget    (#Gadget_SpeedTxt   ,5,top,300,20,"Speed"):top+20
		TrackBarGadget(#Gadget_Speed      ,5,top,300,25,0,200):top+30
		TextGadget    (#Gadget_PositionTxt,5,top,300,20,"Position"):top+20
		TrackBarGadget(#Gadget_Position   ,5,top,300,25,0,1000):top+30
		ButtonGadget  (#Gadget_Load       ,5,top,300,20,"Load"):top+25
		ButtonGadget  (#Gadget_Play       ,5,top,300,20,"Play"):top+25
		ButtonGadget  (#Gadget_Pause      ,5,top,300,20,"Pause"):top+25
		ButtonGadget  (#Gadget_Resume     ,5,top,300,20,"Resume"):top+25
		ButtonGadget  (#Gadget_Stop       ,5,top,300,20,"Stop"):top+25
		loaded=#False
		Quit=#False
		
		Repeat
			EventID.l = WindowEvent()
			
			Select EventID
				Case 0
				If loaded And max>0
					x=MP3_GetPosition(1)
					If GetGadgetState(#Gadget_Position)<>x*1000/max
						SetPosition(x,max)
					EndIf
				EndIf
				Delay(100)
				Case #PB_Event_CloseWindow ; If the user has pressed on the close button
				Quit=#True
				Case #PB_Event_Gadget
				Select EventGadget()
					Case #Gadget_Load
					File$=OpenFileRequester("","","Media (Wave,MP3,OGG)|*.wav;*.ogg;*.mp3|Wave|*.wav|mp3|*.mp3|OGG|*.OGG|ALL|*.*",0)
						If File$<>""
							If loaded
								mp3_Free2(1)
								loaded=#False
							EndIf
							If MP3_Load(1,File$)
								max=MP3_GetLength(1)
								SetVol(MP3_GetVolume(1)/10)
								SetSpeed(MP3_GetSpeed(1)/10)
								SetPosition(0,max)
								loaded=#True
								SetGadgetText(#gadget_File,"File:"+File$)
							Else
								SetGadgetText(#gadget_File,"File")
							EndIf
						EndIf
						Case #Gadget_Resume
						If loaded
							MP3_Resume(1)
						EndIf
						Case #Gadget_Pause
						If loaded
							MP3_Pause(1)
						EndIf
						Case #Gadget_Play
						If loaded
							MP3_Play(1)
						EndIf
						Case #Gadget_Stop
						If loaded
							MP3_Stop(1)
						EndIf
						Case #Gadget_Position
						If loaded And max>0
							x=GetGadgetState(#Gadget_Position)*max/1000
							SetPosition(x,max)
							MP3_Seek(1,x)
							MP3_Resume(1)
						EndIf
						Case #Gadget_Volume
						If loaded
							x=GetGadgetState(#Gadget_Volume)
							SetVol(x)
							MP3_SetVolume(1,x*10)
						EndIf
						Case #Gadget_Speed
						If loaded
							x=GetGadgetState(#Gadget_Speed)
							SetSpeed(x)
							MP3_SetSpeed(1,x*10)
						EndIf
					EndSelect
				EndSelect
				
			Until Quit
			If loaded
				MP3_Stop(1)
				mp3_Free2(1)
			EndIf
		EndIf
	EndIf
	
	End
	;- Procedures Zone
	Procedure MP3_GetStatus(Nb)
		Result=#MP3_Unknown
		a$=Space(#MAX_PATH)
		i=mciSendString_("status MP3_"+Str(Nb)+" mode",@a$,#MAX_PATH,0)
		If i=0
			Debug a$
			Select a$
				Case "stopped":Result=#MP3_Stopped
				Case "playing":Result=#MP3_Playing
				Case "paused":Result=#MP3_Paused
			EndSelect
		EndIf
		ProcedureReturn Result
	EndProcedure
	Procedure MP3_Load(Nb,file.s)
		;i=mciSendString_("open Sequencer!"+Chr(34)+file+Chr(34)+" alias mid"+Str(Nb),0,0,0)
		i=mciSendString_("OPEN "+Chr(34)+file+Chr(34)+" Type MPEGVIDEO ALIAS MP3_"+Str(Nb),0,0,0)
		If i=0
			ProcedureReturn #True
		Else
			ProcedureReturn #False
		EndIf
	EndProcedure
	Procedure MP3_Play(Nb)
		i=mciSendString_("play MP3_"+Str(Nb),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_PlayStart(Nb)
		i=mciSendString_("play MP3_"+Str(Nb)+" from "+Str(0),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_PlayPart(Nb,Start,endPos)
		i=mciSendString_("play MP3_"+Str(Nb)+" from "+Str(Start)+" to "+Str(endPos),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_Pause(Nb)
		i=mciSendString_("pause MP3_"+Str(Nb),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_Resume(Nb)
		i=mciSendString_("resume MP3_"+Str(Nb),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_Stop(Nb)
		i=mciSendString_("stop MP3_"+Str(Nb),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure mp3_Free2(Nb)
		i=mciSendString_("close MP3_"+Str(Nb),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_SetVolume(Nb,volume)
		i=mciSendString_("SetAudio MP3_"+Str(Nb)+" volume to "+Str(volume),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_GetVolume(Nb)
		a$=Space(#MAX_PATH)
		i=mciSendString_("status MP3_"+Str(Nb)+" volume",@a$,#MAX_PATH,0)
		ProcedureReturn Val(a$)
	EndProcedure
	
	
	Procedure MP3_SetSpeed(Nb,Tempo)
		i=mciSendString_("set MP3_"+Str(Nb)+" Speed "+Str(Tempo),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure MP3_GetSpeed(Nb)
		a$=Space(#MAX_PATH)
		i=mciSendString_("status MP3_"+Str(Nb)+" Speed",@a$,#MAX_PATH,0)
		ProcedureReturn Val(a$)
	EndProcedure
	Procedure MP3_GetLength(Nb)
		a$=Space(#MAX_PATH)
		i=mciSendString_("status MP3_"+Str(Nb)+" length",@a$,#MAX_PATH,0)
		ProcedureReturn Val(a$)
	EndProcedure
	Procedure MP3_GetPosition(Nb)
		a$=Space(#MAX_PATH)
		i=mciSendString_("status MP3_"+Str(Nb)+" position",@a$,#MAX_PATH,0)
		ProcedureReturn Val(a$)
	EndProcedure
	Procedure MP3_Seek(Nb,pos)
		i=mciSendString_("Seek MP3_"+Str(Nb)+" to "+Str(pos),0,0,0)
		ProcedureReturn i
	EndProcedure
	Procedure.s MP3_TimeString(time)
		time/1000
		sek=time%60:time/60
		min=time%60:time/60
		ProcedureReturn RSet(Str(time),2,"0")+":"+RSet(Str(min),2,"0")+":"+RSet(Str(sek),2,"0")
	EndProcedure
	Procedure SetVol(x)
		SetGadgetText(#Gadget_VolumeTxt,"Volume:"+Str(x))
		SetGadgetState(#Gadget_Volume,x)
	EndProcedure
	Procedure SetSpeed(x)
		SetGadgetText(#Gadget_SpeedTxt,"Speed:"+Str(x))
		SetGadgetState(#Gadget_Speed,x)
	EndProcedure
	Procedure SetPosition(x,max)
		SetGadgetText(#Gadget_PositionTxt,"Position:"+MP3_TimeString(x)+" : "+MP3_TimeString(max))
		If max>0
			SetGadgetState(#Gadget_Position,x*1000/max)
		Else
			SetGadgetState(#Gadget_Position,0)
		EndIf
	EndProcedure
	
	
; Epb


Re: Lire et ecrire les tags des fichiers mp3

Publié : sam. 18/juin/2016 17:30
par JohnJohnsonSHERMAN
Pas faux... :oops: :oops:

Re: Lire et ecrire les tags des fichiers mp3

Publié : lun. 20/juin/2016 8:11
par Marc56
Zorro a écrit :pour la lecture, plutot que de passer par une librairie Tierce, (DLL )
le plus simple pour lire un mp3 c'est d'utiliser MCI (sous windows )
et la qualité est au rendez vous ;)

voici une librairie complete faite par GPI

ya plus qu'a ;)

Code : Tout sélectionner

; German forum: http://robsite.de/php/pureboard/viewtopic.php?t=2786&highlight=
; Author: GPI
; Date: 09. November 2003
Merci pour ce code :wink:

En passant: un code écrit il y a 13 ans (une éternité en informatique) et qui fonctionne encore du premier coup sur la 5.50 B1, sur W10 x64 :o
(à moins que tu n'ai effectué une modif ?)

Chapeau pour la pérennité de PB et aux choix que fait Fred dans la manière d’encapsuler les fonctions 8)

Re: Lire et ecrire les tags des fichiers mp3

Publié : lun. 20/juin/2016 8:25
par Zorro
non, ce code, je ne pense pas l'avoir modifié

mais c'est vrais que j'en ai adapté pas mal a Pburebasic 4.00 (le grand changement) , mais en general , je le précise
dans l’entête :)