Lire un MP3 avec la bibliothéque movie

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Lire un MP3 avec la bibliothéque movie

Message par falsam »

N'étant pas vraiment un truc ou astuce, je poste ce code ici. La bibliothéque movie permet d'intégrer la diffusion d'une vidéo dans une application. Toutefois il est possible de lire aussi des fichiers mp3

Code : Tout sélectionner

;Lire un MP3 avec la bibliothéque movie

Enumeration 
  #MainForm
  #Mp3
  
  #Mp3Title
  #Mp3Select
  #Mp3Play
  #Mp3Stop
  
  #Mp3Volume
EndEnumeration

Declare OnSelect()
Declare OnPlay()
Declare OnStop()
Declare OnVolumeChange()
Declare OnExit()

InitMovie()

OpenWindow(#MainForm, 0, 0, 280, 150, "Lire un MP3 avec la bibliothéque movie", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)      

;Affichage du titre
TextGadget(#Mp3Title, 10, 20, 380, 22, "No mp3 select ...")

;Interface du lecteur
ButtonGadget(#Mp3Play, 10, 50, 80, 24, "Play")
ButtonGadget(#Mp3Stop, 100, 50, 80, 24, "Stop")
ButtonGadget(#Mp3Select, 190, 50, 80, 24, "Select")

;Volume 
TrackBarGadget(#Mp3Volume, 10, 120, 260, 22, 0, 100)
SetGadgetState(#Mp3Volume, 50)

;Triggers (Déclencheur)
BindGadgetEvent(#Mp3Play, @OnPlay())
BindGadgetEvent(#Mp3Stop, @OnStop())
BindGadgetEvent(#Mp3Select, @OnSelect())
BindGadgetEvent(#Mp3Volume, @OnVolumeChange())

BindEvent(#PB_Event_CloseWindow, @OnExit())

Repeat : WaitWindowEvent(10) : ForEver

Procedure OnSelect()
  Protected MP3file.s = OpenFileRequester("Sélectionner un mp3", "", "mp3 (*.mp3)|*.mp3", 0)
  
  If MP3File
    LoadMovie(#Mp3, MP3File)
    SetGadgetData(#Mp3Play, 0)       ;Un titre est en cours de lecture
    
    OnPlay()
    OnVolumeChange()
    
    ;Affichage du titre
    SetGadgetText(#Mp3Title, GetFilePart(MP3file))    
    
  EndIf
EndProcedure

Procedure OnPlay()
  If IsMovie(#Mp3) 
    Select MovieStatus(#Mp3)
        
      Case 0  ;Le titre n'est pas en cours de lecture
        PlayMovie(#Mp3, WindowID(#MainForm))  
        SetGadgetText(#Mp3Play, "Pause")
        
      Case -1  ;Le titre est en pause : Reprise de la lecture
        ResumeMovie(#Mp3)
        SetGadgetText(#Mp3Play, "Pause")
        
      Default  ;Le titre est en cours de lecture : On le met en pause
        PauseMovie(#Mp3)
        SetGadgetText(#Mp3Play, "Play")
        
    EndSelect
  EndIf
EndProcedure

Procedure OnStop()
  If IsMovie(#Mp3)
    StopMovie(#Mp3)
    SetGadgetData(#Mp3Play, 0)
    SetGadgetText(#Mp3Play, "Play")
  EndIf
EndProcedure

Procedure OnVolumeChange()
  Protected Value = GetGadgetState(#Mp3Volume)
  If IsMovie(#Mp3)
    MovieAudio(#Mp3, Value, 0) 
  EndIf
EndProcedure

Procedure OnExit()
  If IsMovie(#Mp3)
    FreeMovie(#Mp3)
  EndIf
  
  End
EndProcedure
Un code plus complet avec ajout d'une file d'attente et parcours des titres sur ce lien.
:arrow: http://www.purebasic.fr/french/viewtopi ... 61#p180761
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
cage
Messages : 604
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Lire un MP3 avec la bibliothéque movie

Message par cage »

Merci pour le code.

Je cherchais comment jouer mes MP3 en tache de fond dans PB, maintenant je sais.

cage
■ Win10 Pro 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.12 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Lire un MP3 avec la bibliothéque movie

Message par falsam »

On peut améliorer ce code en intégrant la durée d'un titre et la position de lecture ce qui permettrait de passer au titre suivant.

La bibliothèque movie n'est pas génial fait pour lire des mp3.

Mais en cherchant un peu sur les différents forums consacrés à PureBasic on peut trouver des petites choses qui permettent de :
- Connaitre la longueur d'un titre en mesure de temps.
- Connaitre la position de lecture en mesure de temps.

Comment fait on ? Avec cette structure

Code : Tout sélectionner

Structure MovieStruc
  Movie.IGraphBuilder
  MediaControl.IMediaControl
  MediaEvent.IMediaEventEx
  Window.IVideoWindow
  Audio.IBasicAudio
  Video.IBasicVideo
  MediaSeeking.IMediaSeeking
  State.l
EndStructure
Il faut ensuite charger le mp3 dans une variable qui pointe sur cette structure.

Déclaration de la variable

Code : Tout sélectionner

*movie.MovieStruc
Chargement du mp3

Code : Tout sélectionner

*movie = LoadMovie(#Mp3, MP3file)
Déclaration de quelques variables pour la durée et la position

Code : Tout sélectionner

Duration.q, Position.q
Pour lire la durée

Code : Tout sélectionner

*movie\MediaSeeking\GetDuration(@Duration)
pour lire la position de lecture

Code : Tout sélectionner

*movie\MediaSeeking\GetCurrentPosition(@Position)
Obtenir la durée d'un titre mp3.

Code : Tout sélectionner

;Fluid Byte
;http://www.purebasic.fr/german/viewtopic.php?p=142401#p142401

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)"
EndIf
Obtenir la position de lecture d'un titre mp3.

Code : Tout sélectionner

;Fluid Byte
;http://www.purebasic.fr/german/viewtopic.php?p=137518#p137518

InitMovie()

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

Pattern$ = "Mediafiles (All Types)|*.aif;*.aifc;*.aiff;*.mid;*.rmi;*.midi;*.mp3;*.ogg;*.wma;*.wav;*.snd;*.au|"
Pattern$ + "Apple Macintosh(*.aif;*.aifc;*.aiff)|*.aif;*.aifc;*.aiff|"
Pattern$ + "MIDI-Files (*.mid;*.rmi;*.midi)|*.mid;*.rmi;*.midi|"
Pattern$ + "MPEG Audio (*.mp3)|*.mp3|"
Pattern$ + "OGG Files (*.ogg)|*.ogg|"
Pattern$ + "Windows Audiofile (*.wav;*.snd;*.au)|*.wav;*.snd;*.au|"
Pattern$ + "Windows Media Audio (*.wma)|*.wma|"
Pattern$ + "All Files (*.*)|*.*"

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

If Filename$
   *movie.MovieStruc = LoadMovie(0,Filename$)
   
   OpenWindow(0,0,0,300,130,"DX Audio Playback",#WS_SYSMENU | 1)
   
   ImageGadget(0,10,10,270,80,0,#PB_Image_Border)
   
   CreateImage(0,270,80) : LoadFont(0,"Arial",45,256)
   
   PlayMovie(0,WindowID(0))
   
   Repeat
      EventID = WindowEvent() : Delay(20)
   
      *movie\MediaSeeking\GetCurrentPosition(@Position.l)
      
      Millisecs = Position / 10000
      SecondsTotal = Millisecs / 1000
      MinutesTotal = SecondsTotal / 60   
      Hours = MinutesTotal / 60
      
      Seconds = SecondsTotal - (MinutesTotal * 60)
      Minutes = MinutesTotal - (Hours * 60)
      
      Time$ = RSet(Str(Hours),2,"0") + ":" + RSet(Str(Minutes),2,"0") + ":" + RSet(Str(Seconds),2,"0")
   
      StartDrawing(ImageOutput(0))
      DrawingFont(FontID(0))
      DrawText(17,5,Time$,#White,0)
      StopDrawing()
      SetGadgetState(0,ImageID(0))
   Until EventID = #WM_CLOSE
EndIf
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Lire un MP3 avec la bibliothéque movie

Message par falsam »

Nouveau code

- Ajout d'une file d'attente.
- Sélection de plusieurs titres dans un dossier.
- Parcours des titres en file d'attente. (Premier titre, Précédent, Suivant, Dernier titre)

Code : Tout sélectionner

;Lire un MP3 avec la bibliothèque movie

EnableExplicit

Enumeration File
  #Mp3
EndEnumeration

Enumeration Window
  #MainForm
EndEnumeration

Enumeration Gadget  
  #Mp3Title
  #Mp3Select
  #Mp3Play
  #Mp3Stop
  
  #MP3Home
  #MP3Previous
  #MP3Next
  #MP3End

  #Mp3Volume
EndEnumeration

;Structure associée à la lecture des fichiers MP3
Structure MovieStruc
  Movie.IGraphBuilder
  MediaControl.IMediaControl
  MediaEvent.IMediaEventEx
  Window.IVideoWindow
  Audio.IBasicAudio
  Video.IBasicVideo
  MediaSeeking.IMediaSeeking
  State.l
EndStructure

Global *movie.MovieStruc, Position.q, OldPosition.q

;Set de MP3 à jouer et index de parcours
Global Dim SetMP3.s(0), Index.i

;Plan de l'application
Declare Start()

Declare OnSelect()
Declare OnLoad()
Declare OnPlay()
Declare OnChange()
Declare OnStop()
Declare OnVolumeChange()
Declare OnTimer()
Declare OnExit()

Start()

Procedure Start()
  InitMovie()
  
  OpenWindow(#MainForm, 0, 0, 280, 170, "Lire un MP3 avec la bibliothéque movie", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)      
  
  ;Titre
  TextGadget(#Mp3Title, 10, 20, 260, 22, "No mp3 select ...")
      
  ;Interface du lecteur
  ButtonGadget(#MP3Home, 8, 80, 20, 24, "<|")
  ButtonGadget(#MP3Previous, 28, 80, 20, 24, "<<")
  ButtonGadget(#Mp3Play, 48, 80, 60, 24, "Play")
  ButtonGadget(#MP3Next, 107, 80, 20, 24, ">>")
  ButtonGadget(#MP3End, 127, 80, 20, 24, "|>")
  ButtonGadget(#Mp3Stop, 149, 80, 60, 24, "Stop")
  ButtonGadget(#Mp3Select, 210, 80, 60, 24, "Select")
  
  ;Volume 
  TrackBarGadget(#Mp3Volume, 10, 130, 260, 22, 0, 100)
  SetGadgetState(#Mp3Volume, 50)
  
  AddWindowTimer(#MainForm, 1, 10)
  
  ;Triggers (Déclencheur)
  BindGadgetEvent(#Mp3Home, @OnChange())        ;Lire le premier titre
  BindGadgetEvent(#Mp3Previous, @OnChange())    ;Lire le titre précédent
  BindGadgetEvent(#Mp3Play, @OnPlay())          ;Lire ou pause du titre en cours
  BindGadgetEvent(#Mp3Next, @OnChange())        ;Lire le titre suivant
  BindGadgetEvent(#Mp3End, @OnChange())         ;Lire le dernier titre
  BindGadgetEvent(#Mp3Stop, @OnStop())          ;Stoper la lecture
  BindGadgetEvent(#Mp3Select, @OnSelect())      ;Selectionner un titre
  BindGadgetEvent(#Mp3Volume, @OnVolumeChange());Changer le volume
  
  BindEvent(#PB_Event_Timer, @OnTimer())
  BindEvent(#PB_Event_CloseWindow, @OnExit())
  
  Repeat : WaitWindowEvent(10) : ForEver
EndProcedure

Procedure OnSelect()
  Protected MP3file.s = OpenFileRequester("Sélectionner un mp3", "", "mp3 (*.mp3)|*.mp3", 0, #PB_Requester_MultiSelection)
  
  While  MP3File
    SetMP3(ArraySize(SetMp3())) = MP3File
    ReDim SetMP3(ArraySize(SetMp3()) + 1)
        
    If Not IsMovie(#Mp3)
      OnLoad()
    EndIf
    MP3File = NextSelectedFileName() 
  Wend
EndProcedure

Procedure OnLoad()
  OldPosition = 0
  
  *movie = LoadMovie(#Mp3, SetMP3(Index))
  
  If GetGadgetData(#Mp3Play) = 3
    PlayMovie(#Mp3, WindowID(#MainForm))
    OnVolumeChange()
  EndIf
    
  If ArraySize(SetMP3()) = 1
    OnPlay()
    OnVolumeChange()
  EndIf
  
  SetGadgetText(#Mp3Title, GetFilePart(SetMP3(Index)))
EndProcedure

Procedure OnPlay()
  If IsMovie(#Mp3) 
    Select GetGadgetData(#Mp3Play)
        
      Case 0  ;Le titre n'est pas en cours de lecture
        PlayMovie(#Mp3, WindowID(#MainForm))  
        SetGadgetText(#Mp3Play, "Pause")
        SetGadgetData(#Mp3Play, 3)
        
      Case 1  ;Le titre est en pause : Reprise de la lecture
        ResumeMovie(#Mp3)
        SetGadgetText(#Mp3Play, "Pause")
        SetGadgetData(#Mp3Play, 3)
        
      Case 3 ;Le titre est en cours de lecture : On le met en pause
        PauseMovie(#Mp3)
        SetGadgetText(#Mp3Play, "Play")
        SetGadgetData(#Mp3Play, 1)
    EndSelect      
  EndIf
EndProcedure

Procedure OnChange()
  Protected Gadget = EventGadget()
    
  If IsMovie(#MP3)
    Select Gadget
      Case #MP3Home
        Index = 0
        
      Case #MP3Previous
        If Index > 0 
          Index - 1
        EndIf
        
      Case #MP3Next
        If Index < ArraySize(SetMP3()) - 1
          Index + 1
        EndIf
        
      Case #MP3End
        Index = ArraySize(SetMP3()) - 1
        
    EndSelect
    OnLoad()
  EndIf 
EndProcedure

Procedure OnStop()
  If IsMovie(#Mp3)
    StopMovie(#Mp3)
    SetGadgetData(#Mp3Play, 0)
    SetGadgetText(#Mp3Play, "Play")
  EndIf
EndProcedure

Procedure OnVolumeChange()
  Protected Value = GetGadgetState(#Mp3Volume)
  
  If IsMovie(#Mp3)
    MovieAudio(#Mp3, Value, 0) 
  EndIf
EndProcedure

Procedure OnTimer()  
  If IsMovie(#mp3) And MovieStatus(#Mp3) <> -1   
    *movie\MediaSeeking\GetCurrentPosition(@Position)
        
    Position/10000000
    
    If Position <> 0 
      OldPosition = Position
    EndIf
        
    If Position = 0 And OldPosition <> 0
      If Index < ArraySize(SetMP3()) -1 
        Index + 1
        OnLoad()
      Else
        OnStop()
      EndIf
      OldPosition = 0
    EndIf
  EndIf
EndProcedure

Procedure OnExit()
  If IsMovie(#Mp3)
    FreeMovie(#Mp3)
  EndIf
  
  End
EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Re: Lire un MP3 avec la bibliothéque movie

Message par JohnJohnsonSHERMAN »

Le premier code marche, mais pas le dernier...
Lors de la compilation de ton code, il me fait
Structure introuvable : IGraphBuilder
Probléme de la version démo ?
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Lire un MP3 avec la bibliothéque movie

Message par falsam »

J'ai downloadé la version démo et effectivement les codes faisant appel à la structure MovieStruc ne fonctionnent pas. Il va falloir te décider à investir dans la version commerciale. :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Lire un MP3 avec la bibliothéque movie

Message par falsam »

Après de nombreux tests et pas mal de lecture sur le site de Microsoft, je dois me rendre à l'évidence : La fonction GetDuration() de l'interface windows IMediaSeeking n'est pas fiable ou alors je l'utilise mal.

Je renonce à afficher la durée d'un titre mp3.

Le code que j'ai posté précédemment est modifié en conséquence.

:arrow: http://www.purebasic.fr/french/viewtopi ... 61#p180761

Pour ceux qui veulent juste écouter de la musique en tache de fond ça me semble être une bonne alternative aux ténors du genre tels que VLC par exemple.

Une fois compilé, l’exécutable pèse seulement 45 Ko.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Lire un MP3 avec la bibliothéque movie

Message par falsam »

Toute petite modification : Il est possible de sélectionner plusieurs titres d'un dossier.
:arrow: http://www.purebasic.fr/french/viewtopi ... 61#p180761
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre