AVAudioEngine inputNode installTap crash when restarting recording

空扰寡人 提交于 2019-12-18 04:40:07

问题


I am implementing Speech Recognition in my app. When I first present the view controller with the speech recognition logic, everything works fine. However, when I try present the view controller again, I get the following crash:

ERROR:    [0x190bf000] >avae> AVAudioNode.mm:568: CreateRecordingTap: required condition is false: IsFormatSampleRateAndChannelCountValid(format)
*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: IsFormatSampleRateAndChannelCountValid(format)'

Here is the code used for starting and stopping recording:

@available(iOS 10.0, *)
extension DictationViewController {

fileprivate func startRecording() throws {
    guard let recognizer = speechRecognizer else {
        debugLog(className, message: "Not supported for the device's locale")
        return
    }

    guard recognizer.isAvailable else {
        debugLog(className, message: "Recognizer is not available right now")
        return
    }

    mostRecentlyProcessedSegmentDuration = 0
    guard let node = audioEngine.inputNode else {
        debugLog(className, message: "Could not get an input node")
        return
    }

    let recordingFormat = node.outputFormat(forBus: 0)
    node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { [weak self] (buffer, _) in
        self?.request.append(buffer)
    }

    audioEngine.prepare()
    try audioEngine.start()

    recognitionTask = recognizer.recognitionTask(with: request, resultHandler: {/***/})
}

fileprivate func stopRecording() {
    audioEngine.stop()
    audioEngine.inputNode?.removeTap(onBus: 0)
    request.endAudio()
    recognitionTask?.cancel()
}

}

startRecording() is called in viewDidLoad once we have requested authorization. stopRecording() is called when the view controller is dismissed.

Please assist. I'm struggling to find a solution to this crash


回答1:


First, a small issue. When tapping the device's microphone, you'll want to use the format of the input bus:

let recordingFormat = node.inputFormat(forBus: 0)

Second, after some digging it seems like this crash most commonly stems from your application's shared AVAudioSession category settings. Make sure you have your audio session configured like so if you're going to be performing live microphone audio processing:

private func configureAudioSession() {
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .mixWithOthers)
        try AVAudioSession.sharedInstance().setActive(true)
    } catch { }
}



回答2:


You can replace this code:

let recordingFormat = node.outputFormat(forBus: 0)

with the following:

let recordingFormat = AVAudioFormat(standardFormatWithSampleRate: 44100, channels: 1)

This code fixed the problem.




回答3:


There are two possible ways to solve this problem.

  1. Check inputFormat.channelCount. It may be throwing the error because the mic is in use in another application or somewhere else you yours.
if(inputNode.inputFormat(forBus: 0).channelCount == 0){
    NSLog("Not enough available inputs!")
    return
}
  1. Try to reset the audioEngine.
audioEngine.reset()


来源:https://stackoverflow.com/questions/41805381/avaudioengine-inputnode-installtap-crash-when-restarting-recording

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!