重启录制时AVAudioEngine inputNode installTap崩溃

我正在我的应用程序中实现语音识别。 当我第一次使用语音识别逻辑呈现视图控制器时,一切正常。 但是,当我再次尝试呈现视图控制器时,我得到以下崩溃:

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)' 

以下是用于启动和停止录制的代码:

 @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() } } 

一旦我们请求授权,就会在viewDidLoad中调用startRecording()stopRecording()视图控制器时调用stopRecording()

请协助。 我很难找到这个崩溃的解决方案

您可以替换此代码:

 let recordingFormat = node.outputFormat(forBus: 0) 

以下内容:

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

此代码修复了该问题。

首先,一个小问题。 点击设备的麦克风时,您需要使用输入总线的格式:

 let recordingFormat = node.inputFormat(forBus: 0) 

其次,经过一些挖掘后,这种崩溃似乎最常见于应用程序的共享AVAudioSession类别设置。 如果您要进行实时麦克风音频处理,请确保您的音频会话配置如下:

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