2017-03-01 3 views
7

Ich hack ein kleines Projekt mit iOS 10 eingebaute Spracherkennung. Ich habe Arbeitsergebnisse mit dem Gerät Mikrofon, meine Sprache wird sehr genau erkannt.SFSpeechRecognizer - Ende der Äußerung erkennen

Mein Problem ist, dass die Anerkennung Aufgabe Rückruf für jede verfügbare Teil Transkription genannt wird, und ich mag es erkennen Person verstummte und den Rückruf mit isFinal Eigenschaft auf true gesetzt nennen. Es passiert nicht - App hört unbegrenzt zu.

Ist SFSpeechRecognizer jemals in der Lage, Satzende zu erkennen?

Hier ist mein Code - es basiert auf Beispiel im Internet gefunden, es ist meist ein Boilerplate benötigt, um von Mikrofonquelle zu erkennen. Ich modifizierte es durch Hinzufügen der Erkennung taskHint. Ich habe auch shouldReportPartialResults auf false gesetzt, aber es scheint, dass es ignoriert wurde.

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 
} 

Antwort

8

Es scheint, dass isFinal Flag nicht wahr ist, wenn sich Benutzer aufhört, wie erwartet zu sprechen. Ich denke, das ist ein gewolltes Verhalten von Apple, denn das Ereignis "Benutzer hört auf zu sprechen" ist ein undefiniertes Ereignis.

Ich glaube, dass der einfachste Weg, um Ihr Ziel zu erreichen, ist folgendes zu tun:

  • Sie estabilish müssen ein „Intervall der Stille“. Das heißt, wenn der Benutzer für eine Zeit nicht länger als Ihr Intervall spricht, hat er aufgehört zu sprechen (d. H. 2 Sekunden).

  • erstellen Timer zu Beginn des audio session:

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

  • , wenn Sie bekommen neue Transkriptionen in recognitionTask invalidate und starten Sie Ihren Timer

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

  • Wenn der Timer abläuft, bedeutet dies, dass der Benutzer ab 2 Sekunden nicht spricht. Sie können Audio Session sicher beenden und beenden

+0

Warum Apple diesen Tuff gefunden? Sie müssen nur eine nützliche Delegate-Methode implementieren. – Ganesh

Verwandte Themen