怎么做"说"在Swift 3里面的命令行程序?

时间:2017-02-16 18:16:25

标签: swift macos

在这种情况下,我应该使用以下代码做什么?

func convertToM4A(filename: String, voice: String) -> Bool {

    let full_string = speaking_queue?.joined(separator: " ")
    let command_string: [String] = [/"-v \"\(voice)\"",*/ "--progress", "--output-file=\"\(filename)\"","-i", " \"\(full_string!)\""]
    print(command_string)

    /
    let DocumentsDirectory = FileManager().homeDirectory(forUser: "shyamalchandra")
    print((DocumentsDirectory?.absoluteString)!)
    */

    let task = Process()

    task.launchPath = "/usr/bin/say"
    task.arguments = command_string
    let pipe = Pipe()
    task.standardOutput = pipe
    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output: String? = String(data: data, encoding: String.Encoding.utf8)
    task.waitUntilExit()

    if let output = output {
        if !output.isEmpty {
            print(output.trimmingCharacters(in: .whitespacesAndNewlines))
        }
    }

    return true
}

在运行时,它抱怨没有设置TERM环境,而且,不会将文件写入磁盘。怎么办?

3 个答案:

答案 0 :(得分:1)

主要错误是如何构建参数数组。给定的论点 直接传递给流程。 Process不使用shell 解释参数,因此您不能将它们括在引号中 标记。

另一个问题是" -i" (交互式)选项不能使用 写入文件时。

所以你的代码应该是这样的:

func convertToM4A(filename: String, voice: String) -> Bool {

    let fullString = "Hello world"

    let task = Process()
    task.launchPath = "/usr/bin/say"
    task.arguments = [ "-v", voice, "-o", filename, fullString]

    task.launch()
    task.waitUntilExit()

    return true
}

" - 进步"选项会导致显示进度表 标准错误。如果你想显示那么你必须 从标准错误中读取异步

答案 1 :(得分:1)

如果您正在编写本机Mac应用并希望将合成语音记录到音频文件中,请不要尝试包装shell命令 - 这是本机API 为了那个原因。 NSSpeechSynthesizer是一般用于文本转语音的macOS API,它有一个方法startSpeaking(_:to:),可以将输出记录到音频文件中。

此API输出到AIFF文件,但有许多API可用于将其转换/编码为M4A:AVAssetReader / AVAssetWriterAVAudioFile,较低级别的CoreAudio C API等

(通常,如果您正在编写本机Mac程序并且有想要做的事情,请在尝试包装shell命令之前检查是否有API。通常这些shell命令使用相同的API,所以你只是用所有的间接,I / O解析等来惩罚自己。)

是的,NSSpeechSynthesizer是一个AppKit API,但您可以在命令行工具中使用它。

答案 2 :(得分:0)

看看这个lib,之前我已经使用过它,它非常能够运行shell脚本。有了它,那么你可以使用"说"命令并发送一些参数。 https://github.com/kareman/SwiftShell

你可以这样试试

import SwiftShell

try runAndPrint("say", "Hello world", 4, "arguments")

let array = ["Hello world", "we", "are"]
try runAndPrint("say", array, array.count + 2, "arguments")