NSSpeechSynthesizer保存到URL

时间:2016-02-11 06:34:15

标签: multithreading swift macos grand-central-dispatch text-to-speech

我正在创建一个MacOS应用程序,该应用程序从制表符分隔的文本文件生成对话框文件。文本文件格式为(输出文件名)[tab](与该文件说话的文本)。我让程序在主线程中完美运行,但这当然阻止了UI。当我将应用程序的内容移动到用户启动的线程时,我取消阻止了UI,但现在它偶尔会随机地说出扬声器而不是文件。仍然会创建一个文件,但它的持续时间为零。如果脚本包含1,000行,那么它可能会完美地完成整个过程,或者它可能会#34;说"他们中的十个或更多是说话人。它每次几乎总是不同的线。

这是与文件对话的代码:

// Set URL to save file to disk
if let speechFileURL = NSURL(string: speechFilePath) {
    speechSynth.startSpeakingString(spokenText, toURL: speechFileURL)  // Speak to file
}
else {
    dialogAlert("Invalid File: ", text: speechFileName)
}

while(NSSpeechSynthesizer.isAnyApplicationSpeaking() == true) {
    if self.gUserClickedStop {
        speechSynth.stopSpeaking()
        self.gIsSpeaking = false
        break
    }
}

这是对解析脚本并生成语音文件的函数的调用:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] in
    self.parseTheScript()
}

如上所述,调用parseTheScript()而不将其包装在Grand Central Dispatch调用中使其完美地工作,除了阻塞问题。

我刚接触Swift的编程和多线程编程的想法,所以我确定我做错了什么,但我很难解决如何解决这个问题

提前感谢您的帮助。

编辑以添加...

这是解析文本文件并生成对话文件的整个函数:

    // This opens the text file and generates the spoken audio files
func parseTheScript() {
    let filemgr = NSFileManager.defaultManager()
    print("Chosen path: \(scriptFileTextField.stringValue)")   // debug
    if filemgr.fileExistsAtPath(scriptFileTextField.stringValue) {
        print("File exists")
        do {
            outputFilename.stringValue = ""
            scriptToSpeak.stringValue = ""
            outputFilename.hidden = false
            scriptToSpeak.hidden = false
            progressBar.minValue = 0
            progressBar.doubleValue = 0.0
            progressBar.hidden = false
            filenameLabel.hidden = false

            let text = try String(contentsOfFile: scriptFileTextField.stringValue, encoding: NSUTF8StringEncoding)
            let lines: [String] = text.componentsSeparatedByString("\n")
            var progressEndValue = Double(lines.count)
            progressBar.maxValue = progressEndValue

            let speechSynth = NSSpeechSynthesizer.init()
            let theVoice = gVoiceList[voiceListPopup.indexOfSelectedItem - 1]   // Not sure why it's off by one
            speechSynth.setVoice(theVoice)

            for line in lines {
                let thisLine: [String] = line.componentsSeparatedByString("\t") // Split the line at the tab character
                if (thisLine.count == 2) {                  // Did the line split into two parts?
                    let speechFileName = thisLine[0]
                    let spokenText = thisLine[1]
                    outputFilename.stringValue = speechFileName
                    scriptToSpeak.stringValue = spokenText
                    let speechFilePath = destinationFolderTextField.stringValue + speechFileName + ".aif"        // Build the path string for the output speech file
                    print("Filename: \(speechFilePath)")
                    print("SpokenText: \(spokenText)")

                    if(gSpeakToFile) {
                        // Set URL to save file to disk
                        if let speechFileURL = NSURL(string: speechFilePath) {
                            speechSynth.startSpeakingString(spokenText, toURL: speechFileURL)  // Speak to file
                        }
                        else {
                            dialogAlert("Invalid File: ", text: speechFileName)
                        }
                    }
                    else {
                        speechSynth.startSpeakingString(spokenText) // Speak to audio output
                    }

                    while(NSSpeechSynthesizer.isAnyApplicationSpeaking() == true) {
                        if self.gUserClickedStop {
                            speechSynth.stopSpeaking()
                            self.gIsSpeaking = false
                            break
                        }
                    }

                    progressBar.incrementBy(1.0)
                }
                if gUserClickedStop {
                    gUserClickedStop = false
                    gIsSpeaking = false
                    progressEndValue = 0
                    generateButton.title = "Start"
                    break
                }

            }
            gIsSpeaking = false
            progressBar.doubleValue = progressEndValue
            generateButton.title = "Start"
            filenameLabel.hidden = true
            outputFilename.stringValue = ""
            scriptToSpeak.stringValue = ""

        } catch let error as NSError {
            dialogAlert("Error:", text: String(error.localizedDescription))
            print("Error: \(error)")
        }
    } else {
        print("File does not exist")
    }

}

0 个答案:

没有答案