So Confused (SOLVED)

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

So Confused (SOLVED)

Post by codeit »

Hi having spent hours trying to rewrite this code so i can load all selected files to play with no luck
wondering if any one can point me in the right direction as i am now so confused with all the changes
I have tried using an array and recursing the selected folder but does not work.
thanks for any help at all.

Code: Select all

Enumeration playState
  #stopped
  #paused
  #playing
EndEnumeration

NewList mp3list.s()
Global mp3Object

Procedure LoadMp3(File$)
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    mp3Object = CocoaMessage(0, CocoaMessage(0, 0, "NSSound alloc"), "initWithContentsOfFile:$", @File$, "byReference:", #YES)
    CocoaMessage(0, mp3Object, "play")
  CompilerElse
    mp3Object = LoadSound(#PB_Any, File$)
    PlaySound(mp3Object)
  CompilerEndIf
EndProcedure

#FLAGS = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered

CompilerIf #PB_Compiler_OS <> #PB_OS_MacOS
  InitSound()
CompilerEndIf

mainWin = OpenWindow(#PB_Any, 0, 0, 800, 380, "MP3 Player 0.1", #FLAGS)
SetWindowColor(mainWin, RGB(0,83,146))
AddWindowTimer(mainWin, 0, 1000)

loadBtn = ButtonGadget(#PB_Any, 20, 350, 100, 25, "Add")
stopBtn = ButtonGadget(#PB_Any, 130, 350, 100, 25, "Stop")
playBtn = ButtonGadget(#PB_Any, 240, 350, 100, 25, "Play")
pauseBtn = ButtonGadget(#PB_Any, 350, 350, 100, 25, "Pause")
exitBtn = ButtonGadget(#PB_Any, 460, 350, 100, 25, "Exit")

playlist = ListIconGadget(#PB_Any, 30, 10, 740, 300, "Song Title", 150, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(playlist, 1, "Size", 130)
AddGadgetColumn(playlist, 2, "Duration", 130)
AddGadgetColumn(playlist, 3, "Elapsed", 130)

;DisableGadget(playBtn, #True)
;DisableGadget(stopBtn, #True)
;DisableGadget(pauseBtn, #True)

; Start of main loop
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
    Case #PB_Event_Timer
      If mp3Object
        
        CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
          If Not CocoaMessage(0, mp3Object, "isPlaying")
          CompilerElse
            If Not SoundStatus(mp3Object) = #PB_Sound_Playing
            CompilerEndIf
            
            If state = #playing
              If Not NextElement(mp3list())
                FirstElement(mp3list())
              EndIf
              LoadMp3(mp3list())
              SetGadgetState(playlist, CompilerElseex(mp3list()))
            EndIf
          EndIf
        EndIf

      Case #PB_Event_Gadget
        Select EventGadget()
          Case loadBtn
            
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
              mp3File$ = OpenFileRequester("Select MP3 Track:", "", "MP3|*.mp3", 0)
            CompilerElse
              mp3File$ = OpenFileRequester("Select WAV Track:", "", "WAV|*.wav", 0)
            CompilerEndIf
            
            If mp3File$ <> ""
              AddGadgetItem(playlist, -1, GetFilePart(mp3File$, #PB_FileSystem_NoExtension))
              SetGadgetItemText(playlist, ListSize(mp3list()), FormatNumber(FileSize(mp3File$)) + " bytes", 1)
              ; get the duration time and release
              
              CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
                mp3Obj = CocoaMessage(0, CocoaMessage(0, 0, "NSSound alloc"), "initWithContentsOfFile:$", @mp3File$, "byReference:", #YES)
                CocoaMessage(@duration.d, mp3Obj, "duration")
                CocoaMessage(0, mp3Obj, "release")
              CompilerEndIf
              
              ; now we publish the duration in the list
              SetGadgetItemText(playlist, ListSize(mp3list()), FormatDate("%hh:%ii:%ss", duration), 2)
              AddElement(mp3list())
              mp3list() = mp3File$
              
              If ListSize(mp3list()) = 1
                SetGadgetState(playlist, 0)
                
                ;DisableGadget(playBtn, #True)
                ;DisableGadget(stopBtn, #True)
                ;DisableGadget(pauseBtn, #True)
                
              EndIf
            EndIf
            
          Case exitBtn
            Quit = #True
           
          Case stopBtn
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
              CocoaMessage(0, mp3Object, "stop")
            CompilerElse
              StopSound(mp3Object)
            CompilerEndIf
            state = #stopped
            
            ;DisableGadget(stopBtn, #True)
            ;DisableGadget(loadBtn, #False)
            ;DisableGadget(pauseBtn, #True)
            ;DisableGadget(playBtn, #False)
           
          Case playBtn
            Select state
              Case #stopped
                state = #playing
                SelectElement(mp3list(), GetGadgetState(playlist))
                LoadMp3(mp3list())
                
                

                ;DisableGadget(stopBtn, #False)
                ;DisableGadget(pauseBtn, #False)
                ;DisableGadget(playBtn, #True)
               
            EndSelect
            
          Case pauseBtn
            Select state     
              Case #paused
                CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
                  CocoaMessage(0, mp3Object, "resume")
                CompilerElse
                  ResumeSound(mp3Object)
                CompilerEndIf
                state = #playing
              Case #playing
              CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
                  CocoaMessage(0, mp3Object, "pause")   
                CompilerElse
                  PauseSound(mp3Object)
                CompilerEndIf
                state = #paused
            EndSelect

          Case playlist
            If CountGadgetItems(playlist) > 0
              Select EventType()
                Case #PB_EventType_LeftClick
                  ;DisableGadget(playBtn, #False) : DisableGadget(stopBtn, #True)
                  ;DisableGadget(loadBtn, #True) : DisableGadget(pauseBtn, #True)
              EndSelect
            EndIf
        EndSelect
    EndSelect
  Until Quit
 
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    CocoaMessage(0, mp3Object, "stop")
    CocoaMessage(0, mp3Object, "release")
  CompilerElse
    If IsSound(mp3Object)
      If SoundStatus(mp3Object, #PB_Sound_Playing)
        StopSound(mp3Object)
      EndIf
      FreeSound(mp3Object)
    EndIf
  CompilerEndIf
Last edited by codeit on Thu Jul 20, 2017 9:53 am, edited 1 time in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

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 »

Hi wilbert
Yes your suggestion is right but my problem is i can't get my head around incorporating another procedure to load all mp3's in a selected folder.
Having inserted the procedure and altered my code i still can't get it together any help would be great thanks.

Code: Select all

; >> Some constants from the NSFileManager class <<

EnumerationBinary
  #NSDirectoryEnumerationSkipsSubdirectoryDescendants
  #NSDirectoryEnumerationSkipsPackageDescendants
  #NSDirectoryEnumerationSkipsHiddenFiles
EndEnumeration

Enumeration PlayState
  #stopped
  #paused
  #playing
EndEnumeration

NewList mp3list.s()
Global mp3Object


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

Procedure LoadMp3(File$)
    mp3Object = CocoaMessage(0, CocoaMessage(0, 0, "NSSound alloc"), "initWithContentsOfFile:$", @File$, "byReference:", #YES)
    CocoaMessage(0, mp3Object, "play")
EndProcedure


; >>> List all mp3 files in the current directory <<<

Procedure LoadDir(Folder$)

; >> Directory to examine none recursively <<

Directory.s = Folder$

; >> Unfiltered array of directory objects <<

UnfilteredArray.i = CocoaMessage(0, CocoaMessage(0, 0, "NSFileManager defaultManager"), "contentsOfDirectoryAtURL:",
                                 CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @Directory),
                                 "includingPropertiesForKeys:", #nil,
                                 "options:", #NSDirectoryEnumerationSkipsPackageDescendants |
                                             #NSDirectoryEnumerationSkipsHiddenFiles,
                                 "error:", #nil)

; >> Filter it for mp3 files <<

FilteredArray.i = CocoaMessage(0, UnfilteredArray,
                               "filteredArrayUsingPredicate:",
                               CocoaMessage(0, 0, "NSPredicate predicateWithFormat:$",
                                            @"pathExtension ==[c] 'mp3'",
                                            "argumentArray:", #nil))

; >> Get the number of mp3 files <<

FilteredArrayCount.i = CocoaMessage(0, FilteredArray, "count")

; >> Show path and duration for all mp3 files <<

i.i = 0
While i < FilteredArrayCount
 
  NSURLObject = CocoaMessage(0, FilteredArray, "objectAtIndex:", i)
  NSSound = CocoaMessage(0, CocoaMessage(0, 0, "NSSound alloc"),
                         "initWithContentsOfURL:", NSURLObject, "byReference:", #YES)
  CocoaMessage(@Mp3Duration.d, NSSound, "duration")
  CocoaMessage(0, NSSound, "release")
  Mp3Path.s = PeekS(CocoaMessage(0, CocoaMessage(0, NSURLObject, "path"), "UTF8String"), -1, #PB_UTF8)
 
  Debug  Mp3Path + "  [" + FormatDate("%hh:%ii:%ss", Mp3Duration) + "]"
 
  i + 1
Wend
EndProcedure

#FLAGS = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered

mainWin = OpenWindow(#PB_Any, 0, 0, 800, 380, "MP3 Player 0.1", #FLAGS)
SetWindowColor(mainWin, RGB(0,83,146))
AddWindowTimer(mainWin, 0, 1000)

loadBtn = ButtonGadget(#PB_Any, 20, 350, 100, 25, "Add")
stopBtn = ButtonGadget(#PB_Any, 130, 350, 100, 25, "Stop")
playBtn = ButtonGadget(#PB_Any, 240, 350, 100, 25, "Play")
pauseBtn = ButtonGadget(#PB_Any, 350, 350, 100, 25, "Pause")
exitBtn = ButtonGadget(#PB_Any, 460, 350, 100, 25, "Exit")

playlist = ListIconGadget(#PB_Any, 30, 10, 740, 300, "Song Title", 150, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_GridLines)

AddGadgetColumn(playlist, 1, "Bytes", 130)
AddGadgetColumn(playlist, 2, "Duration", 130)
AddGadgetColumn(playlist, 3, "Elapsed", 130)


; Start of main loop
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
    Case #PB_Event_Timer
      If mp3Object
        If Not CocoaMessage(0, mp3Object, "isPlaying")
          If state = #playing
            If Not NextElement(mp3list())
              FirstElement(mp3list())
            EndIf
            LoadMp3(mp3list())
            SetGadgetState(playlist, ListIndex(mp3list()))
          EndIf
        EndIf
      EndIf
      Case #PB_Event_Gadget
        Select EventGadget()
          Case loadBtn
            
            mp3File$ = OpenFileRequester("Select MP3 Track:", "", "MP3|*.mp3", 0)
           
            If mp3File$ <> ""
              AddGadgetItem(playlist, -1, GetFilePart(mp3File$, #PB_FileSystem_NoExtension))
              SetGadgetItemText(playlist, ListSize(mp3list()), FormatNumber(FileSize(mp3File$)), 1)
              ; get the duration time and release
             
;               mp3Obj = CocoaMessage(0, CocoaMessage(0, 0, "NSSound alloc"), "initWithContentsOfFile:$", @mp3File$, "byReference:", #YES)
;               CocoaMessage(@duration.d, mp3Obj, "duration")
;               CocoaMessage(0, mp3Obj, "release")
;              
;               ; now we publish the duration in the list
;               SetGadgetItemText(playlist, ListSize(mp3list()), FormatDate("%hh:%ii:%ss", duration), 2)
              AddElement(mp3list())
              mp3list() = mp3File$
             
              If ListSize(mp3list()) = 1
                SetGadgetState(playlist, 0)
               
              EndIf
            EndIf
           
          Case exitBtn
            Quit = #True
           
          Case stopBtn
            CocoaMessage(0, mp3Object, "stop")
            state = #stopped
           
          Case playBtn
            Select state
              Case #stopped
               SelectElement(mp3list(), GetGadgetState(playlist))
               LoadMp3(mp3list())
               state = #playing
            EndSelect
           
          Case pauseBtn
            Select state     
              Case #paused
                CocoaMessage(0, mp3Object, "resume")
                state = #playing
              Case #playing
                CocoaMessage(0, mp3Object, "pause")
                state = #paused
            EndSelect

          Case playlist
            If CountGadgetItems(playlist) > 0
              Select EventType()
                Case #PB_EventType_LeftClick
              EndSelect
            EndIf
            
        EndSelect
    EndSelect
  Until Quit
  CocoaMessage(0, mp3Object, "stop")
  CocoaMessage(0, mp3Object, "release")
  End
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

I find it hard to understand what you are exactly looking for.

If you want something to be done when the sound has finished, you can use a NSSoundDelegate.

If you don't mind targeting OSX 10.7+ you can also look at AVQueuePlayer instead of NSSound.
Maybe that does what you want. :?
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 »

Basically with some media players you can select a folder to play or just one file
so if you select a folder it will load all files that are MP3 files and start to play them.
or you can chose to add a single file to the playlist and just play that one

So the program must recognise when the first mp3 is loaded and start playing it and if there are more that one play the others in turn
till the end.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

If you don't have to navigate between the items you can consider AVQueuePlayer I mentioned before.
With the example below you can add multiple audio files that are played sequentially.

Code: Select all

; macOS 10.7+, x64

ImportC "-framework AVKit" : EndImport

Procedure AddAudioFile(Player, Filename.s)
  CocoaMessage(0, Player, "insertItem:", 
               CocoaMessage(0, 0, "AVPlayerItem playerItemWithURL:",
                            CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @Filename)),
               "afterItem:", #nil)
EndProcedure


Player = CocoaMessage(0, 0, "AVQueuePlayer new")
AddAudioFile(Player, "file1.mp3")
AddAudioFile(Player, "file2.wav")
AddAudioFile(Player, "file3.mp3")
CocoaMessage(0, Player, "play")

MessageRequester("", "Playing")
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 »

Thanks mate but it's not what i am after.
Have you ever used vlc? well with vlc you can just drag and drop a folder of mp3's on to it and starts playing the first song
this what i am looking for drag and drop or select the folder hope this helps, sorry for being a pain.
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: So Confused

Post by fsw »

@codeit,
What Wilbert showed you is the best way of doing it.

The only thing you have to do is:
1) Select a directory
2) Collect all file names
3) Make sure all files are valid audio files
4) With each file use Wilbert's AddAudioFile() function
5) Start playing files
6) Done

In regards to drag'n drop:
It doesn't work correctly on macOS in PureBasic.
There should be several topics about this on this forum.

I am to provide the public with beneficial shocks.
Alfred Hitshock
codeit
User
User
Posts: 62
Joined: Sat Apr 15, 2017 5:53 pm
Location: Leicestershire

Re: So Confused

Post by codeit »

Thanks guys for your help
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

If the recursion is the problem, you can try something like this.
If you don't need to support Windows, using Cocoa to scan directories recursively is a lot faster compared to using the PB methods.

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

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")


; >>> 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(0)
  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(0, i, s)
    SetGadgetItemData(0, i, *Item)
    i + 1
  Next
  SetGadgetState(0, -1)
EndProcedure



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

OpenWindow(0, 0, 0, 760, 420, "Playlist example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 10, 10, 740, 400, "Title", 220, #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()

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
Last edited by wilbert on Sat Jul 15, 2017 8:23 am, edited 3 times in total.
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

I updated my code in the previous post to be an almost complete example.
You can click a list item now and when it has finished playing, it will continue to the next one.
It also supports dropping files now.
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 »

Well lost for words your example is first class very confusing but brill at the same time
It does everything i was trying to do but looking at the code i can see why i was struggling.
You must have given up your free time to do this, all i can say is thank you very much Wilbert
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

codeit wrote:Well lost for words your example is first class very confusing but brill at the same time
It does everything i was trying to do but looking at the code i can see why i was struggling.
You must have given up your free time to do this, all i can say is thank you very much Wilbert
Sorry if the code is confusing. I know I'm not very good at producing commented code. :?
I hope it makes at least some sense.

It was a bit of a search how to get things working but it was also nice to play with the MetaData functions.
I have never used them before and they can be useful as well for retrieving information about images. :)
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 »

Hi Wilbert
I have been busy trying incorporate some of your code in to mine but with out much success.
I have been trying to select from ExplorerTree a music folder so i then click in the playlist to play an album or track.
Just to show where i am with it i have it zipped for you to look at.
https://www.dropbox.com/s/ylcyxye2zhax ... .zip?dl=0
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: So Confused

Post by wilbert »

codeit wrote:I have been trying to select from ExplorerTree a music folder so i then click in the playlist to play an album or track.
Just to show where i am with it i have it zipped for you to look at.
Nice layout :)
You might consider using the MetaData approach from my last example to get the duration of the mp3 files.

Here's your a modified version of your LoadDir procedure which does this

Code: Select all

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

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


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)
        Debug "---"
        
        CFRelease_(Mp3MetaData)
        i + 1
      Wend
    EndIf
  EndIf
  CocoaMessage(0, Pool, "release")
EndProcedure


LoadDir(GetCurrentDirectory())
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply