Page 1 sur 1

Lire un MP3 avec la bibliothéque movie

Publié : sam. 20/févr./2016 16:34
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

Re: Lire un MP3 avec la bibliothéque movie

Publié : dim. 21/févr./2016 0:28
par cage
Merci pour le code.

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

cage

Re: Lire un MP3 avec la bibliothéque movie

Publié : dim. 21/févr./2016 13:36
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

Re: Lire un MP3 avec la bibliothéque movie

Publié : dim. 21/févr./2016 14:15
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

Re: Lire un MP3 avec la bibliothéque movie

Publié : dim. 21/févr./2016 17:11
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 ?

Re: Lire un MP3 avec la bibliothéque movie

Publié : dim. 21/févr./2016 17:26
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:

Re: Lire un MP3 avec la bibliothéque movie

Publié : lun. 22/févr./2016 11:48
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.

Re: Lire un MP3 avec la bibliothéque movie

Publié : lun. 22/févr./2016 12:27
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