Page 1 of 2

Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 12:44 am
by RASHAD
As I promised save the next code as mp3.vbs after changing the Folder name
You can change the files extension to ogg,flac,wav and maybe more
Dbl click the file to get the result
Use Notepad to save the file as UTF-8

Code: Select all

Const LENGTH = 27 
Dim oShell  : Set oShell  = CreateObject("Shell.Application")
Dim oFolder : Set oFolder = oShell.Namespace("G:\mmedia\sounds")
DIM oFSO    : Set oFSO    = CreateObject("Scripting.FileSystemObject")

For Each strFileName in oFolder.Items
If Lcase(oFSO.GetExtensionName(strFileName.Name)) = Lcase("mp3") Then
    If Split(oFolder.GetDetailsOf(strFileName,LENGTH),":")(2) >= 4 Then
        Msg = Msg & "File name: " &_
        oFolder.GetDetailsOf(strFileName,FILE_NAME) &_
        vbTab & "Duration : "& oFolder.GetDetailsOf(strFileName,LENGTH) & vbcrlf
    End If
End If
Next
wscript.echo Msg
PB program to run MP3.vbs

Code: Select all

startp = ElapsedMilliseconds()
RunProgram("D:\mp3.vbs","","")
endp = ElapsedMilliseconds()
MessageRequester("Info",Str(endp-startp),#MB_OK)

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 2:16 am
by jak64
Thank you RASHAD

I saved the file in UTF-8 on disk D

When I double click on the mp3.vbs, I get the following error message:

Script: D:\mp3.vbs
Line: 1
Character : 1
Error: Required object: 'Ofolder'
Code: 800A01A8
Source: Microsoft VBScript runtime error

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 2:23 am
by jak64
Hi RASHAD

I made a mistake when copying the vbs code, I hadn't copied everything!

It's OK,

Thanks to you

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 4:23 am
by jak64
Hello RASHAD,

How do I retrieve the durations of the mp3.vbs in my Purebasic program?

THANKS

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 8:54 am
by RASHAD
Hi jack64
Any luck with the speed test :)
You can pipe the output to a text file
-Parse the text file to PB

Code: Select all

startp = ElapsedMilliseconds()
RunProgram("cmd "," /c cscript //nologo d:\mp3.vbs > d:\test.txt","",#PB_Program_Hide)
endp = ElapsedMilliseconds()
MessageRequester("Info",Str(endp-startp),#MB_OK)
Modified VBS File for the text file to include as much as it can:

Code: Select all

Const LENGTH = 27 
Dim oShell  : Set oShell  = CreateObject("Shell.Application")
Dim oFolder : Set oFolder = oShell.Namespace("G:\mmedia\sounds")
Dim oFSO    : Set oFSO    = CreateObject("Scripting.FileSystemObject")

For Each strFileName in oFolder.Items
If LCase(oFSO.GetExtensionName(strFileName.Name)) = LCase("mp3") Then
	If Split(oFolder.GetDetailsOf(strFileName,LENGTH),":")(2) >= 4 Then
        Msg = oFolder.GetDetailsOf(strFileName,FILE_NAME) &_
        vbTab & "Duration : "& oFolder.GetDetailsOf(strFileName,LENGTH)
	  wscript.echo msg
	End If
End If
Next

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 1:06 pm
by jak64
Hello Rashid,
Thank you for all this information, it's great but I still have another problem:

I have classified my music in several directories:

1) I have a "MUSIC" directory
2) I have 3 subdirectories under the "MUSIC" directory:
- SONGS
- INSTRUMENTAL
- CLASSICAL MUSIC
3) In these subdirectories, I also have many other subdirectories, for example in "SONGS", I have one directory per singer (I have almost 1500 subdirectories with the name of the singer (singer ).

I can't write 1500 different vbs to scan these directories and subdirectories!

Is there a way to scan all these directories with a single vbs?

I put below the code that I have written currently.

For the moment, I use a database to store the durations of the musics, while waiting to have a vbs which can do the same thing.

Code: Select all

;---------- Options
EnableExplicit

UseSQLiteDatabase()
InitMovie() 

;---------- Déclaration procédures
Declare AfficherListeMusique()
Declare ChargerMusiques()
Declare.s ChercherDureeMp3(Mp3.s)
Declare CreerBaseMusiques()
Declare CreerLesGadgets()
Declare.s EpurerCaracteres(Chaine.s)
Declare GadgetBalloonToolTip(WindowNumber.l, GadgetNumber.l, Text.s)
Declare LireMp3(Mp3.s)
Declare Rechercher()
Declare ScanDirectory(source.s, rek=0)
Declare SetGadgetCallback(WindowID.I, ListIconID.I)
Declare TrierListeMusiqueSurDuree()
Declare TrierListeMusiqueSurGenre()
Declare TrierListeMusiqueSurTitre()
Declare WndProc(hWnd, uMsg, wParam, lParam)

;---------- Constantes
#Base="Musiques.sqlite"
#Chr_13=Chr($0D)
#CouleurCaracteresRecherche=$4F4F2F
#CouleurFondFenetre=$4B4B4B
#CouleurFondListe=$333333
#CouleurFondRecherche=$8CE6F0
#DoubleQuote=Chr(34)
#Espacement=10
#OptionsFenetre= #PB_Window_MinimizeGadget; | #PB_Window_ScreenCentered
#RepertoireMusiques="D:\VARIETES\"

;---------- Enumérations
Enumeration
  #BoutonRechercher
  #FenetreWindows
  #LecteurMusique
  #ListeMusiques
  #PoliceBoutonRechercher
  #PoliceListe
  #PoliceRecherche
  #Recherche
EndEnumeration

;---------- Structures
;= Utile pour détecter clic sur entêtes colonnes liste des films
Structure CallbackEntry
  WindowID.I
  ListIconID.I
  DefaultCallback.I
EndStructure

Structure UneMusique
  CheminEtTitreComplet.s
  CheminEtTitreCompletEpure.s
  Genre.s
  TitreComplet.s
  Duree.s
EndStructure

;---------- Listes
NewList CallbackEntry.CallbackEntry() ;= Utile pour détecter clic sur entêtes colonnes liste des films
Global NewList ListeMesMusiques.UneMusique()
Global NewList ListeMesMusiquesAffichees.UneMusique()

;= Utile pour détecter clic sur entêtes colonnes liste des films

;---------- Tableaux

;---------- Variables
Global AfficherTout.b
Global AncienTitre.s
Global Base.l
Global TempsDebutLecture.i
Global TempsActuel.i
Global DureeTotaleMp3.i
Global DureeMp3.s
Global Event.w
Global HauteurApplication.w
Global HauteurBureau.w
Global HauteurListeMusiques.w
Global hWind
Global InfoBulle
Global LargeurApplication.w
Global LargeurBureau.w
Global LargeurListeMusiques.w
Global mouse_normal = LoadCursor_(0,#IDC_ARROW)
Global mouse_hand = LoadCursor_(0,#IDC_HAND)
Global PoliceBoutonRechercher.w
Global PoliceListe.w
Global PoliceRecherche.w
Global PremierClic.b
Global pt.POINT
Global Quitter.b
Global RepertoireCourant.s
Global Resultat.w
Global Saisie.s
Global ScaleH.f
Global ScaleV.f
Global TriDureeCroissant.b
Global TriGenreCroissant.b
Global TriTitreCroissant.b
Global XApplication.w
Global YApplication.w

Global TempsDebut.i
Global TempsFin.i
;---------- Polices
PoliceBoutonRechercher=LoadFont(#PoliceBoutonRechercher, "Calibri", 12)
PoliceListe= LoadFont(#PoliceListe, "Calibri", 12)
PoliceRecherche=LoadFont(#PoliceRecherche, "Calibri", 16)

;---------- Début du programme
RepertoireCourant=GetCurrentDirectory()

; ----- Caractéristiques de l'écran
ExamineDesktops()

LargeurBureau=DesktopWidth(0)
HauteurBureau=DesktopHeight(0)

ScaleH=DesktopScaledX(100)/100
ScaleV=DesktopScaledY(100)/100

LargeurBureau=LargeurBureau/ScaleH
HauteurBureau=HauteurBureau/ScaleV

If LargeurBureau<800 Or HauteurBureau<600
  MessageRequester("Résolution", "Affichage 800 x 600 minimum")
  End
EndIf 

LargeurApplication=1366
HauteurApplication=768

If LargeurApplication>LargeurBureau
  LargeurApplication=LargeurBureau
EndIf

If HauteurApplication+68>HauteurBureau
  HauteurApplication=HauteurBureau-68
EndIf

XApplication=(LargeurBureau-LargeurApplication)/2-3
If HauteurBureau > HauteurApplication + 68
  YApplication=  (HauteurBureau - HauteurApplication - 68)/2
Else
  YApplication=0
EndIf

CreerBaseMusiques()

OpenWindow(#FenetreWindows,XApplication,YApplication,LargeurApplication,HauteurApplication,"MesMusiques - Maa fouaaa - 2023",#OptionsFenetre)
StickyWindow(#FenetreWindows,#False) ; Fenêtre non modale
SetWindowCallback(@WndProc(),#FenetreWindows)
SetWindowColor(#FenetreWindows,#CouleurFondFenetre)
LargeurListeMusiques=LargeurApplication-300-#Espacement
HauteurListeMusiques=HauteurApplication-100

AfficherTout=#True

;= Charger les informations de toutes les musiques
ChargerMusiques()

;= Créer tous les gadgets
CreerLesGadgets()

;= Trier la liste sur le titre de la musique
TriTitreCroissant=#True
TriGenreCroissant=#True
TriDureeCroissant=#True
TrierListeMusiqueSurTitre()

;= Rendre les gadgets visibles
HideGadget(#ListeMusiques,#False)
HideGadget(#Recherche,#False)
HideGadget(#BoutonRechercher,#False)
SetActiveGadget(#Recherche)

;= Utile pour détecter clic sur entêtes colonnes liste des musiques
SetGadgetCallback(#FenetreWindows, #ListeMusiques) 

AncienTitre=""
PremierClic=#False
;---------- Boucle principale
Repeat
  TempsActuel=ElapsedMilliseconds()
  ;Debug ListeMesMusiquesAffichees()\TitreComplet + " = " + Str((DureeTotaleMp3 - (TempsActuel - TempsDebutLecture)) /1000) + " secondes"
  
  
  ;SelectElement(ListeMesMusiquesAffichees(), Resultat)
  If PremierClic
    If DureeTotaleMp3 -(TempsActuel - TempsDebutLecture) <= 0
      Resultat+1
      SetGadgetState(#ListeMusiques,Resultat)
      If Resultat>-1
        SelectElement(ListeMesMusiquesAffichees(), Resultat)
        With ListeMesMusiquesAffichees()
          If \CheminEtTitreComplet <> AncienTitre
            DureeTotaleMp3=Val(Mid(\Duree,1,2))*60000 + Val(Mid(\Duree,4,2))*1000
            LireMp3(\CheminEtTitreComplet)
            AncienTitre=\CheminEtTitreComplet
          Else
            AncienTitre=""
            StopMovie(#LecteurMusique)
          EndIf
        EndWith
      EndIf
    EndIf
  EndIf
  
  
  
  
  Event = WaitWindowEvent()
  Select Event
      ;===== Changer le curseur lorsqu'un gadget est survolé
    Case #WM_MOUSEMOVE
      GetCursorPos_(@pt.POINT)
      hWind = WindowFromPoint_(PeekQ(@pt))
      If hWind = WindowID(#FenetreWindows) ; La souris est sur le fond de la fenêtre
        SetCursor_(mouse_normal)
      Else ; La souris est sur le gadget
        SetCursor_(mouse_hand)
      EndIf

      ;===== Fermeture des fenêtres
    Case #PB_Event_CloseWindow
      Quitter=#True
      
      ;===== Empêcher le déplacement de la fenêtre (elle est recentrée automatiquement)
    Case #PB_Event_MoveWindow
      If GetWindowState(#FenetreWindows) = #PB_Window_Normal
        ResizeWindow(#FenetreWindows,XApplication,YApplication,LargeurApplication,HauteurApplication)
      EndIf
      
      ;===== Evènements sur les gadgets
    Case #PB_Event_Gadget
      Select EventGadget()
          
          ;===== Clic sur une musique dans la liste des musiques         
        Case #ListeMusiques
          Select EventType()

            Case #PB_EventType_LeftClick ; Clic gauche, alors afficher détail du film
              
              If EventData() ; Pour détecter clic sur entêtes colonnes liste des films
                If EventData() = 1 ; Tri sur le titre de la musique
                  TrierListeMusiqueSurTitre()
                  TriGenreCroissant=#True
                  TriDureeCroissant=#True
                  ;StopMovie(#LecteurMusique)
                ElseIf EventData() = 2 ; Trier sur le genre de la musique
                  TrierListeMusiqueSurGenre()
                  TriTitreCroissant=#True
                  TriDureeCroissant=#True
                ElseIf EventData() = 3 ; Trier sur la durée
                  TrierListeMusiqueSurDuree()
                  TriTitreCroissant=#True
                  TriGenreCroissant=#True
                  
                EndIf 
                
              ;= Clic gauche sur une ligne dans la liste des musiques
              Else
                Resultat=GetGadgetState(#ListeMusiques)          ; Récuperer l'indice de la musique dans la liste
                If Resultat>-1
                  PremierClic=#True
                  SelectElement(ListeMesMusiquesAffichees(), Resultat)
                  With ListeMesMusiquesAffichees()
                    If \CheminEtTitreComplet <> AncienTitre
                      DureeTotaleMp3=Val(Mid(\Duree,1,2))*60000 + Val(Mid(\Duree,4,2))*1000
                      LireMp3(\CheminEtTitreComplet)
                      AncienTitre=\CheminEtTitreComplet
                    Else
                      AncienTitre=""
                      StopMovie(#LecteurMusique)
                    EndIf
                  EndWith
                EndIf
              EndIf
          EndSelect
          
          ;===== La zone de recherche a été modifiée
        Case #Recherche
          Select EventType()
            ;Case #PB_EventType_Change
              ;CacherGadgetsDetail()                   ; Cacher les gadgets détails du film
              ;SetGadgetState(#ListeSeries,-1)         ; Désélectionner les séries
              ;If GetGadgetState(#OptionTitre)         ; Si bouton radio Titre coché
              ;Rechercher()                   ; Rechercher sur le titre
                                             ;ElseIf GetGadgetState(#OptionActeur)    ; Si bouton radio Acteur coché
                                             ;  RechercheParActeur()                  ; Rechercher sur le nom de l'acteur
                                             ;ElseIf GetGadgetState(#OptionRealisateur)    ; Si bouton radio Réalisateur coché
                                             ;  RechercheParRealisateur()                  ; Rechercher sur le nom du réalisateur              
                                             ;ElseIf GetGadgetState(#OptionGenre)          ; Si bouton radio Genre coché
                                             ;  RechercheParGenre()                        ; Rechercher par genre
                                             ;EndIf
          EndSelect
          
        ;===== Bouton pout lire la vidéo tutoriel
        Case #BoutonRechercher
          Select EventType()
            Case #PB_EventType_LeftClick
              Rechercher()
          EndSelect
      EndSelect
  EndSelect
Until Quitter
CloseDatabase(Base)
End

Procedure AfficherListeMusique()
  ClearGadgetItems(#ListeMusiques) ;= Effacer la liste des musiques (s'il y en avait d'affichés)
  ResetList(ListeMesMusiquesAffichees())
  While NextElement(ListeMesMusiquesAffichees())
    With ListeMesMusiquesAffichees()
      AddGadgetItem (#ListeMusiques,-1,\TitreComplet + Chr(10) + \Genre + Chr(10) + \Duree)
    EndWith
  Wend  
EndProcedure

Procedure ChargerMusiques()
  TempsDebut=ElapsedMilliseconds()
  ScanDirectory(#RepertoireMusiques)
  TempsFin=ElapsedMilliseconds()
  ;Debug (TempsFin-TempsDebut)
  CopyList(ListeMesMusiques(),ListeMesMusiquesAffichees())
 ;   Debug "Terminé"
EndProcedure

Procedure.s ChercherDureeMp3(Mp3.s)
Protected Longueur.s, Duration.q, Secondes.w, Minutes.w
If Mp3
  mciSendString_("OPEN "+Chr(34)+Mp3+Chr(34)+" Type MPEGVideo ALIAS "+Str(0),0,0,0)
  Longueur = Space(#MAX_PATH)
  mciSendString_("Status 0 length",@Longueur,#MAX_PATH,0)
  Duration = ValD(Longueur)
  
  Minutes=Int(Duration/60000)
  Secondes=Int((Duration-Minutes*60000)/1000)
  DureeMp3 =RSet(StrU(Minutes,#PB_Quad),2,"0")+":"+RSet(StrU(Secondes,#PB_Quad),2,"0")
  mciSendString_("close all ",0,0,0)  
EndIf
EndProcedure

;= Procedure utile pour détecter clic sur entêtes colonnes liste des films
Procedure ColumnHeaderClickCallback(WindowHandle.I, Msg.I, WParam.I, LParam.I)
  Shared CallbackEntry()
  Protected Result.I
  Protected *Header.HD_NOTIFY
  ForEach CallbackEntry()
    If WindowHandle = GadgetID(CallbackEntry()\ListIconID)
      Break
    EndIf
  Next
  Result = CallWindowProc_(CallbackEntry()\DefaultCallback, WindowHandle, Msg, WParam, LParam)
  If Msg = #WM_NOTIFY
    *Header = LParam
    If *Header\hdr\code = #HDN_ITEMCLICK
      PostEvent(#PB_Event_Gadget, CallbackEntry()\WindowID, CallbackEntry()\ListIconID, #PB_EventType_LeftClick, *Header\iItem + 1)
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure CreerBaseMusiques()
  Protected Requete.s
  If FileSize(#PB_Compiler_FilePath + #Base) < 0
    Base = CreateFile(#PB_Any, #PB_Compiler_FilePath + #Base)
    If Base
      CloseFile(Base)
    Else
      MessageRequester("Info", "Problème création base de données " + #Base + " !")
      End
    EndIf
    Base = OpenDatabase(#PB_Any, #PB_Compiler_FilePath + #Base, "", "", #PB_Database_SQLite)
    If Base = 0
      MessageRequester("Base de données", "<"+ #Base +">" + " non trouvée, erreur - " + DatabaseError())
      End
    Else
      ; Création de la table MUSIQUES
      Requete=""
      Requete = "CREATE TABLE IF NOT EXISTS MUSIQUES ("
      Requete + "ID_MUSIQUE INTEGER PRIMARY KEY AUTOINCREMENT Not NULL, "
      Requete + "CHEMIN_ET_TITRE_COMPLET_EPURE STRING, "
      Requete + "DUREE STRING"
      Requete + ")"
      If DatabaseUpdate(Base, Requete) = 0
        MessageRequester("Base de données","Erreur dans création table MUSIQUES - " + DatabaseError())
      EndIf 
    EndIf
  Else
    Base = OpenDatabase(#PB_Any, #PB_Compiler_FilePath + #Base, "", "", #PB_Database_SQLite)
  EndIf 
EndProcedure

Procedure CreerLesGadgets()
  Protected XAffichage.w, YAffichage.w, LAffichage.w, HAffichage.w
  ;= Liste des musiques
  XAffichage=#Espacement 
  YAffichage=45
  LAffichage=LargeurListeMusiques
  HAffichage=HauteurListeMusiques
  ListIconGadget(#ListeMusiques, XAffichage,YAffichage,LAffichage,HAffichage, "Titre", LAffichage-280,
                 #PB_ListIcon_FullRowSelect)
  AddGadgetColumn(#ListeMusiques, 1, "Genre", 200) 
  AddGadgetColumn(#ListeMusiques, 2, "Durée", 53)
  SetGadgetColor(#ListeMusiques,#PB_Gadget_BackColor,#CouleurFondListe)
  SetGadgetColor(#ListeMusiques,#PB_Gadget_FrontColor,#White)
  SetGadgetFont(#ListeMusiques, PoliceListe)
  HideGadget(#ListeMusiques,#True)
  
  ;= Zone de saisie de la recherche
  LAffichage=300
  XAffichage=#Espacement 
  YAffichage=10
  HAffichage=26
  StringGadget(#Recherche,XAffichage,YAffichage,LAffichage,HAffichage,"",#PB_String_BorderLess)
  SetGadgetColor(#Recherche,#PB_Gadget_FrontColor,#CouleurCaracteresRecherche)
  SetGadgetColor(#Recherche,#PB_Gadget_BackColor,#CouleurFondRecherche)
  SetGadgetFont(#Recherche, PoliceRecherche)
  InfoBulle = GadgetBalloonToolTip( #FenetreWindows , #Recherche , "Saisir des caractères sans tenir compte" + #Chr_13 +
                                                                   " ni des accents" + #Chr_13 +
                                                                   " ni des majuscules" + #Chr_13 +
                                                                   " ni des tirets" + #Chr_13 +
                                                                   " ni des caractères de ponctuation" + #Chr_13 +
                                                                   " ni des caractères spéciaux")
  HideGadget(#Recherche,#True)
  
  ;= Bouton lancer la recherche
  XAffichage=#Espacement + 300 + #Espacement
  YAffichage=5
  LAffichage=200
  HAffichage=35
  ButtonGadget(#BoutonRechercher,XAffichage,YAffichage,LAffichage,HAffichage,"Lancer la recherche")
  SetGadgetFont(#BoutonRechercher, PoliceBoutonRechercher)
  InfoBulle = GadgetBalloonToolTip( #FenetreWindows , #BoutonRechercher , "Cliquer pour lancer la recherche")
  HideGadget(#BoutonRechercher,#True)

EndProcedure

Procedure.s EpurerCaracteres(Chaine.s)
  Chaine=ReplaceString(Chaine,"-","",#PB_String_NoCase) ; Moins
  Chaine=ReplaceString(Chaine,"–","",#PB_String_NoCase) ; Surligné
  Chaine=ReplaceString(Chaine,",","",#PB_String_NoCase) ; Virgule
  Chaine=ReplaceString(Chaine,";","",#PB_String_NoCase) ; Point-virgule
  Chaine=ReplaceString(Chaine,":","",#PB_String_NoCase) ; Deux points
  Chaine=ReplaceString(Chaine,"!","",#PB_String_NoCase) ; Point d'exclamation
  Chaine=ReplaceString(Chaine,".","",#PB_String_NoCase) ; Point
  Chaine=ReplaceString(Chaine,Chr(39),"",#PB_String_NoCase) ; Double quote
  Chaine=ReplaceString(Chaine,"’","",#PB_String_NoCase) ; Quote
  Chaine=ReplaceString(Chaine,"(","",#PB_String_NoCase) ; Parenthèse ouvrante
  Chaine=ReplaceString(Chaine,")","",#PB_String_NoCase) ; Parenthèse fermante
  Chaine=ReplaceString(Chaine,"\","",#PB_String_NoCase) ; Anti slash
  Chaine=ReplaceString(Chaine,"&","",#PB_String_NoCase) ; Esperluète
  Chaine=ReplaceString(Chaine,Chr(180),"",#PB_String_NoCase) ; Coche
  Chaine=ReplaceString(Chaine,Chr(176),"",#PB_String_NoCase) ; Petit rond de numéro
  Chaine=ReplaceString(Chaine,"+","",#PB_String_NoCase) ; Signe plus
  Chaine=ReplaceString(Chaine,"=","",#PB_String_NoCase) ; Signe égal
  Chaine=ReplaceString(Chaine,"$","",#PB_String_NoCase) ; Dollar
  
  ; A
  Chaine=ReplaceString(Chaine,"A","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"á","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Á","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"à","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"À","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"â","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Â","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"å","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ä","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ä","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ã","a",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ã","a",#PB_String_NoCase)
  
  ; B
  Chaine=ReplaceString(Chaine,"B","b",#PB_String_NoCase)
  
  ; C
  Chaine=ReplaceString(Chaine,"C","c",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ç","c",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ç","c",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Č","c",#PB_String_NoCase)
  
  ; D
  Chaine=ReplaceString(Chaine,"D","d",#PB_String_NoCase)

  ; E
  Chaine=ReplaceString(Chaine,"E","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"é","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"É","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"è","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"È","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ê","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ê","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ë","e",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ë","e",#PB_String_NoCase)
  
  ; F
  Chaine=ReplaceString(Chaine,"F","f",#PB_String_NoCase)
  
  ; G
  Chaine=ReplaceString(Chaine,"G","g",#PB_String_NoCase)
  
  ; H
  Chaine=ReplaceString(Chaine,"H","h",#PB_String_NoCase)
  
  ; I
  Chaine=ReplaceString(Chaine,"I","i",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"í","i",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"î","i",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Î","i",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ï","i",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ï","i",#PB_String_NoCase)
  
  ; J
  Chaine=ReplaceString(Chaine,"J","j",#PB_String_NoCase)
  
  ; K
  Chaine=ReplaceString(Chaine,"K","k",#PB_String_NoCase)
  
  ; L
  Chaine=ReplaceString(Chaine,"L","l",#PB_String_NoCase)
  
  ; M
  Chaine=ReplaceString(Chaine,"M","m",#PB_String_NoCase)

   ; N
  Chaine=ReplaceString(Chaine,"N","n",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ñ","n",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ñ","n",#PB_String_NoCase) 
  
  ; O
  Chaine=ReplaceString(Chaine,"O","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ó","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ò","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ô","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ô","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ō","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ō","o",#PB_String_NoCase) 
  Chaine=ReplaceString(Chaine,"ö","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ö","o",#PB_String_NoCase)
  
  ; Ø
  Chaine=ReplaceString(Chaine,"Ø","o",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ø","o",#PB_String_NoCase)
  
  ; œ
  Chaine=ReplaceString(Chaine,"œ","oe",#PB_String_NoCase)
  
  ; P
  Chaine=ReplaceString(Chaine,"P","p",#PB_String_NoCase)

  ; Q
  Chaine=ReplaceString(Chaine,"Q","q",#PB_String_NoCase)
  
  ; R
  Chaine=ReplaceString(Chaine,"R","r",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ř","r",#PB_String_NoCase)
 
  ; S
  Chaine=ReplaceString(Chaine,"S","s",#PB_String_NoCase)
  ; ß
  Chaine=ReplaceString(Chaine,"ß","ss",#PB_String_NoCase) 
  
  ; T
  Chaine=ReplaceString(Chaine,"T","t",#PB_String_NoCase)

  ; U
  Chaine=ReplaceString(Chaine,"U","u",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ú","u",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ù","u",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ù","u",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"û","u",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Û","u",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"ü","u",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,"Ü","u",#PB_String_NoCase)
  
  ; V
  Chaine=ReplaceString(Chaine,"V","v",#PB_String_NoCase)
 
  ; W
  Chaine=ReplaceString(Chaine,"W","w",#PB_String_NoCase)
  
  ; X
  Chaine=ReplaceString(Chaine,"X","x",#PB_String_NoCase)
  
  ; Y
  Chaine=ReplaceString(Chaine,"Y","y",#PB_String_NoCase)

  ; Z
  Chaine=ReplaceString(Chaine,"Z","z",#PB_String_NoCase)
  
  ; Caractère espace
  ;Chaine=ReplaceString(Chaine,Chr(32),"",#PB_String_NoCase)
  
  ; Autres caractères
  Chaine=ReplaceString(Chaine,Chr(63),"",#PB_String_NoCase)
  Chaine=ReplaceString(Chaine,Chr(160),"",#PB_String_NoCase)
  
  ProcedureReturn Chaine
EndProcedure

Procedure GadgetBalloonToolTip(WindowNumber.l, GadgetNumber.l, Text.s)
  Protected Tooltip.l, Balloon.TOOLINFO
  Tooltip = CreateWindowEx_ (0, "ToolTips_Class32" , "" , #WS_POPUP | #TTS_NOPREFIX | #TTS_BALLOON , 0, 0, 0, 0, WindowID (WindowNumber), 0, GetModuleHandle_ (0), 0)
  SendMessage_ (Tooltip, #TTM_SETTIPTEXTCOLOR , GetSysColor_ ( #COLOR_INFOTEXT ), 0)
  SendMessage_ (Tooltip, #TTM_SETTIPBKCOLOR , GetSysColor_ ( #COLOR_INFOBK ), 0)
  SendMessage_ (Tooltip, #TTM_SETMAXTIPWIDTH , 0, 500) ; Largeur Maximale de la bulle
  Balloon\cbSize = SizeOf (TOOLINFO)
  Balloon\uFlags = #TTF_IDISHWND | #TTF_SUBCLASS
  Balloon\hwnd = WindowID (WindowNumber)
  Balloon\uId = GadgetID (GadgetNumber)
  SendMessage_(Tooltip, #TTM_SETDELAYTIME, #TTDT_AUTOMATIC,500) ; 500=5 secondes d'affichage du texte
  Balloon\lpszText = @Text
  SendMessage_ (Tooltip, #TTM_ADDTOOL , 0, @Balloon)
  ProcedureReturn Tooltip
EndProcedure

Procedure LireMp3(FichierMp3.s)
  LoadMovie(#LecteurMusique,FichierMp3)
  PlayMovie(#LecteurMusique,#Null)
  TempsDebutLecture=ElapsedMilliseconds()
EndProcedure

Procedure Rechercher()
  ;Debug "Recherche"
  Protected Chaine.s, IMusique.w
  ;NbTotalFilms=0
  ;NbTotalEpisodesSeries=0
  

  ;= Effacer la liste des musiques (s'il y en avait d'affichés)
  ClearGadgetItems(#ListeMusiques)
  ClearList(ListeMesMusiquesAffichees())
  Saisie=GetGadgetText(#Recherche)
  If Saisie<>""
    Saisie=EpurerCaracteres(Saisie)
    ;= Rechercher les musiques correspondant à la recherche et les mettre dans la liste pour les afficher
    ;NbFilmsRecherches=0
    ResetList(ListeMesMusiques())
    While NextElement(ListeMesMusiques())
      With ListeMesMusiques()
        Chaine = \CheminEtTitreCompletEpure
        If FindString(Chaine,Saisie,1) > 0
          AddElement(ListeMesMusiquesAffichees())
          ListeMesMusiquesAffichees()\CheminEtTitreComplet=\CheminEtTitreComplet
          ListeMesMusiquesAffichees()\CheminEtTitreCompletEpure=\CheminEtTitreCompletEpure
          ListeMesMusiquesAffichees()\Duree=\Duree
          ListeMesMusiquesAffichees()\Genre=\Genre
          ListeMesMusiquesAffichees()\TitreComplet=\TitreComplet
        EndIf 
      EndWith
   Wend 
Else
  CopyList(ListeMesMusiques(),ListeMesMusiquesAffichees())
EndIf
TriTitreCroissant=#True
TrierListeMusiqueSurTitre()
EndProcedure

Procedure ScanDirectory(source.s,  rek = 0) ; Source, indice
  Protected s_name.s
  Protected s_type.w
  Protected s_fullname.s
  Protected Debut.w
  Protected Fin.w
  Protected Requete.s
  Protected TitreTrouve.b
  
  If Right(source, 1) <> "\"
    source + "\"   ; Ajoute les "\" 
  EndIf

  If ExamineDirectory(rek, source, "*")
    While NextDirectoryEntry(rek) 
      s_name = DirectoryEntryName(rek) ; Nom du répertoire ou du fichier
      s_type = DirectoryEntryType(rek) ; Type (Répertoire ou fichier)
      Select s_type          
        Case #PB_DirectoryEntry_File 
          s_fullname.s = source + s_name
          If Right(UCase(s_fullname),4)=".MP3"
            ; Ajouter cette entrée dans la liste des musiques
            AddElement(ListeMesMusiques())
            With ListeMesMusiques()
              \CheminEtTitreComplet = s_fullname
              \CheminEtTitreCompletEpure = EpurerCaracteres(s_fullname)
              \TitreComplet = s_name
              ; Rechercher le genre de musique
              If FindString(source,"\chansons\",1,#PB_String_NoCase) > 0
                \Genre="Chanson"
              ElseIf FindString(source,"\instrumental\",1,#PB_String_NoCase) > 0
                Debut = FindString(source,"\instrumental\",1,#PB_String_NoCase)
                Debut = Debut + 14
                Fin = FindString(source,"\",Debut+1,#PB_String_NoCase)
                If Fin >0
                  \Genre=Mid (source,Debut,(Fin - Debut))
                Else
                  \Genre = "Inconnu"
                EndIf 
              ElseIf FindString(source,"\musique classique\",1,#PB_String_NoCase) > 0
                \Genre = "Musique classique"
              Else
                \Genre= "Inconnu"
              EndIf
              ;= Chercher si cette musique est déjà dans la base de données
              Requete="SELECT * FROM MUSIQUES WHERE CHEMIN_ET_TITRE_COMPLET_EPURE=" + "'" + \CheminEtTitreCompletEpure + "'"
              TitreTrouve=#False  
              If DatabaseQuery(Base, Requete) <> 0 ; La requête s'est bien déroulée
                While NextDatabaseRow(Base)
                  \Duree=GetDatabaseString(Base, 2)
                  TitreTrouve=#True
                Wend
                FinishDatabaseQuery(Base)
                If Not TitreTrouve
                  ;= Ce titre n'est pas dans la base, il va être ajouté
                  ChercherDureeMp3(\CheminEtTitreComplet)
                  \Duree=DureeMp3
                  Requete= "INSERT INTO MUSIQUES (CHEMIN_ET_TITRE_COMPLET_EPURE, DUREE) VALUES (" +
                           "'" + \CheminEtTitreCompletEpure  + "'," +
                           "'" + \Duree + "'" +
                           ")"
                  If DatabaseUpdate(Base, Requete) = 0
                    MessageRequester("Base","Erreur ajout nouveau titre dans la table MUSIQUES - " + DatabaseError())
                    End
                  EndIf 
                EndIf
              Else
                MessageRequester("Base", "Erreur lecture table MUSIQUES - " + DatabaseError())
                End
              EndIf           
            EndWith
          EndIf 
        Case #PB_DirectoryEntry_Directory 
          If s_name <> "." And s_name <> ".." 
            ScanDirectory(source + s_name, rek + 1) 
          EndIf      
      EndSelect 
    Wend 
    FinishDirectory(rek) ; Libère la mémoire
  EndIf
EndProcedure

Procedure SetGadgetCallback(WindowID.I, ListIconID.I)
  Shared CallbackEntry()
  AddElement(CallbackEntry())
  CallbackEntry()\WindowID = WindowID
  CallbackEntry()\ListIconID = ListIconID
  CallbackEntry()\DefaultCallback = SetWindowLongPtr_(GadgetID(CallbackEntry()\ListIconID), #GWL_WNDPROC, @ColumnHeaderClickCallback())
EndProcedure

Procedure TrierListeMusiqueSurDuree()
  If TriDureeCroissant
    SortStructuredList(ListeMesMusiquesAffichees(), #PB_Sort_Ascending | #PB_Sort_NoCase, OffsetOf(UneMusique\Duree),TypeOf(UneMusique\Duree))
    TriDureeCroissant=#False
  Else
    SortStructuredList(ListeMesMusiquesAffichees(), #PB_Sort_Descending | #PB_Sort_NoCase, OffsetOf(UneMusique\Duree),TypeOf(UneMusique\Duree))
    TriDureeCroissant=#True
  EndIf
  AfficherListeMusique()
EndProcedure

Procedure TrierListeMusiqueSurGenre()
  If TriGenreCroissant
    SortStructuredList(ListeMesMusiquesAffichees(), #PB_Sort_Ascending | #PB_Sort_NoCase, OffsetOf(UneMusique\Genre),TypeOf(UneMusique\Genre))
    TriGenreCroissant=#False
  Else
    SortStructuredList(ListeMesMusiquesAffichees(), #PB_Sort_Descending | #PB_Sort_NoCase, OffsetOf(UneMusique\Genre),TypeOf(UneMusique\Genre))
    TriGenreCroissant=#True
  EndIf
  AfficherListeMusique()
EndProcedure

Procedure TrierListeMusiqueSurTitre()
  If TriTitreCroissant
    SortStructuredList(ListeMesMusiquesAffichees(), #PB_Sort_Ascending | #PB_Sort_NoCase, OffsetOf(UneMusique\TitreComplet),TypeOf(UneMusique\TitreComplet))
    TriTitreCroissant=#False
  Else
    SortStructuredList(ListeMesMusiquesAffichees(), #PB_Sort_Descending | #PB_Sort_NoCase, OffsetOf(UneMusique\TitreComplet),TypeOf(UneMusique\TitreComplet))
    TriTitreCroissant=#True
  EndIf
  AfficherListeMusique()
EndProcedure

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  Protected gadgetNo, fgcolor, bgcolor
  If uMsg = #WM_CTLCOLORSTATIC 
    gadgetNo = GetProp_(lParam, "PB_ID")
    fgColor = GetProp_(GadgetID(gadgetNo), "fgc")
    bgColor = GetProp_(GadgetID(gadgetNo), "bgc")
    If fgColor Or bgColor
      SetTextColor_(wParam, fgColor)
      SetBkMode_(wParam, #TRANSPARENT)
      ProcedureReturn bgColor
    EndIf
  EndIf
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 1:28 pm
by RASHAD
Oh jack64 :lol:
Your project is complicated more than I expected
I will try to help with VBS to run at multiple folders
Be tuned

In the mean time I was playing with VBS and next is the result it will suit any small project
Save the next as ModMP3.vbs in the TEMP folder

Code: Select all

Const LENGTH = 27
src = "G:\mmedia\sounds"
ext = "mp3"
 
dim oShell  : Set oShell  = CreateObject("Shell.Application")
dim oFolder : Set oFolder = oShell.Namespace(src)
dim oFSO    : Set oFSO    = CreateObject("Scripting.FileSystemObject")

For Each strFileName in oFolder.Items
If LCase(oFSO.GetExtensionName(strFileName.Name)) = LCase(ext) Then
	If Split(oFolder.GetDetailsOf(strFileName,LENGTH),":")(2) >= 4 Then
        Msg = oFolder.GetDetailsOf(strFileName,FILE_NAME) &_
        chr(9) & oFolder.GetDetailsOf(strFileName,LENGTH)
	  wscript.echo msg
	End If
End If
Next

Save the next as mp3run.pb then run it

Code: Select all

LoadFont(0,"Comic Sans ms",14)
If OpenWindow(0, 0, 0, 800, 600, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0, 10, 10, 780, 500, "MP3 File Name", 500, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
  AddGadgetColumn(0, 1, "Duration", 100)
  ButtonGadget(1,10,565,80,24,"RUN")
  SetGadgetFont(0,FontID(0))
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          vbs$ = GetTemporaryDirectory()+"modmp3.vbs"
          out$ = GetTemporaryDirectory()+"Text.txt"
          RunProgram("cmd "," /c cscript //nologo "+vbs$+" > "+out$,"",#PB_Program_Open|#PB_Program_Wait|#PB_Program_Hide)
          If ReadFile(0, out$) 
            While Eof(0) = 0 
              text$ = ReplaceString(ReadString(0),Chr(9),Chr(10))
              AddGadgetItem(0, -1,text$)
            Wend
            CloseFile(0)
            DeleteFile(out$,#PB_FileSystem_Force) 
          Else
            MessageRequester("Information","Couldn't open the file!")
          EndIf
      EndSelect
  EndSelect
Until Quit = 1
EndIf

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 1:45 pm
by jak64
RASHAD,

Where is TEMP folder ?

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 1:51 pm
by RASHAD
Hi jack
GetTemporaryDirectory()

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 1:53 pm
by jak64
Ok I found the Temp is in my
C:\Users\DELL\AppData\Local\Temp

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 2:34 pm
by Marc56us
Where is TEMP folder ?
Tip: Open Temp folder in Windows (Any version)

GUI:
Win + R then type %temp%

DOS (shell):
cd %temp%

That's all
:wink:

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 2:35 pm
by jak64
Thank you Marc56us

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 2:40 pm
by jak64
With this code, the duration of some music is incorrect while it is correct with the vbs that you posted below

Code: Select all

Filename$ = OpenFileRequester("","","ALL|*.*;*.mid|Wave|*.wav|mp3|*.mp3|OGG|*.OGG|MID|*.MID",0)
If Filename$
  mciSendString_("OPEN "+Chr(34)+Filename$+Chr(34)+" Type MPEGVideo ALIAS "+Str(0),0,0,0)
  Length$ = Space(#MAX_PATH)
  mciSendString_("Status 0 length",@Length$,#MAX_PATH,0)
  Duration.q = ValD(length$)
  ;Debug Duration
  ;ms = Duration % 1000
  S.q = Int(Duration / 1000) : While S > 59:S-60:Wend 
  M.q = Int(Duration / 1000 / 60) : While M > 59:M-60:Wend 
  H.q = Int(Duration / 1000 / 60 / 60) : While H > 59:H-60:Wend
  Duration$ =RSet(StrU(H,#PB_Quad),2,"0")+":"+RSet(StrU(M,#PB_Quad),2,"0")+":"+RSet(StrU(S,#PB_Quad),2,"0");+":"+RSet(StrU(ms,#PB_Quad),3,"0")
  Debug Duration$
  mciSendString_("close all ",0,0,0)  
 EndIf

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 2:50 pm
by RASHAD
The MP3 files is complicated some is CBR others is VBR and both the 2 snippet I posted are using MS Windows
So don't blame me :D
I am joking

Re: Getting MP3 file duration using VBS

Posted: Fri Mar 10, 2023 3:28 pm
by RASHAD