connaitre la durée d'un mp3

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

connaitre la durée d'un mp3

Message par case »

voila comme kcc cherchait a savoir et qu'encore une fois il cherchait a faire les choses simplement Image
bref je me suis penché un peu sur le format mp3 et sa structure et j'ai crée une procédure qui permet de connaitre la durée en hr:min:sec d'un mp3 ...

peut être que je tenterais une version plus propre (la c'est pas super niveau code) un de ces jours, mais la c'est tard je vais me coucher :p

j'ai testé avec quelque mp3 , ca fonctionne reste plus qu'a trouver les cas particuliers ou ca plante :mrgreen:

Code : Tout sélectionner

Declare.s mp3length(file.s)
chk$=OpenFileRequester("choisissez un fichier mp3","","*.mp3",1)
Debug mp3length(chk$)
Procedure.s mp3length(file.s)
  rd=ReadFile(#PB_Any,file) ;ouverture du fichier
  If rd       ; ouvert correctement
    Repeat      ;lecture du fichier 
      retry:
      head.s    
      b1=ReadByte(rd)   ; lecture des 4 premiers octets du fichier
      b2=ReadByte(rd)   ;
      b3=ReadByte(rd)   ;
      b4=ReadByte(rd)   ;
      ; transformation en chaine de caractere binaire sur 32 bit
      head = RSet(Bin(b1&$ff),8,"0")
      head = head + RSet(Bin(b2&$ff),8,"0")
      head = head + RSet(Bin(b3&$ff),8,"0")
      head = head + RSet(Bin(b4&$ff),8,"0")
      
      If Mid(head,1,11)="11111111111" ;  ;"frame sync ??? "
        firstsync=1       
         ; quelle version de mpeg ?
        Select Mid(head,12,2)
          Case "00"
            v=25  ; "mpeg 2.5"
          Case "01"    ;"reserved"
          Case "10"
            v=2 ; mpeg 2
          Case "11"
            v=1 ; mpeg 1
        EndSelect
        ;
        ;
        ; quel layer 
        Select Mid(head,14,2)
          Case "00" ; "reserved"
          Case "01"
          l=3 ;layer 3"
          Case "10" 
          l=2;layer 2"
          Case "11" 
          l=1;"layer 1"
        EndSelect
        ;
        ;
        ;protegé par un CRC ? 
        Select Mid(head,16,1)
          Case "0"
            crc=0; "protected by crc"
          Case "1" 
            crc=1; "no crc protected"
        EndSelect
        ;
        ;
        ;
        ;debug "bitrate"
        bitrate=0
        If  l=1   ; LAYER 1 
          Select Mid(head,17,4)
            Case "0000" 
              ;debug "vbr"
            Case "0001"
              bitrate=32
            Case "0010"
              bitrate=64
            Case "0011"
              bitrate=96
            Case "0100"
              bitrate=128
            Case "0101"
              bitrate=160
            Case "0110"
              bitrate=192
            Case "0111"
              bitrate=224
            Case "1000"
              bitrate=256
            Case "1001"
              bitrate=288
            Case "1010"
              bitrate=320
            Case "1011"
              bitrate=352
            Case "1100"
              bitrate=384
            Case "1101"
              bitrate=416
            Case "1110"
              bitrate=448
            Case "1111"
              ;debug "bad"
          EndSelect
        EndIf 
        If  l=2 ; LAYER 2
          Select Mid(head,17,4)
            Case "0000" 
            ;debug "vbr"
            Case "0001"
              bitrate=32
            Case "0010"
              bitrate=48
            Case "0011"
              bitrate=56
            Case "0100"
              bitrate=64
            Case "0101"
              bitrate=80
            Case "0110"
              bitrate=96
            Case "0111"
              bitrate=112
            Case "1000"
              bitrate=128
            Case "1001"
              bitrate=160
            Case "1010"
              bitrate=192
            Case "1011"
              bitrate=224
            Case "1100"
              bitrate=256
            Case "1101"
              bitrate=320
            Case "1110"
              bitrate=384
            Case "1111"
              ;debug "bad"
          EndSelect
        EndIf 
        If  l=3 ;LAYER 3
          Select Mid(head,17,4)
            Case "0000" 
            ;debug "vbr"
            Case "0001"
              bitrate=32
            Case "0010"
              bitrate=40
            Case "0011"
              bitrate=48
            Case "0100"
              bitrate=56
            Case "0101"
              bitrate=64
            Case "0110"
              bitrate=80
            Case "0111"
              bitrate=96
            Case "1000"
              bitrate=112
            Case "1001"
              bitrate=128
            Case "1010"
              bitrate=160
            Case "1011"
              bitrate=192
            Case "1100"
              bitrate=224
            Case "1101"
              bitrate=256
            Case "1110"
              bitrate=320
            Case "1111"
              ;debug "bad"
          EndSelect
          ;Debug bitrate
        EndIf 
        ;frequence d'echantillonage
        freq=0
        If v=1
          Select Mid(head,21,2)
            Case "00"
              freq=44100
            Case "01"
              freq=48000
            Case "10"
              freq=32000
            Case "11"
              ;debug "reserved"
          EndSelect
        EndIf
        If v=2
          Select Mid(head,21,2)
            Case "00"
              freq=22050
            Case "01"
              freq=24000
            Case "10"
              freq=16000
            Case "11"
             ;debug "reserved"
          EndSelect
        EndIf
        If v=25
          Select Mid(head,21,2)
            Case "00"
              freq=11025
            Case "01"
              freq=12000
            Case "10"
              freq=8000
            Case "11"
              ;debug "reserved"
          EndSelect
        EndIf         
        ; padding byte ? 
        Select Mid(head,23,1)
          Case "0"
            padded=0; "not padded"
          Case "1"; "padded"
            padded=1
        EndSelect
        Select Mid(head,25,2) 
          Case "00"
            ;debug "stereo"
          Case "01"
            ;debug "joint stereo"
          Case "10"
            ;debug "dual channel"
          Case "11"
            ;debug "mono"
        EndSelect
        Select Mid(head,27,2)
          Case "00"
          ;debug "intensity stereo off: ms stereo off"
          Case "01"
          ;debug "intensity stereo off: ms stereo off"
          Case "10"
          ;debug "intensity stereo off: ms stereo on"
          Case "11"
          ;debug "intensity stereo off: ms stereo on"
        EndSelect
        Select Mid(head,29,1)
          Case "0"
          ;debug "audio not copyrighted"
          Case "1"
          ;debug "audio copyrighted"    
          EndSelect    
          Select Mid(head,30,1)
          Case "0"
          ;debug "copy of original media"
          Case "1"
          ;debug "original media"    
        EndSelect
        Select Mid(head,31,2)
          Case "00"
          ;debug "none"
          Case "01"
          ;debug "50/15 ms"    
          Case "10"
          ;debug "reserved"
          Case "11"
          ;debug "ccit j.17"
        EndSelect
      Else
        If firstsync=1
          Break
        Else
          FileSeek(rd,Loc(rd)-3)
          Goto retry
        EndIf
      EndIf
      framesize=((144*(bitrate*1000))/freq)+padded
      totalsec.f=totalsec+(((framesize*8)/1000)/bitrate)
      ;Debug totalsec
      FileSeek(rd,Loc(rd)+(framesize-4))
    ForEver
  EndIf
  CloseFile(rd)
  total=Int(totalsec)
  hour=(total/3600)
  total=(total-(hour*3600))
  min=Int(total/60)
  sec=total-(min*60)
  ProcedureReturn(RSet(Str(hour),2,"0")+":"+RSet(Str(min),2,"0")+":"+RSet(Str(sec),2,"0"))
EndProcedure
ImageImage
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: connaitre la durée d'un mp3

Message par Ar-S »

Merci case, je teste ça dès que je peux :D
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: connaitre la durée d'un mp3

Message par case »

a noter qu'il n'existe pas de header officiel regroupant toute les info dans un mp3 et chaque 'frame' contiens le bitrate et la fréquence d'échantillonnage
dans un monde ou tout serait simple et facile il suffirais de diviser la taille du mp3 par la taille d'une frame pour connaitre le nombre de frames du mp3 puis de calculer ensuite la durée en fonction du bitrate et de la frequence, mais voila certains mp3 contiennent plus ou moins de tags, des header proprietaires au logiciel d'encodage et certains on un bitrate variable du coup il n'est pas possible de connaitre la durée d'un mp3 juste en lisant le début du fichier et il faut donc calculer la durée de chaque 'frame' indépendamment

le même principe est utilisé pour le format ogg il me semble.

sinon pour plus d'infoil y a de la lecture par la
ImageImage
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: connaitre la durée d'un mp3

Message par Backup »

excellent Case , ça a l'air de fonctionner ton affaire :)
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: connaitre la durée d'un mp3

Message par Kwai chang caine »

Case y m'a volé mon sujet, rien qu'a moi 8O
C'est fort...pour une fois que j'ai écouté vos conseils, et que "j'm'ai" dit : "Allez, j'vais demander comment trouver la durée", et y vont me dire : "KCC y s'rend pas compte de ce que c'est comme code d'avoir une info comme celle la :? "....tu ferais mieux d'utiliser ce qui existe deja plutot que de demander de reinventer la roue" :?

Alors KCC, il a fait toutes les casses de la programmation, et il a trouvé une ROUE...FFMPEG :oops:
Certe c'est pas vraiment la bonne jante...mais elle avait le merite d'etre ronde :roll:
Et en plus elle est open source, remarque...avec moi, qu'ils ouvrent les sources ou pas....c'est comme COMATE....ça change pas grand chose....j'sais meme pas si elles se lisent de gauche a droite ou de droite a gauche :oops:

Et la .....le case y sort un code de la mort....parce qu'il aime pas ma roue :?

En tout cas c'est trop cool, tu as deviné ce que j'allais demander, presque sans que je le demande :lol:
Je ne sais pas si tu l'a fait pour moi, mais je te remercie mille fois, meme si ce n'est pas le cas 8)
Je pense qu'un code comme ça va en interesser plus d'un :roll:

Je viens d'essayer...et j'ai bien tout eu de lady gaga....ton code il a tellement bien marché...que je sais des choses sur elle...que j'ose pas vous dire....j'vais vendre ça aux journaux et me faire noir de i-tunes...euh non de tunes tout court...j'm'ai trompé :mrgreen:

Si t'as un PC dans tes toilettes.....vu qu'on est un peu obligé d'y passer.....c'est une bonne idée pour le OGG et le WAV aussi
Encore merci 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: connaitre la durée d'un mp3

Message par Kwai chang caine »

SHARDIK m'a donné aussi deux liens de codes de FLUID BYTE
Je les rappatrie ici, ça peut toujours servir. :wink:
Y'en a un pour le WAV 8)

Pour le MP3
http://www.purebasic.fr/german/viewtopi ... 81#p142401

Code : Tout sélectionner

Structure MovieStruc
   Movie.IGraphBuilder
   MediaControl.IMediaControl
   MediaEvent.IMediaEventEx
   Window.IVideoWindow
   Audio.IBasicAudio
   Video.IBasicVideo
   MediaSeeking.IMediaSeeking
   State.l
EndStructure

Filename$ = OpenFileRequester("",Filename$,"",0)

If Filename$
   InitMovie()
   
   *movie.MovieStruc = LoadMovie(0,Filename$)
   *movie\MediaSeeking\GetDuration(@Duration.q)
   
   Millisecs = Duration / 10000   
   Duration / 10000000
   Hours = (Duration / 3600)
   Minutes = (Duration / 60) - (60 * Hours)
   Seconds = Duration - (60 * (Duration / 60))

   Hours$ = Str(Hours) : Minutes$ = Str(Minutes) : Seconds$ = Str(Seconds)
   
   If Seconds < 10 : Seconds$ = "0" + Seconds$ : EndIf
   If Minutes < 10 : Minutes$ = "0" + Minutes$ : EndIf
   If Hours   < 10 : Hours$   = "0" + Hours$   : EndIf
   
   Debug "Soundfile = " + Filename$
   Debug "Duration = " + Str(Millisecs) + " Ms"
   Debug "Time Format = " + Hours$ + ":" + Minutes$ + ":" + Seconds$ + " (H:M:S)"
Pour le WAV
http://www.purebasic.fr/english/viewtop ... 67#p178267

Code : Tout sélectionner

; Structure WAVEFORMATEX
;    wFormatTag.w
;    nChannels.w
;    nSamplesPerSec.l
;    nAvgBytesPerSec.l
;    nBlockAlign.w
;    wBitsPerSample.w
;    cbSize.w
; EndStructure

Define lpck.MMCKINFO, wfmt.WAVEFORMATEX

If InitSound() = 0
   MessageRequester("Error","DirectX 7 isn't available or no sound card present.",16) : End
EndIf

Filename$ = OpenFileRequester("","","WAVE Files (*.wav)|*.wav",0)

If Filename$
   HMMIO = mmioOpen_(Filename$,0,#MMIO_READ)
   
   ; FILE FORMAT
   lpck\fccType = mmioStringToFOURCC_("WAVE",0)
   
   Result = mmioDescend_(HMMIO,lpck,0,#MMIO_FINDRIFF)
   
   If Result <> #MMSYSERR_NOERROR
      MessageRequester("Error","Not a wave file!",16) : End
   EndIf
   
   ; READ FORMAT CHUNK
   lpck\ckid = mmioStringToFOURCC_("fmt",0)
   
   Result = mmioDescend_(HMMIO,lpck,lpck,#MMIO_FINDCHUNK)
   
   If Result <> #MMSYSERR_NOERROR      
      MessageRequester("Error","Couldn't get format chunk!",16) : End     
   EndIf
   
   ; READ COMPRESSION TYPE
   mmioRead_(HMMIO,wfmt,lpck\ckSize)
   
   If wfmt\wFormatTag ! #WAVE_FORMAT_PCM
      MessageRequester("Error","Compressed wave files aren't supported!",16) : End   
   EndIf
   
   ; READ DATA CHUNK
   lpck\ckid = mmioStringToFOURCC_("data",0)
   
   Result = mmioDescend_(HMMIO,lpck,lpck,#MMIO_FINDCHUNK)    
   
   If Result <> #MMSYSERR_NOERROR
      MessageRequester("Error","Couldn't get data chunk!",16) : End   
   EndIf
   
   ; CALCULATE SOUND LENGTH
   Duration = lpck\ckSize / wfmt\nAvgBytesPerSec
   
   Hours = (Duration / 3600)
   Minutes = (Duration / 60) - (60 * Hours)
   Seconds = Duration - (60 * (Duration / 60))
   Millisecs = Int(lpck\ckSize / (wfmt\nAvgBytesPerSec / 1000))
   
   Hours$ = Str(Hours) : Minutes$ = Str(Minutes) : Seconds$ = Str(Seconds)
   
   If Seconds < 10 : Seconds$ = "0" + Seconds$ : EndIf
   If Minutes < 10 : Minutes$ = "0" + Minutes$ : EndIf
   If Hours   < 10 : Hours$   = "0" + Hours$   : EndIf
   
   Time$ = Hours$ + ":" + Minutes$ + ":" + Seconds$   
   
   mmioClose_(HMMIO,0)
   
   ; DEBUG INFO
   Debug "Soundfile = " + Filename$
   Debug "Duration = " + Str(Millisecs) + " Ms"
   Debug "Time Format = " + Time$ + " (H:M:S)"
EndIf
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
venom
Messages : 3138
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: connaitre la durée d'un mp3

Message par venom »

Merci c'est du tout cuit :P :wink:









@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Répondre