将用于语音的 AppleScript 转换为 Swift

Convert AppleScript for speech to Swift

我想将此 AppleScript 转换为 Swift。

其中输入是字符串 (myText: String),输出是变速朗读的字符串 (readingSpeed: Int)。

A​​ppleScript:

on run {input, parameters}
    say input using "Alex" speaking rate 540

    return input
end run

我曾考虑过使用 SpeakCFString,但无法实现。

这里有两种方法,一种使用 shell 任务调用 say,另一种使用 NSSpeechSynthesizer class.

NSTask 实现:

import Foundation

let input = Process.arguments[1..<Process.arguments.count].joinWithSeparator(" ")

let task = NSTask()
task.launchPath = "/usr/bin/say"
task.arguments = ["-v", "alex", input]

task.launch()
task.waitUntilExit()

print(input)
exit(task.terminationStatus)

NSSpeechSynthesizer 实现:

import Foundation
import AppKit

class Speaker {
    var synth: NSSpeechSynthesizer!
    var speaking: Bool {
        get {
            return synth.speaking
        }
    }

    init() {
        setupSynth(nil)
    }

    init(voice: String?) {
        setupSynth(voice)
    }

    func setupSynth(voice: String?) {
        var voice = voice
        if voice == nil {
            voice = NSSpeechSynthesizer.availableVoices()[0]
        }

        synth = NSSpeechSynthesizer(voice: voice)
    }

    func say(text: String) -> Bool {
        return synth.startSpeakingString(text)
    }
}

func say(text: String) -> Bool {
    let speaker = Speaker()

    if (speaker.say(text)) {
        let loop = NSRunLoop.currentRunLoop()
        let mode = loop.currentMode ?? NSDefaultRunLoopMode
        while loop.runMode(mode, beforeDate: NSDate(timeIntervalSinceNow: 0.1)) && speaker.speaking {}
        return true
    }
    return false
}

let input = Process.arguments[1..<Process.arguments.count].joinWithSeparator(" ")
say(input)
print(input)

你可以用同样的方式 运行 这两个:

$ swift speak.swift hello world