Использование Swift 4
Я работаю над диалоговым приложением. В настоящее время у меня есть приложение, записывающее аудио от пользователя с Speech API. Это работает, и я могу вести полноценную беседу туда и обратно без сбоев приложения, когда обратная связь отображается только в виде текста на экране. Я также хотел бы, чтобы текст был озвучен.
Например:
Шаг 1: Пользователь говорит: «Привет, как дела»
Шаг 2: Приложение отображает (в текстовом виде и голосом): "Хорошо, как ты?"
Шаг 3: Пользователь может сказать: "Хорошо, какого цвета небо?"
Step4: приложение отобразит ответ и обновит пользовательский интерфейс.
При интеграции текста в речь приложение в настоящее время аварийно завершает работу непосредственно перед шагом 3. Пользователь попытался вставить свой ответ, и приложение полностью вылетает с этой ошибкой:
"Завершение приложения из-за необработанного исключения 'com.apple.coreaudio.avfaudio', причина: 'обязательное условие: false: 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!)
}
Спасибо!