Search code examples
macosapplescriptfinder

Play sound with AppleScript using afplay and relative file path


I'm trying to create an AppleScript that uses afplay (as suggested here) to play a random sound file that's located in a directory within the same directory as the script.

folder
-- applescript.scpt
-- sounds
----- sound-x.aiff

I found this comment regarding relative paths to be potentially useful:

 (POSIX path of (path to me))

However, I keep receiving errors when I try mashing it up with this approach for randomness...

set theNumber to 3

set theFiles to {}
repeat
    set file_path to quoted form of (POSIX path of (path to me))
    tell application "Finder" to set aFile to (some file of file_path & "/sounds_dir") as text
    if aFile is not in theFiles then
        set end of theFiles to aFile
        tell application "Finder" to open file aFile
        do shell script ("afplay " & file_path & " > /dev/null 2>&1 &")
    end if
    if (count of theFiles) is equal to theNumber then exit repeat
end repeat

Solution

  • In a script, path to me returns the path to the script file but we need its parent path to add a sub path.


    To compose the correct path, we can use the subroutine composeFilePath(fileName).


    The main action is in the repeat loop. I also added a delay so it's easier to test. Save the script before using since path to me will return a wrong path when its unsaved.

    set LOOPS to 3
    set soundFolderName to "sounds_dir"
    
    # ---------------------
    # SETUP 
    # ---------------------
    set soundFolderFullPath to my composeFilePath(soundFolderName)
    
    tell application "Finder"
    
        if folder soundFolderFullPath exists then
    
            set soundFolder to (folder soundFolderFullPath)
    
        else
            set soundFolder to ""
            # Customize action when folder does not exist
            beep
            log "*** Error: folder " & quoted form of soundFolderFullPath & " missing!"
            return
        end if
    
        if (count files in soundFolder) is 0 then
            # Customize action when folder has no items in it
            beep
            log "*** Error: No items in " & quoted form of soundFolderFullPath & " !"
            return
        end if
    
    end tell
    
    # -------------------------------------------
    # We have "soundFolder" and it has items in it
    # -------------------------------------------
    
    repeat LOOPS times
    
        # PLAY RANDOM FILE
    
        # As ONE LINER:
        ## do shell script "/usr/bin/afplay " & quoted form of (POSIX path of ((some file of soundFolder) as text)) & " > /dev/null 2>&1 &"
    
        # Step By Step
        set aRandomFile to some file of soundFolder
        set aRandomFile to POSIX path of (aRandomFile as text)
    
        set shellScript to "/usr/bin/afplay " & quoted form of aRandomFile & " > /dev/null 2>&1 &"
        do shell script shellScript
    
        delay 1
    
    end repeat
    
    
    
    
    on composeFilePath(fileName)
        if fileName is "" then return ""
        set pathToMe to path to me -- this is the full path to this script
        -- get the folder this script is in:
        set thisScriptsFolder to ""
        tell application "Finder"
            try
                set thisScriptsFolder to (get container of pathToMe) as text
            end try
        end tell
        if thisScriptsFolder is "" then
            return ""
        end if
        return thisScriptsFolder & fileName -- full path
    end composeFilePath