使用 afplay 和相对文件路径通过 AppleScript 播放声音

Play sound with AppleScript using afplay and relative file path

我正在尝试创建一个使用 afplay(如 suggested here)的 AppleScript 来播放随机声音文件,该文件位于与脚本相同的目录中。

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

我发现 this comment 关于相对路径可能有用:

 (POSIX path of (path to me))

但是,当我尝试将其与 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

你的路径全乱了。 Applescript 不使用 "posix paths",因此您无法将这种类型的路径传递给 Finder 等应用程序。 Shell 脚本确实使用 posix 路径,您必须引用它们。

此外,对于 applescript,只要您的路径是字符串格式,您必须在使用前在路径前面加上 "file" 或 "folder" 一词,以便 applescript 可以理解它是一个对象要采取行动,否则 applescript 会将其视为字符串。此外,applescript 中的字符串路径应该以冒号分隔 (:) 而不是斜线分隔 (/)。最后 applescript 路径以您的硬盘驱动器名称开头,例如 "Macintosh HD".

您可以看到,在 applescript 中处理路径的方式与在 shell 中的处理方式大不相同。无论如何,我没有测试这段代码,但使用这些基本规则应该可以。祝你好运。

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

scriptpath to me return 中 pathscript file 但我们 需要 parent path 添加一个 sub path.


要编写正确的路径,我们可以使用子例程


主要动作在重复循环中。我还添加了一个 delay 以便更容易测试。 使用前先保存脚本,因为 path to me 未保存时会 return 路径错误。

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