Noch ein simpler MP3-Player

Anwendungen, Tools, Userlibs und anderes nützliches.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Noch ein simpler MP3-Player

Beitrag von Helle »

Ohne MCI, läuft endlos, schneller Titelwechsel, Shuffle usw.

Code: Alles auswählen

;- MP3-Player, "Helle" Klaus Helbing, 03.10.2006, PB4.00

If InitMouse() = 0 Or InitMovie() = 0
   MessageRequester("Fehler!", "DirectX-Initialisierung fehlgeschlagen", #MB_ICONSTOP)
   End
 EndIf

If OpenWindow(0, 0, 0, 360, 530, "Helles MP3-Player", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) = 0
   MessageRequester("Fehler!","Hier stimmt was nicht!")
 EndIf 

Enumeration 
  #Gadget_Titel 
  #Gadget_Interpret 
  #Gadget_Jahr 
  #Gadget_VolumeTxt 
  #Gadget_Volume 
  #Gadget_Load 
  #Gadget_Play 
  #Gadget_Stop 
  #Gadget_Pause 
  #Gadget_Shuffle 
  #Gadget_Skip 
  #Gadget_Laden 
  #Gadget_Wiedergabe 
  #Gadget_Gesamtzeit
  #Gadget_Restzeit
  #Gadget_List 
EndEnumeration 

Global L.l = 75                   ;Lautstärke
Global Pause.l
Global Aktiv.l
Global Auswahl.l
Global Song.l
Global Memory.l
Global Zeiger.l
Global Filelaenge.l
Global Bitrate.l
Global SongTimeGes.l
Global SongTimeAkt.l
Global TimeOld.l
Global TimeH.l
Global TimeP.l
Global Zufall.l

Global Titel$
Global Interpret$
Global Jahr$
Global MP3$
Global Pfad$
Global Temp$
Global Minuten$
Global Sekunden$

Procedure SetVol(L) 
  SetGadgetText(#Gadget_VolumeTxt,"Lautstärke : " + Str(L)) 
  SetGadgetState(#Gadget_Volume, L) 
EndProcedure 

Procedure Songstart() 
  MP3$ = Pfad$ + GetGadgetItemText(#Gadget_List, Song, 0) + ".mp3" 
  LoadMovie(1, MP3$)
  MovieAudio(1, L, 0)        ;Lautstärke L, Balance mittig (0)
  PlayMovie(1, 0)
  Aktiv = 1
  SetGadgetState(#Gadget_List, Song)
 
  If ReadFile(0, MP3$)
    Filelaenge = Lof(0)
    FileSeek(0, Filelaenge - 128) 
    ReadData(0, Memory, 128)           ;die letzten 128 Byte der Datei einlesen 
      If PeekS(Memory, 3) = "TAG" 
        Titel$ = PeekS(Memory + 3, 30)           ;30 Zeichen für Titel 
        Interpret$ = PeekS(Memory + 33, 30)      ;30 Zeichen für Interpret
        Jahr$ = PeekS(Memory + 93, 4)            ;4 Zeichen für Jahr
                                
        SetGadgetText(#Gadget_Titel, "      Titel :  " + Titel$) 
        SetGadgetText(#Gadget_Interpret, "Interpret :  " + Interpret$) 
        SetGadgetText(#Gadget_Jahr, "   Jahr :  " + Jahr$)      
      EndIf 
             
;- Header suchen, um Bitrate zu ermitteln für Spielzeit  
   Zeiger = 0                          ;für Header-Suche
   FileSeek(0, 0) 
   ReadData(0, Memory, 131072)         ;die ersten 128 KB der Datei einlesen 
     If PeekS(Memory, 3) = "ID3" 
      !pushad                          ;ein wenig Assembler ist das Salz an der Suppe!
      !mov esi,[v_Memory]
      !mov ebx,6
      !mov ecx,3
    
      !xor eax,eax
      !Noch:
      !mov al,[esi+ebx]
      !shl eax,7
      !inc ebx
      !dec ecx
      !jnz Noch
    
      !mov al,[esi+ebx]      
      !mov [v_Zeiger],eax
      !popad
     EndIf              
 
      !pushad
      !mov esi,[v_Memory]
      !mov ebx,[v_Zeiger]
      !Weiter:
      !mov al,[esi+ebx]
      !cmp al,0ffh
      !je Fertig
      !inc ebx                         ;Limit?
      !jmp Weiter
      !Fertig:
     
      !xor eax,eax
      !mov al,[esi+ebx+2]
      !shr al,2                        ;eigentlich 4, aber wegen DD shl 2 
      !mov edx,[Bitratenwert+eax]
      !mov [v_Bitrate],edx
      !popad
           
   SongTimeGes = Filelaenge / Bitrate  ;sehr simple, tuts aber bei mir
   Minuten$ = Str(SongTimeGes / 60000)
   Sekunden$ = Str(SongTimeGes / 1000 - (Val(Minuten$) * 60))
   If Len(Minuten$) = 1 : Minuten$ = "0" + Minuten$ : EndIf
   If Len(Sekunden$) = 1 : Sekunden$ = "0" + Sekunden$ : EndIf
   SetGadgetText(#Gadget_Gesamtzeit, "Gesamtzeit :  " + Minuten$ + " : " + Sekunden$)
   SongTimeAkt = 0     
   TimeOld = ElapsedMilliseconds()    
             
   CloseFile(0)
  EndIf 
 
EndProcedure

Memory = AllocateMemory(131072)        ;128 KB reservieren 
   
    TextGadget(#Gadget_Titel, 10, 10, 300, 20, "      Titel :  ") 
    TextGadget(#Gadget_Interpret, 10, 30, 300, 20, "Interpret :  ") 
    TextGadget(#Gadget_Jahr, 20, 50, 150, 20, "   Jahr :  ") 
    TextGadget(#Gadget_Gesamtzeit, 250, 50, 100, 20, "Gesamtzeit :  ")
    TextGadget(#Gadget_Restzeit, 250, 70, 100, 20, "    Restzeit :  ")   
       
    TextGadget(#Gadget_VolumeTxt, 150, 70, 100, 20, "Lautstärke :") 
    TrackBarGadget(#Gadget_Volume, 10, 90, 340, 20, 0, 100) 
 
    ButtonGadget(#Gadget_Play, 20, 140, 100, 30, "PLAY") 
    ButtonGadget(#Gadget_Pause, 20, 180, 100, 30, "PAUSE") 
    ButtonGadget(#Gadget_Stop, 155, 140, 50, 70, "STOP") 
    ButtonGadget(#Gadget_Shuffle, 240, 140, 100, 30, "SHUFFLE") 
    ButtonGadget(#Gadget_Skip, 240, 180, 100, 30, "SKIP")    
  
    ButtonGadget(#Gadget_Load, 123, 244, 110, 30, "Verzeichnis wählen")  
     
    Frame3DGadget(#Gadget_Laden, 10, 230, 340, 50, "Laden") 
    Frame3DGadget(#Gadget_Wiedergabe, 10, 120, 340, 100, "Wiedergabe") 
  
    ListViewGadget(#Gadget_List, 10, 290, 340, 230) 
 
   SetVol(L)                 ;Lautstärke erstmal auf 75 setzen

Repeat 
 Delay(50)  
   
    TimeP = TimeH            ;eventuelle Pausenzeiten werden zu TimeOld zuaddiert
    TimeH = ElapsedMilliseconds()
   
   If Pause
     TimeOld + (TimeH - TimeP)
   EndIf  
    
   If Aktiv And Pause = 0
      SongTimeAkt = (TimeH - TimeOld) 
      Minuten$ = Str((SongTimeGes / 1000 - SongTimeAkt / 1000) / 60)
      Sekunden$ = Str((SongTimeGes / 1000 - SongTimeAkt / 1000) - (Val(Minuten$) * 60))
      If Len(Minuten$) = 1 : Minuten$ = "0" + Minuten$ : EndIf
      If Len(Sekunden$) = 1 : Sekunden$ = "0" + Sekunden$ : EndIf
      SetGadgetText(#Gadget_Restzeit, "    Restzeit :  " + Minuten$ + " : " + Sekunden$)      
      
       If SongTimeAkt >= SongTimeGes
         StopMovie(1)
         FreeMovie(1)    
         Song + 1
         Songstart()
       EndIf    
 
       If Song <> GetGadgetState(#Gadget_List)   ;schnelle Auswahl per Maus
         StopMovie(1)
         FreeMovie(1)    
         Song = GetGadgetState(#Gadget_List)
         Songstart()
       EndIf 
   EndIf 
    
   EventID = WindowEvent()
  
Select EventID
  Case #PB_Event_Gadget 
     Select EventGadget()
        
        Case #Gadget_Play
         If Auswahl
           If Pause = 0
             Songstart()               ;1.Song starten
           Else                        ;war nur Pause
             Pause = 0
               If Aktiv
                 ResumeMovie(1)
               EndIf 
           EndIf 
         EndIf 
     
        Case #Gadget_Pause
          If Aktiv
            Pause = 1
            PauseMovie(1) 
          EndIf 
        
        Case #Gadget_Stop
          Pause = 0
           If Aktiv
             Aktiv = 0
             StopMovie(1)
             FreeMovie(1)    
           EndIf  
 
        Case #Gadget_Volume 
          L = GetGadgetState(#Gadget_Volume) 
          SetVol(L)
            If Aktiv
              MovieAudio(1, L, 0)
            EndIf 
           
        Case #Gadget_Load              
          ClearGadgetItemList(#Gadget_List)
          If Aktiv
            StopMovie(1)
            FreeMovie(1)    
          EndIf
           Aktiv = 0
           Auswahl = 0
           Pause = 0
         
           Pfad$ = PathRequester("Verzeichnis mit MP3-Dateien auswählen", "") 
            If ExamineDirectory(0, Pfad$, "*.mp3")  
             While NextDirectoryEntry(0)
               If DirectoryEntryType(0) = #PB_DirectoryEntry_File
                  MP3$ = DirectoryEntryName(0)
                    While MP3$ 
                      MP3$ = LSet(MP3$, Len(MP3$) - 4)     ;".mp3" weg, reine Optik  
                      AddGadgetItem(#Gadget_List, -1, MP3$)
                      MP3$ = NextSelectedFileName() 
                      Auswahl + 1
                    Wend 
               EndIf 
            Wend
            FinishDirectory(0)
            EndIf
       
        Case #Gadget_Skip
          If Aktiv
            If Auswahl > Song + 1
              Song + 1
              Songstart()              ;nächsten Song starten
            Else 
              Song = 0
              Songstart()              ;alles von vorn!          
            EndIf  
          EndIf 
 
        Case #Gadget_Shuffle
          If Auswahl And Aktiv = 0
            For x = 0 To Auswahl * 10  ;ein paar Durchläufe solltens schon sein 
              Zufall = Random(Auswahl) - (Auswahl / 2)     ;Subtraktion, um "Löcher" zu vermeiden
                If Zufall < 0 
                   Zufall = 0 
                EndIf 
              Temp$ = GetGadgetItemText(#Gadget_List, Zufall, 0)
              RemoveGadgetItem(#Gadget_List, Zufall)  
              AddGadgetItem(#Gadget_List, -1, Temp$)  
            Next 
           Song = 0
          EndIf
     
     EndSelect
EndSelect

Until Eventid = #PB_Event_CloseWindow 
  If Aktiv 
    FreeMovie(1)
  EndIf 

End

;--------------------------------------------------------------------------------------------------
!section '.data' Data readable writeable

!Bitratenwert DD 0, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40
Gruss
Helle

Edit 03.10.2006: Memory drastisch erhöht
Zuletzt geändert von Helle am 03.10.2006 21:24, insgesamt 1-mal geändert.
Benutzeravatar
C4rizz
Beiträge: 223
Registriert: 01.05.2006 12:43
Computerausstattung: Desktop : Amd Athlon X2 3,2 ghz Black Edition. 4GB Corsair XMS DDR2, nVidia 460 gtx Sonic Extreme

Notebook : [Asus] i5 @ 2,9 ghz, 8GB Corsair DDR3, nVidia gt 540m

Internet : DSL - 16 Mbit | HSDPA - 7,2 Mbit
Wohnort: Celle

Beitrag von C4rizz »

joa is doch schon ganz nett. :allright:
PB 3.94/4.10
Meine Hompage
Benutzeravatar
winduff
Beiträge: 879
Registriert: 10.02.2006 21:05
Wohnort: Gießen
Kontaktdaten:

Beitrag von winduff »

In der Schleife würde ich Delay(50) durch Delay(1) ersetzen. Reicht voll und ganz aus, und das Programm läuft flüssiger ;)
Bild
AND51 hat geschrieben:...und ich würde dein Programm aus Wut zwei mal installieren, um eines genüsslicher löschen zu können, als das andere...
Benutzeravatar
Green Snake
Beiträge: 1394
Registriert: 22.02.2005 19:08

Beitrag von Green Snake »

Wenn ich zum zweiten Mal einen Song auswähle, erhalte ich einen Invalid Memory Access.

Code: Alles auswählen


[...]

  !mov al,[esi + ebx]      
  !add [v_Zeiger],eax 
  !popad 
EndIf                                    ;Hier wird der IMA gemeldet.

[...]
-.-"
Benutzeravatar
winduff
Beiträge: 879
Registriert: 10.02.2006 21:05
Wohnort: Gießen
Kontaktdaten:

Beitrag von winduff »

:mrgreen: :shock: und einen Bluescreen :?
Bild
AND51 hat geschrieben:...und ich würde dein Programm aus Wut zwei mal installieren, um eines genüsslicher löschen zu können, als das andere...
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Reserviertes Memory drastisch erhöht (Code s.o.). Wäre für Rückmeldung sehr dankbar! Kann eigentlich nur daran liegen; mit meinen Files (allerdings nicht sehr vielen und alle von einer Quelle) gab´s keine Probleme.
Delay(50) ist natürlich ein "persönlicher" Wert damit ja nichts ein im Vordergrund laufendes Schachprogramm (100% CPU-Last) stört.

Gruss
Helle
Antworten