当我连续点击启动和停止操作时,我的应用程序崩溃了.我从事语音识别工作



这是我使用Speech框架实现语音到文本转换的类代码。但每当我连续按下stop_start操作时,我的应用程序就会崩溃,我会收到这个错误-Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'SFSpeechAudioBufferRecognitionRequest cannot be re-used'

import UIKit
import Speech
class ViewController: UIViewController ,SFSpeechRecognizerDelegate {

//MARK:- IBOutlet
@IBOutlet weak var textViewAudioText: UITextView!
@IBOutlet weak var btn_start: UIButton!

//MARK: - Local Properties
let audioEngine = AVAudioEngine()
let speechReconizer : SFSpeechRecognizer? = SFSpeechRecognizer()
let requestSFSpeech = SFSpeechAudioBufferRecognitionRequest()
var task : SFSpeechRecognitionTask!
var isStart : Bool = false

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.requestPermission()
}

func requestPermission(){
self.btn_start.isUserInteractionEnabled = false
SFSpeechRecognizer.requestAuthorization { authStatus in
OperationQueue.main.addOperation {
if authStatus == SFSpeechRecognizerAuthorizationStatus.authorized {
print("Accepted")
self.btn_start.isUserInteractionEnabled = true
} else if authStatus == .denied{
print("user denied permission")
} else if authStatus == .notDetermined{
print("Device does not have functionality")
} else if authStatus == .restricted{
print("user restricted")
}
}
}

}

}
//MARK:- UIBUtton Action
extension ViewController{
@IBAction func actionGetTextFromAudio(_ sender: UIButton) {
self.convertAudioFileToText()
}

@IBAction func btn_start_stop(_ sender: UIButton) {
//MARK:- Coding for start and stop sppech recognization...!
self.isStart = !self.isStart
if self.isStart {
self.convertSpeechToText()
self.btn_start.setTitle("STOP", for: .normal)
self.btn_start.backgroundColor = .systemGreen
} else {
self.cancelSpeechRecognization()
self.btn_start.setTitle("START", for: .normal)
self.btn_start.backgroundColor = .systemOrange
}
}
}

//MARK:- METHOD CONVERT AUDIO TO TEXT
extension ViewController {

func convertAudioFileToText() {            
let audioURL = Bundle.main.url(forResource: "test1", withExtension: "mp3")

let extractedExpr: SFSpeechRecognizer? = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))
let recognizer = extractedExpr
let request = SFSpeechURLRecognitionRequest(url: audioURL!)

request.shouldReportPartialResults = true

if (recognizer?.isAvailable)! {
recognizer?.recognitionTask(with: request) { result, error in
guard error == nil else { print("Error: (error!)"); return }
guard let result = result else { print("No result!"); return }

print(result.bestTranscription.formattedString)
self.textViewAudioText.text = result.bestTranscription.formattedString
}
} else {
print("Device doesn't support speech recognition")
}
}

/*
1. First get audio url from where you have store audio file.
2. Then create instance of SFSpeechRecognizer with locale that you have want.
3. Create instance of SFSpeechURLRecognitionRequest which are used to requesting recognitionTask.

4.  recognitionTask will give you result and error. Where result contains bestTranscription.formattedString. formmatedString is your test result of audio file.

5.  If set request.shouldReportPartialResults = true,
this will give your partial result of every line speak in audio.
*/


}

extension ViewController{
//MARK: UPDATED FUNCTION

func cancelSpeechRecognization() {
task.finish()
requestSFSpeech.endAudio()
audioEngine.stop()

if audioEngine.inputNode.numberOfInputs > 0 {
audioEngine.inputNode.removeTap(onBus: 0)
}
self.textViewAudioText.text = ""
}


func convertSpeechToText() {
let node = audioEngine.inputNode
let recordingFormat = node.outputFormat(forBus: 0)

node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, _) in
self.requestSFSpeech.append(buffer)
}

audioEngine.prepare()
do {
try audioEngine.start()
} catch let error {
print("Error comes here for starting the audio listner (error.localizedDescription)")
}

guard let myRecognization = SFSpeechRecognizer() else {
print("Recognization is not allow on your local")
return
}

if !myRecognization.isAvailable {
print("Recognization is free right now, Please try again after some time.")
}

task = speechReconizer?.recognitionTask(with: requestSFSpeech, resultHandler: { (response, error) in
guard let response = response else {
if error != nil {
print(error.debugDescription)

}else {
print("Problem in giving the response")
}
return
}

let message = response.bestTranscription.formattedString
print("Message : (message)")
self.textViewAudioText.text = message
})
}

}

可能需要停止语音识别任务。试试这个可能有助于

if audioEngine.inputNode.numberOfInputs > 0 {
audioEngine.inputNode.removeTap(onBus: 0)
}

录制完成后停止音频

func finishSpeech(){
audioEngine.stop() //AVAudioEngine()
recognitionTask?.cancel() //speechRecognizer?.recognitionTask
request.endAudio()  //SFSpeechAudioBufferRecognitionRequest?
audioEngine.inputNode.removeTap(onBus: 0)
}

张贴代表您解释的答案。这可能有助于

最新更新