web-dev-qa-db-ja.com

録音を再開すると、AVAudioEngine inputNodeinstallTapがクラッシュする

アプリに音声認識を実装しています。ビューコントローラに音声認識ロジックを最初に提示したとき、すべてが正常に機能します。ただし、View Controllerを再度提示しようとすると、次のクラッシュが発生します。

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

}
_

startRecording()は、認証をリクエストすると、viewDidLoadで呼び出されます。 stopRecording()は、ViewControllerが閉じられたときに呼び出されます。

手伝ってください。このクラッシュの解決策を見つけるのに苦労しています

13
Appache99

まず、小さな問題です。デバイスのマイクをタップするときは、入力バスの形式を使用する必要があります。

let recordingFormat = node.inputFormat(forBus: 0)

第二に、掘り下げた後、このクラッシュは最も一般的にはアプリケーションの共有AVAudioSessionカテゴリ設定に起因するようです。ライブマイクオーディオ処理を実行する場合は、オーディオセッションが次のように構成されていることを確認してください。

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

このコードを置き換えることができます:

let recordingFormat = node.outputFormat(forBus: 0)

次のように:

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

このコードは問題を修正しました。

2
Selva Murugan

この問題を解決するには、2つの方法があります。

  1. 小切手 inputFormat.channelCount。マイクが別のアプリケーションまたは他の場所で使用されているため、エラーがスローされている可能性があります。
if(inputNode.inputFormat(forBus: 0).channelCount == 0){
    NSLog("Not enough available inputs!")
    return
}
  1. audioEngineをリセットしてみてください。
audioEngine.reset()
1