Play sound with AppleScript using afplay and relative file path

2.2k views Asked by At

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
2

There are 2 answers

0
AudioBubble On BEST ANSWER

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
2
regulus6633 On

You have your paths all messed up. Applescript doesn't use "posix paths" so you can't pass that type of path to applications such as the Finder. Shell scripts do use posix paths and you have to quote them.

In addition for applescript, whenever your path is in string format you must put the word "file" or "folder" in front of the path before you use it so that applescript can understand it's an object to be acted upon otherwise applescript just treats it like a string. Also string paths in applescript should be colon delimited (:) rather than slash delimited (/). Finally applescript paths start with the name of your hard drive such as "Macintosh HD".

You can see you must treat paths in applescript much differently than you do with the shell. Anyway, I didn't test this code but using those basic rules this should work. Good luck.

set theNumber to 3

set theFiles to {}
repeat
    set file_path to (path to me) as text
    set file_dir to file_path & ":sounds_dir:"
    tell application "Finder" to set aFile to (some file of folder file_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 " & quoted form of POSIX path of aFile & " > /dev/null 2>&1 &"
    end if
    if (count of theFiles) is equal to theNumber then exit repeat
end repeat