ios - 当我连续单击开始和停止操作时,我的应用程序崩溃了。我正在使用语音识别
问题描述
这是我的课程代码,我正在使用语音框架来实现语音到文本的转换。但是,每当我连续按 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)
}
发布代表您的解释的答案。这可能会有所帮助
推荐阅读
- reactjs - 更改图标启动器后 processDebugResources FAILED
- python - Kivy 视频播放器延迟/滞后
- python - Python .month 格式是 numeric(1) 想要 MMM(Jan)
- php - 尝试合并 SQL 查询的两个结果 - ToDoList App
- javascript - Angular - 在嵌套对象中访问 ngFor 变量
- python - Pythonic 嵌套 for - Python 中的循环
- automapper - 使用 ValueTransformer 映射可空和不可空双精度
- angular - 如何在角度测试中获取 nativeElement [属性] 值?
- python - 如何在 Django 视图中执行长时间运行的进程?
- .net-core - .net core 3.1 pack dll 与 Azure Devops