So Confused (SOLVED)

Mac OSX specific forum
codeit
User
User
Posts: 62
Joined: Sat Apr 15, 2017 5:53 pm
Location: Leicestershire

Re: So Confused

Post by codeit »

Hi
How could i get this LoadDir procedure to add all found Mp3's to the Playlist as i am not getting anything with this.

Code: Select all


ImportC "-framework CoreServices"
  MDItemCreateWithURL(allocator, url)
  MDItemCopyAttribute(item, name)
EndImport

; <<< Some constants from the NSFileManager class >>>

EnumerationBinary
  #NSDirectoryEnumerationSkipsSubdirectoryDescendants
  #NSDirectoryEnumerationSkipsPackageDescendants
  #NSDirectoryEnumerationSkipsHiddenFiles
EndEnumeration

Enumeration PlayState
  #stopped
  #paused
  #playing
EndEnumeration

Enumeration Ids
  #WinMain
  #ExpListG
  #PlayList
  #BackWard
  #Play
  #ForWard
  #Stop
  #Hide
  #Pause
EndEnumeration

UsePNGImageDecoder()

NewList mp3list.s()

Global mp3Object

Global back0, play0, next0, stop0, hide0 ,pause0

Global kMDItemTitle.i = PeekI(dlsym_(-2, "kMDItemTitle"))
Global kMDItemDurationSeconds.i = PeekI(dlsym_(-2, "kMDItemDurationSeconds"))

Global Img_Window_0_0 = LoadImage(#PB_Any,"Resources/ys-play.png")
Global Img_Window_0_1 = LoadImage(#PB_Any,"Resources/ys-backward-3btns.png")
Global Img_Window_0_2 = LoadImage(#PB_Any,"Resources/ys-forward-3btns.png")
Global Img_Window_0_3 = LoadImage(#PB_Any,"Resources/ys-stop.png")
Global Img_Window_0_4 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")
Global Img_Window_0_5 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")

; <<< Open the main Window & setup Gadets >>>

Procedure OpenWindow_0(x = 0, y = 0, width = 815, height = 555)
  OpenWindow(#WinMain, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_WindowCentered)
  SetWindowColor(Window_0, RGB(213,213,213))
  ExplorerListGadget(#ExpListG, 0, 0, 200, 520, GetHomeDirectory() + "Music/", #PB_Explorer_BorderLess | #PB_Explorer_AlwaysShowSelection)

  ListIconGadget(#PlayList, 200, 20, 615, 500, "Title", 130, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
  AddGadgetColumn(#PlayList, 1, "Author", 130)
  AddGadgetColumn(#PlayList, 2, "Duration", 130)

  ImageGadget(#BackWard, 5, 525, 29, 23, ImageID(Img_Window_0_1))
  GadgetToolTip(#BackWard, "Backward")
  ImageGadget(#Play, 34, 525, 27, 23, ImageID(Img_Window_0_0))
  GadgetToolTip(#Play, "Play/Pause")
  ImageGadget(#ForWard, 60, 525, 29, 23, ImageID(Img_Window_0_2))
  GadgetToolTip(#ForWard, "Forward")
  ImageGadget(#Stop, 93, 525, 29, 23, ImageID(Img_Window_0_3))
  GadgetToolTip(#Stop, "Stop")
  ImageGadget(#Hide, 127, 525, 29, 23, ImageID(Img_Window_0_4))
  GadgetToolTip(#Hide, "Show/Hide Playlits")
  
  ProgressBar_0 = ProgressBarGadget(#PB_Any, 170, 530, 470, 15, 0, 0)
  Container_0 = ContainerGadget(#PB_Any, 200, 0, 614, 20, #PB_Container_Flat)
  SetGadgetColor(Container_0, #PB_Gadget_FrontColor,RGB(94,94,94))
  CloseGadgetList()
  AddWindowTimer(#WinMain, 0, 1000)
EndProcedure

; <<< Load mp3 file & play it >>>

Procedure LoadDir(Folder$)
  Protected.i Pool, PathURL, FileArray, Mp3Array, Mp3Count, Mp3Item, Mp3MetaData, Attribute, i
  Protected Mp3Path.s, Mp3Title.s, Mp3Duration.l
  Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
  PathURL = CocoaMessage(0,0, "NSURL fileURLWithPath:$", @Folder$)
  If PathURL
    FileArray = CocoaMessage(0, CocoaMessage(0, 0, "NSFileManager defaultManager"),
                             "contentsOfDirectoryAtURL:", PathURL,
                             "includingPropertiesForKeys:", 0, "options:", 4, "error:", 0)
    If FileArray
     
      ; Get Mp3Array and Mp3Count
      Mp3Array = CocoaMessage(0, FileArray, "filteredArrayUsingPredicate:",
                              CocoaMessage(0, 0, "NSPredicate predicateWithFormat:$",
                                           @"pathExtension==[c]'mp3'", "argumentArray:", 0)) 
      Mp3Count = CocoaMessage(0, Mp3Array, "count")
     
      ; Loop through all found Mp3 files
      i = 0
      While i < Mp3Count
        Mp3Item = CocoaMessage(0, Mp3Array, "objectAtIndex:", i)
        Mp3Path = PeekS(CocoaMessage(0, CocoaMessage(0, Mp3Item, "path"), "UTF8String"), -1, #PB_UTF8)
        Mp3MetaData = MDItemCreateWithURL(0, Mp3Item)
       
        ; Get title
        Mp3Title = ""
        Attribute = MDItemCopyAttribute(Mp3MetaData, kMDItemTitle)
        If Attribute
          Mp3Title = PeekS(CocoaMessage(0, Attribute, "UTF8String"), -1, #PB_UTF8)
          CFRelease_(Attribute)
        EndIf
       
        ; Get duration
        Mp3Duration = 0
        Attribute = MDItemCopyAttribute(Mp3MetaData, kMDItemDurationSeconds)
        If Attribute
          Mp3Duration = CocoaMessage(0, Attribute, "intValue")
          CFRelease_(Attribute)
        EndIf
       
        ; Show the information about the mp3
        ;Debug "Path: " + Mp3Path
        Debug "Title: " + Mp3Title
        Debug "Duration :" + FormatDate("%hh:%ii:%ss", Mp3Duration)
       
        CFRelease_(Mp3MetaData)
        i + 1
      Wend
    EndIf
  EndIf
  CocoaMessage(0, Pool, "release")
EndProcedure

OpenWindow_0()

; <<< Start of main loop >>>
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
     
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #ExpListG
          Select EventType()
            Case #PB_EventType_LeftClick,#PB_EventType_LeftDoubleClick
              
              LoadDir(GetGadgetText(#ExpListG)) ; << possible problem not sure << 
          EndSelect
      EndSelect
  EndSelect
Until Quit
End

wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

Is this the behavior you are looking for ?

Code: Select all

ImportC "-framework CoreServices"
  MDItemCreateWithURL(allocator, url)
  MDItemCopyAttribute(item, name)
EndImport

Enumeration PlayState
  #stopped
  #paused
  #playing
EndEnumeration

Enumeration Ids
  #WinMain
  #ExpListG
  #PlayList
  #BackWard
  #Play
  #ForWard
  #Stop
  #Hide
  #Pause
EndEnumeration

UsePNGImageDecoder()

NewList mp3list.s()

Global mp3Object

Global back0, play0, next0, stop0, hide0 ,pause0

Global kMDItemTitle.i = PeekI(dlsym_(-2, "kMDItemTitle"))
Global kMDItemAuthors.i = PeekI(dlsym_(-2, "kMDItemAuthors"))
Global kMDItemDurationSeconds.i = PeekI(dlsym_(-2, "kMDItemDurationSeconds"))

Global Img_Window_0_0 = LoadImage(#PB_Any,"Resources/ys-play.png")
Global Img_Window_0_1 = LoadImage(#PB_Any,"Resources/ys-backward-3btns.png")
Global Img_Window_0_2 = LoadImage(#PB_Any,"Resources/ys-forward-3btns.png")
Global Img_Window_0_3 = LoadImage(#PB_Any,"Resources/ys-stop.png")
Global Img_Window_0_4 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")
Global Img_Window_0_5 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")

; <<< Open the main Window & setup Gadets >>>

Procedure OpenWindow_0(x = 0, y = 0, width = 815, height = 555)
  OpenWindow(#WinMain, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_WindowCentered)
  SetWindowColor(Window_0, RGB(213,213,213))
  ExplorerListGadget(#ExpListG, 0, 0, 200, 520, GetHomeDirectory() + "Music/", #PB_Explorer_BorderLess | #PB_Explorer_AlwaysShowSelection)

  ListIconGadget(#PlayList, 200, 20, 615, 500, "Title", 130, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
  AddGadgetColumn(#PlayList, 1, "Author(s)", 130)
  AddGadgetColumn(#PlayList, 2, "Duration", 130)
  AddGadgetColumn(#PlayList, 3, "Path", 130)
  
  ImageGadget(#BackWard, 5, 525, 29, 23, ImageID(Img_Window_0_1))
  GadgetToolTip(#BackWard, "Backward")
  ImageGadget(#Play, 34, 525, 27, 23, ImageID(Img_Window_0_0))
  GadgetToolTip(#Play, "Play/Pause")
  ImageGadget(#ForWard, 60, 525, 29, 23, ImageID(Img_Window_0_2))
  GadgetToolTip(#ForWard, "Forward")
  ImageGadget(#Stop, 93, 525, 29, 23, ImageID(Img_Window_0_3))
  GadgetToolTip(#Stop, "Stop")
  ImageGadget(#Hide, 127, 525, 29, 23, ImageID(Img_Window_0_4))
  GadgetToolTip(#Hide, "Show/Hide Playlits")
  
  ProgressBar_0 = ProgressBarGadget(#PB_Any, 170, 530, 470, 15, 0, 0)
  Container_0 = ContainerGadget(#PB_Any, 200, 0, 614, 20, #PB_Container_Flat)
  SetGadgetColor(Container_0, #PB_Gadget_FrontColor,RGB(94,94,94))
  CloseGadgetList()
  AddWindowTimer(#WinMain, 0, 1000)
EndProcedure

; <<< Load mp3 file & play it >>>

Procedure LoadDir(Folder$)
  Protected.i Pool, PathURL, FileArray, Mp3Array, Mp3Count, Mp3Item, Mp3MetaData, Attribute, i
  Protected Mp3Path.s, Mp3Title.s, Mp3Authors.s, Mp3Duration.l
  
  ClearGadgetItems(#PlayList)
  
  Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
  PathURL = CocoaMessage(0,0, "NSURL fileURLWithPath:$", @Folder$)
  If PathURL
    FileArray = CocoaMessage(0, CocoaMessage(0, 0, "NSFileManager defaultManager"),
                             "contentsOfDirectoryAtURL:", PathURL,
                             "includingPropertiesForKeys:", 0, "options:", 4, "error:", 0)
    If FileArray
     
      ; Get Mp3Array and Mp3Count
      Mp3Array = CocoaMessage(0, FileArray, "filteredArrayUsingPredicate:",
                              CocoaMessage(0, 0, "NSPredicate predicateWithFormat:$",
                                           @"pathExtension==[c]'mp3'", "argumentArray:", 0)) 
      Mp3Count = CocoaMessage(0, Mp3Array, "count")
     
      ; Loop through all found Mp3 files
      i = 0
      While i < Mp3Count
        Mp3Item = CocoaMessage(0, Mp3Array, "objectAtIndex:", i)
        Mp3Path = PeekS(CocoaMessage(0, CocoaMessage(0, Mp3Item, "path"), "UTF8String"), -1, #PB_UTF8)
        Mp3MetaData = MDItemCreateWithURL(0, Mp3Item)
       
        ; Get title
        Mp3Title = ""
        Attribute = MDItemCopyAttribute(Mp3MetaData, kMDItemTitle)
        If Attribute
          Mp3Title = PeekS(CocoaMessage(0, Attribute, "UTF8String"), -1, #PB_UTF8)
          CFRelease_(Attribute)
        EndIf
       
        ; Get author(s)
        Mp3Authors = ""
        Attribute = MDItemCopyAttribute(Mp3MetaData, kMDItemAuthors)
        If Attribute
          Mp3Authors = PeekS(CocoaMessage(0, CocoaMessage(0, Attribute, "componentsJoinedByString:$", @", "), "UTF8String"), -1, #PB_UTF8)
          CFRelease_(Attribute)
        EndIf
        
        ; Get duration
        Mp3Duration = 0
        Attribute = MDItemCopyAttribute(Mp3MetaData, kMDItemDurationSeconds)
        If Attribute
          Mp3Duration = CocoaMessage(0, Attribute, "intValue")
          CFRelease_(Attribute)
        EndIf
       
        ; Add the mp3 to PlayList gadget
        AddGadgetItem(#PlayList, i, Mp3Title)
        SetGadgetItemText(#PlayList, i, Mp3Authors, 1)
        SetGadgetItemText(#PlayList, i, FormatDate("%hh:%ii:%ss", Mp3Duration), 2)
        SetGadgetItemText(#PlayList, i, Mp3Path, 3)
        
        CFRelease_(Mp3MetaData)
        i + 1
      Wend
    EndIf
  EndIf
  CocoaMessage(0, Pool, "release")
EndProcedure

OpenWindow_0()

; <<< Start of main loop >>>
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
     
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #ExpListG
          Select EventType()
            Case #PB_EventType_Change
              LoadDir(GetGadgetText(#ExpListG))
          EndSelect
      EndSelect
  EndSelect
Until Quit
End
Windows (x64)
Raspberry Pi OS (Arm64)
codeit
User
User
Posts: 62
Joined: Sat Apr 15, 2017 5:53 pm
Location: Leicestershire

Re: So Confused

Post by codeit »

I have managed to get it together and it plays ok but just can't get to select the folders on the left side
and play by selecting on the right side please can you point me to where i am going wrong
Thanks

Code: Select all

EnableExplicit

; >>> Some MetaData related things <<<

ImportC "-framework CoreServices"
  CFStringCreateWithCString(alloc, cStr.p-utf8, encoding = $8000100) 
  MDItemCopyAttribute(item, name)
  MDItemCreate(allocator, path)
EndImport

UsePNGImageDecoder()

Procedure.s GetCFString(CFString.i)
  Protected CFStringLength.i = CFStringGetLength_(CFString)
  Protected Dim CharacterData.u(CFStringLength)
  CFStringGetCString_(CFString, @CharacterData(), CFStringLength + 1, #kCFStringEncodingUTF8)
  ProcedureReturn PeekS(@CharacterData(), -1, #PB_UTF8)
EndProcedure

Global kMDItemDurationSeconds.i = CFStringCreateWithCString(0, "kMDItemDurationSeconds")
Global kMDItemTitle.i = CFStringCreateWithCString(0, "kMDItemTitle")
Global kMDItemAlbum.i = CFStringCreateWithCString(0, "kMDItemAlbum")
Global kMDItemMusicalGenre.i = CFStringCreateWithCString(0, "kMDItemMusicalGenre")

Global Img0 = LoadImage(#PB_Any,"Resources/ys-backward-3btns.png")
Global Img1 = LoadImage(#PB_Any,"Resources/ys-play.png")
Global Img2 = LoadImage(#PB_Any,"Resources/ys-forward-3btns.png")
Global Img3 = LoadImage(#PB_Any,"Resources/ys-stop.png")
Global Img4 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")
Global Img5 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")

Global Exp.i, PlayList.i, Play.i, Stop.i
Global BackWard.i, ForWard.i, Hide.i

; >>> AudioItem structure <<<

Structure AudioItem
  title.s 
  album.s
  duration.l
  fileName.s
  fileSize.q
EndStructure


; >>> Procedure to get meta data <<<

Procedure GetMetaData(*Item.AudioItem, AudioFileName.s)
  Protected.i Path, MDItem, Attribute
  Path = CFStringCreateWithCString(0, AudioFileName)
  MDItem = MDItemCreate(0, Path)
  If MDItem
   
    ; get title
    Attribute = MDItemCopyAttribute(MDItem, kMDItemTitle)
    If Attribute
      *Item\title = GetCFString(Attribute)
      CFRelease_(Attribute)
    EndIf
   
    ; get album
    Attribute = MDItemCopyAttribute(MDItem, kMDItemAlbum)
    If Attribute
      *Item\album = GetCFString(Attribute)
      CFRelease_(Attribute)
    EndIf
   
    ; get duration
    Attribute = MDItemCopyAttribute(MDItem, kMDItemDurationSeconds)
    If Attribute
      CFNumberGetValue_(Attribute, #kCFNumberSInt32Type, @*Item\duration)
      CFRelease_(Attribute)
    EndIf
   
    CFRelease_(MDItem)
    CFRelease_(Path)
  EndIf
EndProcedure


; >>> Procedure to add audio to playlist <<<

Procedure AddAudio(List PlayList.AudioItem(), FileOrDirectory.s, Recurse = #False)
  Protected NewList Directory.s()
  Protected *Item.AudioItem
  Protected.i d, Size, DirectoryName.s, Extension.s
 
  Size = FileSize(FileOrDirectory)
  If Size = -2
    AddElement(Directory())
    Directory() = FileOrDirectory
  ElseIf Size > 0
    *Item = AddElement(PlayList())
    GetMetaData(*Item, FileOrDirectory)
    *Item\fileName = FileOrDirectory
    *Item\fileSize = Size
  EndIf
 
  While FirstElement(Directory())
    DirectoryName = Directory()
    DeleteElement(Directory())
    d = ExamineDirectory(#PB_Any, DirectoryName, "*.*")
    If d
      While NextDirectoryEntry(d)
        ; exclude files and directories starting with '.'
        If Asc(DirectoryEntryName(d)) <> '.'
          FileOrDirectory = DirectoryName + DirectoryEntryName(d)
          Extension = LCase(GetExtensionPart(FileOrDirectory))
          Size = FileSize(FileOrDirectory)
          If Size = -2
            ; exclude macOS apps which are actually directories
            If Recurse And Extension <> "app"
              AddElement(Directory())
              Directory() = FileOrDirectory + "/"
            EndIf
          ElseIf Size > 0
            If Extension = "mp3" Or Extension = "wav"
              *Item = AddElement(PlayList())
              GetMetaData(*Item, FileOrDirectory)
              *Item\fileName = FileOrDirectory
              *Item\fileSize = Size
            EndIf 
          EndIf
        EndIf
      Wend
    EndIf
    FinishDirectory(d)
  Wend
 
EndProcedure



; >>> Main code <<<

Global NewList PlayList.AudioItem()
Global.i NSSound, delegateClass, soundDelegate

Declare ItemSelectedCallback()

ProcedureC DidFinishPlayingCallback(obj,sel,sound,flag)
  Protected.i i
  If flag = #YES
    i = GetGadgetState(0) + 1; get next list index
    If i < CountGadgetItems(0)
      SetGadgetState(0, i)
      ItemSelectedCallback()
    Else
      SetGadgetState(0, -1)
    EndIf     
  EndIf
EndProcedure

delegateClass = objc_allocateClassPair_(objc_getClass_("NSObject"), "SoundDelegateClass",0)
class_addMethod_(delegateClass,sel_registerName_("sound:didFinishPlaying:"), @DidFinishPlayingCallback(), "v@:@c")
objc_registerClassPair_(delegateClass)
soundDelegate = class_createInstance_(delegateClass, 0)

Procedure ItemSelectedCallback()
  Protected *Item.AudioItem
  *Item = GetGadgetItemData(0, GetGadgetState(0))
  If NSSound
    CocoaMessage(0, NSSound, "stop")
    CocoaMessage(0, NSSound, "release")
  EndIf
  NSSound = CocoaMessage(0, CocoaMessage(0, 0, "NSSound alloc"),
                         "initWithContentsOfFile:$", @*Item\fileName, "byReference:", #YES)
  CocoaMessage(0, NSSound, "setDelegate:", soundDelegate)
  
  CocoaMessage(0, NSSound, "play")
EndProcedure

Procedure RefreshList()
  Protected s.s, i.i, *Item.AudioItem
  ClearGadgetItems(PlayList)
  ForEach PlayList()
    *Item = PlayList()
    s.s = *Item\title + #LF$
    s   + *Item\album + #LF$
    s   + FormatDate("%hh:%ii:%ss", *Item\duration) + #LF$
    s   + GetFilePart(*Item\fileName) + #LF$
    s   + FormatNumber(*Item\fileSize * 1e-6, 2) + #LF$
    AddGadgetItem(Playlist, i, s)
    SetGadgetItemData(Playlist, i, *Item)
    i + 1
  Next
  SetGadgetState(Playlist, -1)
EndProcedure

Define.i i, Event, FileCount, Files.s, *Item.AudioItem

OpenWindow(0, 0, 0, 826, 550, "Mp3 Player 0.1", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_WindowCentered)
SetWindowColor(0, RGB(213,213,213))

ExplorerListGadget(1, 0, 0, 200, 520, GetHomeDirectory() + "Music/", #PB_Explorer_BorderLess | #PB_Explorer_AlwaysShowSelection)

ListIconGadget(0, 200, 20, 625, 500, "Title", 130, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
EnableGadgetDrop(0, #PB_Drop_Files, #PB_Drag_Copy)
AddGadgetColumn(0, 1, "Album", 160)
AddGadgetColumn(0, 2, "Duration", 80)
AddGadgetColumn(0, 3, "FileName", 160)
AddGadgetColumn(0, 4, "FileSize (MB)", 80)
BindEvent(#PB_Event_Gadget, @ItemSelectedCallback(), 0, 0, #PB_EventType_LeftClick)

AddAudio(PlayList(), GetHomeDirectory() + "Music/", #True)
RefreshList()

ImageGadget(2, 5, 525, 29, 23, ImageID(Img0))
GadgetToolTip(2, "Backward")

ImageGadget(3, 34, 525, 27, 23, ImageID(Img1))
GadgetToolTip(3, "Play/Pause")

ImageGadget(4, 60, 525, 29, 23, ImageID(Img2))
GadgetToolTip(4, "Forward")

ImageGadget(5, 93, 525, 29, 23, ImageID(Img3))
GadgetToolTip(5, "Stop")

ImageGadget(6, 127, 525, 29, 23, ImageID(Img4))
GadgetToolTip(6, "Show/Hide Playlits")

ProgressBarGadget(7, 170, 530, 470, 15, 0, 100)
ContainerGadget(8, 200, 0, 625, 20, #PB_Container_Flat)
SetGadgetColor(8, #PB_Gadget_FrontColor,RGB(94,94,94))


Repeat
  Event = WaitWindowEvent()

  If Event = #PB_Event_GadgetDrop
    Files = EventDropFiles()
    FileCount = CountString(files, #LF$) + 1
    For i = 1 To FileCount
      AddAudio(PlayList(), StringField(Files, i, #LF$), #False)
    Next
    RefreshList()
  EndIf
Until Event = #PB_Event_CloseWindow

If NSSound
  CocoaMessage(0, NSSound, "stop")
  CocoaMessage(0, NSSound, "release")
EndIf
Wolfram
Enthusiast
Enthusiast
Posts: 567
Joined: Thu May 30, 2013 4:39 pm

Re: So Confused

Post by Wolfram »

something like this…

Code: Select all

EnableExplicit

; >>> Some MetaData related things <<<

ImportC "-framework CoreServices"
  CFStringCreateWithCString(alloc, cStr.p-utf8, encoding = $8000100) 
  MDItemCopyAttribute(item, name)
  MDItemCreate(allocator, path)
EndImport

UsePNGImageDecoder()

Procedure.s GetCFString(CFString.i)
  Protected CFStringLength.i = CFStringGetLength_(CFString)
  Protected Dim CharacterData.u(CFStringLength)
  CFStringGetCString_(CFString, @CharacterData(), CFStringLength + 1, #kCFStringEncodingUTF8)
  ProcedureReturn PeekS(@CharacterData(), -1, #PB_UTF8)
EndProcedure

Global kMDItemDurationSeconds.i = CFStringCreateWithCString(0, "kMDItemDurationSeconds")
Global kMDItemTitle.i = CFStringCreateWithCString(0, "kMDItemTitle")
Global kMDItemAlbum.i = CFStringCreateWithCString(0, "kMDItemAlbum")
Global kMDItemMusicalGenre.i = CFStringCreateWithCString(0, "kMDItemMusicalGenre")

Global Img0 = LoadImage(#PB_Any,"Resources/ys-backward-3btns.png")
Global Img1 = LoadImage(#PB_Any,"Resources/ys-play.png")
Global Img2 = LoadImage(#PB_Any,"Resources/ys-forward-3btns.png")
Global Img3 = LoadImage(#PB_Any,"Resources/ys-stop.png")
Global Img4 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")
Global Img5 = LoadImage(#PB_Any,"Resources/ys-playlist-1btn.png")

Global Exp.i, PlayList.i, Play.i, Stop.i
Global BackWard.i, ForWard.i, Hide.i

; >>> AudioItem structure <<<

Structure AudioItem
  title.s 
  album.s
  duration.l
  fileName.s
  fileSize.q
EndStructure


; >>> Procedure to get meta data <<<

Procedure GetMetaData(*Item.AudioItem, AudioFileName.s)
  Protected.i Path, MDItem, Attribute
  Path = CFStringCreateWithCString(0, AudioFileName)
  MDItem = MDItemCreate(0, Path)
  If MDItem
   
    ; get title
    Attribute = MDItemCopyAttribute(MDItem, kMDItemTitle)
    If Attribute
      *Item\title = GetCFString(Attribute)
      CFRelease_(Attribute)
    EndIf
   
    ; get album
    Attribute = MDItemCopyAttribute(MDItem, kMDItemAlbum)
    If Attribute
      *Item\album = GetCFString(Attribute)
      CFRelease_(Attribute)
    EndIf
   
    ; get duration
    Attribute = MDItemCopyAttribute(MDItem, kMDItemDurationSeconds)
    If Attribute
      CFNumberGetValue_(Attribute, #kCFNumberSInt32Type, @*Item\duration)
      CFRelease_(Attribute)
    EndIf
   
    CFRelease_(MDItem)
    CFRelease_(Path)
  EndIf
EndProcedure


; >>> Procedure to add audio to playlist <<<

Procedure AddAudio(List PlayList.AudioItem(), FileOrDirectory.s, Recurse = #False)
  Protected NewList Directory.s()
  Protected *Item.AudioItem
  Protected.i d, Size, DirectoryName.s, Extension.s
 
  Size = FileSize(FileOrDirectory)
  If Size = -2
    AddElement(Directory())
    Directory() = FileOrDirectory
  ElseIf Size > 0
    *Item = AddElement(PlayList())
    GetMetaData(*Item, FileOrDirectory)
    *Item\fileName = FileOrDirectory
    *Item\fileSize = Size
  EndIf
 
  While FirstElement(Directory())
    DirectoryName = Directory()
    DeleteElement(Directory())
    d = ExamineDirectory(#PB_Any, DirectoryName, "*.*")
    If d
      While NextDirectoryEntry(d)
        ; exclude files and directories starting with '.'
        If Asc(DirectoryEntryName(d)) <> '.'
          FileOrDirectory = DirectoryName + DirectoryEntryName(d)
          Extension = LCase(GetExtensionPart(FileOrDirectory))
          Size = FileSize(FileOrDirectory)
          If Size = -2
            ; exclude macOS apps which are actually directories
            If Recurse And Extension <> "app"
              AddElement(Directory())
              Directory() = FileOrDirectory + "/"
            EndIf
          ElseIf Size > 0
            If Extension = "mp3" Or Extension = "wav"
              *Item = AddElement(PlayList())
              GetMetaData(*Item, FileOrDirectory)
              *Item\fileName = FileOrDirectory
              *Item\fileSize = Size
            EndIf 
          EndIf
        EndIf
      Wend
    EndIf
    FinishDirectory(d)
  Wend
 
EndProcedure



; >>> Main code <<<

Global NewList PlayList.AudioItem()
Global.i NSSound, delegateClass, soundDelegate

Declare ItemSelectedCallback()

ProcedureC DidFinishPlayingCallback(obj,sel,sound,flag)
  Protected.i i
  If flag = #YES
    i = GetGadgetState(0) + 1; get next list index
    If i < CountGadgetItems(0)
      SetGadgetState(0, i)
      ItemSelectedCallback()
    Else
      SetGadgetState(0, -1)
    EndIf     
  EndIf
EndProcedure

delegateClass = objc_allocateClassPair_(objc_getClass_("NSObject"), "SoundDelegateClass",0)
class_addMethod_(delegateClass,sel_registerName_("sound:didFinishPlaying:"), @DidFinishPlayingCallback(), "v@:@c")
objc_registerClassPair_(delegateClass)
soundDelegate = class_createInstance_(delegateClass, 0)

Procedure ItemSelectedCallback()
  Protected *Item.AudioItem
  *Item = GetGadgetItemData(0, GetGadgetState(0))
  If NSSound
    CocoaMessage(0, NSSound, "stop")
    CocoaMessage(0, NSSound, "release")
  EndIf
  NSSound = CocoaMessage(0, CocoaMessage(0, 0, "NSSound alloc"),
                         "initWithContentsOfFile:$", @*Item\fileName, "byReference:", #YES)
  CocoaMessage(0, NSSound, "setDelegate:", soundDelegate)
  
  CocoaMessage(0, NSSound, "play")
EndProcedure

Procedure RefreshList()
  Protected s.s, i.i, *Item.AudioItem
  ClearGadgetItems(PlayList)
  ForEach PlayList()
    *Item = PlayList()
    s.s = *Item\title + #LF$
    s   + *Item\album + #LF$
    s   + FormatDate("%hh:%ii:%ss", *Item\duration) + #LF$
    s   + GetFilePart(*Item\fileName) + #LF$
    s   + FormatNumber(*Item\fileSize * 1e-6, 2) + #LF$
    AddGadgetItem(Playlist, i, s)
    SetGadgetItemData(Playlist, i, *Item)
    i + 1
  Next
  SetGadgetState(Playlist, -1)
EndProcedure

Procedure readDirectory(folderPath$) ;<---

  If ExamineDirectory(0, folderPath$, "*.mp3")
    
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        AddAudio(PlayList(), folderPath$ +DirectoryEntryName(0), #False)
        
      EndIf
    Wend
    
    FinishDirectory(0)
    RefreshList()
  EndIf
  
EndProcedure

Define.i i, Event, FileCount, Files.s, *Item.AudioItem, addDirectory


OpenWindow(0, 0, 0, 826, 550, "Mp3 Player 0.1", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_WindowCentered)
SetWindowColor(0, RGB(213,213,213))

ExplorerListGadget(1, 0, 0, 200, 520, GetHomeDirectory() + "Music/", #PB_Explorer_BorderLess | #PB_Explorer_AlwaysShowSelection)

ListIconGadget(0, 200, 20, 625, 500, "Title", 130, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
EnableGadgetDrop(0, #PB_Drop_Files, #PB_Drag_Copy)
AddGadgetColumn(0, 1, "Album", 160)
AddGadgetColumn(0, 2, "Duration", 80)
AddGadgetColumn(0, 3, "FileName", 160)
AddGadgetColumn(0, 4, "FileSize (MB)", 80)
BindEvent(#PB_Event_Gadget, @ItemSelectedCallback(), 0, 0, #PB_EventType_LeftClick)

AddAudio(PlayList(), GetHomeDirectory() + "Music/", #True)
RefreshList()

ImageGadget(2, 5, 525, 29, 23, ImageID(Img0))
GadgetToolTip(2, "Backward")

ImageGadget(3, 34, 525, 27, 23, ImageID(Img1))
GadgetToolTip(3, "Play/Pause")

ImageGadget(4, 60, 525, 29, 23, ImageID(Img2))
GadgetToolTip(4, "Forward")

ImageGadget(5, 93, 525, 29, 23, ImageID(Img3))
GadgetToolTip(5, "Stop")

ImageGadget(6, 127, 525, 29, 23, ImageID(Img4))
GadgetToolTip(6, "Show/Hide Playlits")

addDirectory =ButtonGadget(#PB_Any, 150, 525, 55, 25, "add")

ProgressBarGadget(7, 230, 530, 470, 15, 0, 100)
ContainerGadget(8, 200, 0, 625, 20, #PB_Container_Flat)
SetGadgetColor(8, #PB_Gadget_FrontColor,RGB(94,94,94))


Repeat
  Event = WaitWindowEvent()
Select Event
  Case  #PB_Event_GadgetDrop
    Files = EventDropFiles()
    FileCount = CountString(files, #LF$) + 1
    For i = 1 To FileCount
      AddAudio(PlayList(), StringField(Files, i, #LF$), #False)
    Next
    RefreshList()
  Case #PB_Event_Gadget
    Select EventGadget()
      Case addDirectory
        readDirectory( GetGadgetText(1) )

    EndSelect
    
  EndSelect
Until Event = #PB_Event_CloseWindow

If NSSound
  CocoaMessage(0, NSSound, "stop")
  CocoaMessage(0, NSSound, "release")
EndIf
macOS Catalina 10.15.7
codeit
User
User
Posts: 62
Joined: Sat Apr 15, 2017 5:53 pm
Location: Leicestershire

Re: So Confused

Post by codeit »

Thanks Wolfram
The procedure is fine but what i can't work out is how to bind both ExplorerListGadget and ListIconGadget
so that when i click on ExplorerListGadget it then populates the ListIconGadget with mp3 files just like Windows Explorer
then select the desired mp3.
Wolfram
Enthusiast
Enthusiast
Posts: 567
Joined: Thu May 30, 2013 4:39 pm

Re: So Confused

Post by Wolfram »

Hello codeit,

I'm not sure that I understand you right.
Do you want that the mp3 files from the ExplorerGadget added to your list just by selecting a folder on the ExplorerGadget?
macOS Catalina 10.15.7
codeit
User
User
Posts: 62
Joined: Sat Apr 15, 2017 5:53 pm
Location: Leicestershire

Re: So Confused

Post by codeit »

Hi Wolfram
Just by selecting a folder so only drives and folders on the left and the files on the right.

Thanks
Post Reply