2017-03-01 129 views
7

我使用iOS 10內置的語音識別功能來竊聽一個小項目。我使用設備的麥克風獲得了工作成果,我的演講被非常準確地識別出來。SFSpeechRecognizer - 檢測話語的結尾

我的問題是識別任務回調呼籲每個可用的部分轉錄,我希望它檢測人停止了講話,並呼籲與isFinal屬性設置爲true回調。它沒有發生 - 應用程序無限期地在監聽。

是否SFSpeechRecognizer有史以來能夠檢測到句子結束?

這是我的代碼 - 它基於互聯網上找到的例子,它主要是從麥克風源識別的樣板。 我通過添加識別taskHint對其進行了修改。我也將shouldReportPartialResults設置爲false,但似乎它已被忽略。

func startRecording() { 

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

    let audioSession = AVAudioSession.sharedInstance() 
    do { 
     try audioSession.setCategory(AVAudioSessionCategoryRecord) 
     try audioSession.setMode(AVAudioSessionModeMeasurement) 
     try audioSession.setActive(true, with: .notifyOthersOnDeactivation) 
    } catch { 
     print("audioSession properties weren't set because of an error.") 
    } 

    recognitionRequest = SFSpeechAudioBufferRecognitionRequest() 
    recognitionRequest?.shouldReportPartialResults = false 
    recognitionRequest?.taskHint = .search 

    guard let inputNode = audioEngine.inputNode else { 
     fatalError("Audio engine has no input node") 
    } 

    guard let recognitionRequest = recognitionRequest else { 
     fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object") 
    } 

    recognitionRequest.shouldReportPartialResults = true 

    recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in 

     var isFinal = false 

     if result != nil { 
      print("RECOGNIZED \(result?.bestTranscription.formattedString)") 
      self.transcriptLabel.text = result?.bestTranscription.formattedString 
      isFinal = (result?.isFinal)! 
     } 

     if error != nil || isFinal { 
      self.state = .Idle 

      self.audioEngine.stop() 
      inputNode.removeTap(onBus: 0) 

      self.recognitionRequest = nil 
      self.recognitionTask = nil 

      self.micButton.isEnabled = true 

      self.say(text: "OK. Let me see.") 
     } 
    }) 

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

    audioEngine.prepare() 

    do { 
     try audioEngine.start() 
    } catch { 
     print("audioEngine couldn't start because of an error.") 
    } 

    transcriptLabel.text = "Say something, I'm listening!" 

    state = .Listening 
} 

回答

8

看來,當用戶停止說話預期isFinal標誌不會成真。我猜這是蘋果想要的行爲,因爲事件「用戶停止說話」是一個未定義的事件。

我認爲,要實現自己的目標的最簡單的方法是做到以下幾點:

  • 你必須estabilish一個「沉默的區間」。這意味着,如果用戶不說話的時間超過了你的時間間隔,他就停止說話(即2秒)。

  • audio session年初創建定時器

var timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "didFinishTalk", userInfo: nil, repeats: false)

  • 當你在recognitionTask無效,並重新啓動定時器新改編

    timer.invalidate() timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "didFinishTalk", userInfo: nil, repeats: false)

  • 如果計時器到期,這意味着用戶不會從2秒開始通話。您可以安全地停止音頻會話並退出

+0

爲什麼蘋果發現這個凝灰岩?只需要實現有用的委託方法。 – Ganesh