Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terminating app due to uncaught App crashes while using Speech kit ios

I got this error while implementing speech to text:

Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: _recordingTap == nil'

and:

ERROR: [0x1b2df5c40] >avae> AVAudioNode.mm:565: CreateRecordingTap: required condition is false: _recordingTap == nil

Here is the code of my viewController:

public class ViewController: UIViewController, SFSpeechRecognizerDelegate { // MARK: Properties  private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))!  private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?  private var recognitionTask: SFSpeechRecognitionTask?  private let audioEngine = AVAudioEngine()  @IBOutlet var textView : UITextView!  @IBOutlet var recordButton : UIButton!  // MARK: UIViewController  public override func viewDidLoad() {     super.viewDidLoad()      // Disable the record buttons until authorization has been granted.     recordButton.isEnabled = false }  override public func viewDidAppear(_ animated: Bool) {     speechRecognizer.delegate = self      SFSpeechRecognizer.requestAuthorization { authStatus in         /*             The callback may not be called on the main thread. Add an             operation to the main queue to update the record button's state.         */         OperationQueue.main.addOperation {             switch authStatus {                 case .authorized:                     self.recordButton.isEnabled = true                  case .denied:                     self.recordButton.isEnabled = false                     self.recordButton.setTitle("User denied access to speech recognition", for: .disabled)                  case .restricted:                     self.recordButton.isEnabled = false                     self.recordButton.setTitle("Speech recognition restricted on this device", for: .disabled)                  case .notDetermined:                     self.recordButton.isEnabled = false                     self.recordButton.setTitle("Speech recognition not yet authorized", for: .disabled)             }         }     } }  private func startRecording() throws {      // Cancel the previous task if it's running.     if let recognitionTask = recognitionTask {         recognitionTask.cancel()         self.recognitionTask = nil     }      let audioSession = AVAudioSession.sharedInstance()     try audioSession.setCategory(AVAudioSessionCategoryRecord)     try audioSession.setMode(AVAudioSessionModeMeasurement)     try audioSession.setActive(true, with: .notifyOthersOnDeactivation)      recognitionRequest = SFSpeechAudioBufferRecognitionRequest()      guard let inputNode = audioEngine.inputNode else { fatalError("Audio engine has no input node") }     guard let recognitionRequest = recognitionRequest else { fatalError("Unable to created a SFSpeechAudioBufferRecognitionRequest object") }      // Configure request so that results are returned before audio recording is finished     recognitionRequest.shouldReportPartialResults = true      // A recognition task represents a speech recognition session.     // We keep a reference to the task so that it can be cancelled.     recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in         var isFinal = false          if let result = result {             self.textView.text = result.bestTranscription.formattedString             isFinal = result.isFinal         }          if error != nil || isFinal {             self.audioEngine.stop()             inputNode.removeTap(onBus: 0)              self.recognitionRequest = nil             self.recognitionTask = nil              self.recordButton.isEnabled = true             self.recordButton.setTitle("Start Recording", for: [])         }     }      let recordingFormat = inputNode.outputFormat(forBus: 0)     inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in         self.recognitionRequest?.append(buffer)     }      audioEngine.prepare()      try audioEngine.start()      textView.text = "(Go ahead, I'm listening)" }  // MARK: SFSpeechRecognizerDelegate  public func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {     if available {         recordButton.isEnabled = true         recordButton.setTitle("Start Recording", for: [])     } else {         recordButton.isEnabled = false         recordButton.setTitle("Recognition not available", for: .disabled)     } }  // MARK: Interface Builder actions  @IBAction func recordButtonTapped() {     if audioEngine.isRunning {         audioEngine.stop()         recognitionRequest?.endAudio()         recordButton.isEnabled = false         recordButton.setTitle("Stopping", for: .disabled)     } else {         try! startRecording()         recordButton.setTitle("Stop recording", for: [])     } } } 
like image 886
Waris Shams Avatar asked Jan 03 '17 07:01

Waris Shams


1 Answers

You can try to use it on stop recording

Swift 3:

audioEngine.inputNode?.removeTap(onBus: 0) 

It's helped me and should help you too.

like image 65
Evsenev Avatar answered Sep 23 '22 11:09

Evsenev