Last active
March 6, 2020 15:18
-
-
Save elpsk/6f8c2ac12ffc19ef0f5c1119ac3832e9 to your computer and use it in GitHub Desktop.
Recognize spoken text using Siri
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import Speech | |
protocol SpeechManagerProtocol { | |
func didTextRecognized(text: String) | |
} | |
class SpeechManager: NSObject { | |
private var speechRecognizer : SFSpeechRecognizer? | |
private var recognitionRequest : SFSpeechAudioBufferRecognitionRequest? | |
private var recognitionTask : SFSpeechRecognitionTask? | |
private var delegate : SpeechManagerProtocol! | |
private lazy var audioEngine = AVAudioEngine() | |
init( delegate: SpeechManagerProtocol, language: String ) { | |
super.init() | |
self.delegate = delegate | |
speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: language))! | |
initSpeechRecognizer() | |
} | |
// ------------------------------------------------------------------------- | |
func initSpeechRecognizer() { | |
SFSpeechRecognizer.requestAuthorization { (authStatus) in | |
switch authStatus { | |
case .authorized: | |
self.startRecording() | |
break | |
case .denied, .restricted, .notDetermined: | |
break | |
} | |
} | |
} | |
func startRecording() { | |
if recognitionTask != nil { | |
recognitionTask?.cancel() | |
recognitionTask = nil | |
} | |
let audioSession = AVAudioSession.sharedInstance() | |
do { | |
try audioSession.setCategory( | |
AVAudioSession.Category.record, | |
mode: AVAudioSession.Mode.measurement, | |
options: AVAudioSession.CategoryOptions.defaultToSpeaker) | |
try audioSession.setMode(AVAudioSession.Mode.measurement) | |
try audioSession.setActive(true, options: .notifyOthersOnDeactivation) | |
} catch {} | |
recognitionRequest = SFSpeechAudioBufferRecognitionRequest() | |
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 { | |
isFinal = (result?.isFinal)! | |
let text = (result?.bestTranscription.formattedString)!.lowercased() | |
self.delegate!.didTextRecognized(text: text) | |
} | |
if error != nil || isFinal { | |
self.audioEngine.stop() | |
self.audioEngine.inputNode.removeTap(onBus: 0) | |
self.recognitionRequest = nil | |
self.recognitionTask = nil | |
// start again, I want continuous recording. | |
self.startRecording() | |
} | |
}) | |
let recordingFormat = audioEngine.inputNode.outputFormat(forBus: 0) | |
audioEngine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in | |
self.recognitionRequest?.append(buffer) | |
} | |
audioEngine.prepare() | |
do { try audioEngine.start() } catch {} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment