Запустите микрофон с помощью намерений приложения «необходимое условие ложно: IsFormatSampleRateAndChannelCountValid(формат)»

Я хочу включить распознавание речи в свое приложение, для этого я использовал Speech Framework от Apple в сочетании с App Intents Framework. Намерение приложения «Слушать» запускает распознавание речи. Теперь у меня проблема, что я продолжаю получать следующее сообщение об ошибке:

      *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio',      reason: 'required condition is false: IsFormatSampleRateAndChannelCountValid(format)'
 terminating with uncaught exception of type NSException

в следующей строке:

       self.audioEngine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
            self.recognitionRequest?.append(buffer)
    }

Эта проблема не возникает, когда я выполняю тот же код простым нажатием кнопки, но ONYL с намерением приложения «Слушать». Я знаю, что есть проблема с микрофоном, который Siri использует при прослушивании намерения приложения. Но как я могу решить эту проблему? Я провел много исследований, а также попробовал это с асинхронными функциями, но это не помогло.

Мой код:

      import Speech
import UIKit

class TestVoice: UIControl, SFSpeechRecognizerDelegate {    
let speechRecognizer        = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))
   var recognitionRequest      : SFSpeechAudioBufferRecognitionRequest?
   var recognitionTask         : SFSpeechRecognitionTask?
   let audioEngine             = AVAudioEngine()


func stopRecording() {
    self.audioEngine.stop()
    self.recognitionRequest?.endAudio()
}

func setupSpeech() {
    
       self.speechRecognizer?.delegate = self
       SFSpeechRecognizer.requestAuthorization { (authStatus) in

           switch authStatus {
               case .authorized:
                   print("yes")
               case .denied:
                   print("died")
               case .restricted:
                   print("died")
               case .notDetermined:
                   print("none")
           }
           OperationQueue.main.addOperation() {
           }
       }
   }


func startRecording() -> Bool {
        setupSpeech()
        clearSessionData()
        createAudioSession()
        recognitionRequest = bufferRecRequest()
        recognitionRequest?.shouldReportPartialResults = true
        self.recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest!, resultHandler: { (result, error) in
            
            var finished = false
            
            if let result = result {
                //do something
                finished = result.isFinal
            }
            
            if error != nil || finished {
                self.audioEngine.stop()
                self.audioEngine.inputNode.removeTap(onBus: 0)
                self.recognitionRequest = nil
                self.recognitionTask = nil
            }
        })
        
    
    let recordingFormat = self.audioEngine.inputNode.outputFormat(forBus: 0)
    self.audioEngine.inputNode.installTap(onBus: 0, bufferSize: 2048, format: recordingFormat) { (buffer, when) in
            self.recognitionRequest?.append(buffer)
    }
        
        self.audioEngine.prepare()
        
        do {
            try self.audioEngine.start()
        } catch {
            print("audioEngine couldn't start because of an error.")
            delegate?.showFeedbackError(title: "Sorry", message: "Your microphone is used somewhere else")
            return false
        }
    return true
    }

func clearSessionData(){
    if recognitionTask != nil {
        recognitionTask?.cancel()
        recognitionTask = nil
    }
}

func bufferRecRequest()->SFSpeechAudioBufferRecognitionRequest{
    self.recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
    guard let recognitionRequest = recognitionRequest else {
        fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")
    }
    return recognitionRequest
}

func createAudioSession()-> Bool{
    
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord, options: .mixWithOthers)
        
    } catch {
        print("audioSession properties weren't set because of an error.")
        delegate?.showFeedbackError(title: "Sorry", message: "Mic is busy")
        return false
    }
    return true
}
}

Цель приложения

       import AppIntents
 import UIKit


 struct ListenIntent: AppIntent {
     static var openAppWhenRun: Bool = true

    @available(iOS 16, *)
     static let title: LocalizedStringResource = "Listen"
     static var description =
        IntentDescription("Listens to the User")
     let speechRecognizer = TestVoice()

     func perform() throws -> some IntentResult & ProvidesDialog {
         speechRecognizer.startRecording()
         return .result(dialog: "Done")
        
}}

0 ответов

Другие вопросы по тегам