有没有一种方法可以在同一视图控制器中利用文本进行语音转换和语音转换?

时间:2019-05-20 19:32:03

标签: ios swift text-to-speech speech-to-text

使用Swift 4

我正在研究会话应用程序。当前,我有该应用程序使用Speech API记录来自用户的音频。它可以正常工作,我可以来回进行完整的对话,而不会导致应用程序崩溃,并且反馈仅以文本形式显示在屏幕上。我也想说一下文字。

例如: 第1步:用户说:“你好,你好吗” 第2步:应用程序(以文本视图和语音显示):“很好,你好吗?” 第3步:用户可以说:“很好,天空是什么颜色?” 第4步::该应用将显示响应并更新用户界面。

将文本集成到语音中时,该应用程序当前在步骤3之前崩溃。用户尝试输入响应,该应用程序完全崩溃,并出现以下错误:

“由于未捕获的异常'com.apple.coreaudio.avfaudio'而终止应用程序,原因:'所需条件为假:format.sampleRate == hwFormat.sampleRate'”

我已经设置了一个断点并遍历了代码。它总是在这里崩溃:

node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, time) in
    self.request.append(buffer)
}

此外,我可以使它正常运行而不会崩溃,但是它只能通过电话上的耳机播放音频。

func mic_Action(_ sender: Any) {
    synthesizer?.stopSpeaking(at: .immediate)
    if isRecording == false {
        textView.text = "Listening..."
        recordAndRecognizeSpeech()
    } else {
        isRecording = false
        audioEngine.stop()
        recognitionTask?.finish()
        audioEngine.inputNode.removeTap(onBus: 0)
        //NLP API
        callAPI()
    }

func recordAndRecognizeSpeech() {
    let node = audioEngine.inputNode
    let recordingFormat = node.outputFormat(forBus: 0)
    node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, time) in
        self.request.append(buffer)
    }

    audioEngine.prepare()
    do {
        try audioEngine.start()
    } catch {
        return print(error)
    }

    guard let myRecognizer = SFSpeechRecognizer() else { return }
    if !myRecognizer.isAvailable { return }
    isRecording = true
    promptLabel.isHidden = true

    recognitionTask = speechRecognizer?.recognitionTask(with: request, resultHandler: { (result, error) in
        if let result = result {
            let bestString = result.bestTranscription.formattedString
            self.textView.text = bestString.quoted
        } else if let error = error {
            print(error)
        }
    })
}

func callAPI() {
    let apiService = apiService()
    guard
        let query = textView.text,
        let sessionId = self.sessionId
        else { return }
    apiService.sendInteraction(query: query, sessionId: sessionId) { (error, response) in
        if let err = error {
            print(err.domain)
            print(err.code)
        } else {
            guard let response = response else { return }
            print("INTERACTION SUCCESSFUL")
            DispatchQueue.main.async {
                self.voiceFeedback(response.ResponseText)
                self.updateView(response)
                print(response)
            }
        }
    }
}

func voiceFeedback(_ utterance: String) {
    audioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession?.setMode(AVAudioSession.Mode.spokenAudio)
        try audioSession?.setActive(true, options: [.notifyOthersOnDeactivation])
        try audioSession?.setCategory(AVAudioSession.Category.playAndRecord, options:AVAudioSession.CategoryOptions.defaultToSpeaker)
    } catch {
        print("audioSession properties weren't set because of an error.")
    }

    self.utterance = AVSpeechUtterance(string: utterance)
    self.utterance?.voice = AVSpeechSynthesisVoice(language: "en-GB")

    synthesizer = AVSpeechSynthesizer()
    synthesizer?.speak(self.utterance!)

}

谢谢!

0 个答案:

没有答案