什麼都不說先上效果緩存
早在2011年iPhone4s 的上,iOS 5系統就有了語音識別. 但有如下缺陷安全
在 2016 年的 WWDC 上,Apple 終於開放了語音識別 Speech Recognition API,那就是 Speech 框架。事實上,Siri 的語音識別正是由 Speech Kit 提供支持。服務器
下面經過一個語音轉換爲文本介紹Speech 框架的使用app
##界面設計 首先,讓咱們來建立一個 iOS Single View Application 工程。而後在 Main.storyboard 上添加 UILabel用於標題 UITextView用於顯示識別內容 UIButton 用於觸發 下一步,連線 textView變量,Button變量和事件框架
@IBOutlet weak var textView: UITextView! @IBOutlet weak var speakerBtn: UIButton! @IBAction func speakAction(_ sender: Any) { }
##使用 Speech 框架 import這個框架,並遵循 SFSpeechRecognizerDelegate 協議。ide
##用戶權限 在使用 Speech 框架進行語音識別以前,你必須先請求用戶許可,緣由是識別不只發生在 iOS 設備本地,還須要依賴 Apple 的服務器。具體來講,全部音頻數據都會被傳輸到蘋果後臺進行處理。所以須要獲取用戶的權限,其中包括用戶必須容許應用使用的音頻輸入和語音識別權限。函數
//用於apple語言識別的變量 private let speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "zh-CN"))
// MARK: - *** 獲取用戶權限 *** func authRequest(){ speakerBtn.isEnabled = false speechRecognizer?.delegate = self SFSpeechRecognizer.requestAuthorization { (authStatus) in var isBtnEndable = false switch authStatus{ case.authorized: isBtnEndable = true case .denied: isBtnEndable = false print("User denied access to speech recognition") case .restricted: isBtnEndable = false print("Speech recognition restricted on this device") case .notDetermined: isBtnEndable = false } OperationQueue.main.addOperation { self.speakerBtn.isEnabled = isBtnEndable } } }
Apple 要求應用爲全部請求的權限提供自定義消息,對於語音權限的狀況,咱們必須爲兩個行爲請求受權: 麥克風的使用 語音的識別 要自定義消息,你須要在 info.plist 文件中定義這些消息。 讓咱們打開 info.plist 文件的源代碼。方法是在 info.plist 上點擊右鍵。而後選擇 Open As > Source Code。最後,複製下面的 XML 代碼並將它們插入到 </dict> 標籤前。測試
<key>NSMicrophoneUsageDescription</key> <string>麥克風輸入請求信息</string> <key>NSSpeechRecognitionUsageDescription</key> <string>語音識別請求信息</string>
注意:務必在IPhone真機上運行測試,iOS 模擬器並不會鏈接 Mac 的麥克風。this
處理語音識別設計
// 能夠將識別請求的結果返回給你,它帶來了極大的便利,必要時,能夠取消或中止任務。 private var recognitionTask: SFSpeechRecognitionTask? //對象用於處理語音識別請求,爲語音識別提供音頻輸入 private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest? // 音頻引擎 用於進行音頻輸入 private let audioEngine = AVAudioEngine()
// MARK: - *** 處理語音識別 *** 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{ fatalError("會話建立失敗") } recognitionRequest = SFSpeechAudioBufferRecognitionRequest() guard let inputNode = audioEngine.inputNode else { fatalError("音頻引擎 沒有輸入節點") } guard let recognitionRequest = recognitionRequest else { fatalError("建立音頻緩存失敗") } //結果報告 recognitionRequest.shouldReportPartialResults = true //開啓受權任務 recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in var isFinal = false if result != nil { self.textView.text = result?.bestTranscription.formattedString isFinal = (result?.isFinal)! } if error != nil || isFinal { self.audioEngine.stop() inputNode.removeTap(onBus: 0) self.recognitionRequest = nil self.recognitionTask = nil self.speakerBtn.isEnabled = true } }) 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.") } } }
在建立語音識別任務時,咱們首先得確保語音識別的可用性,須要實現delegate 方法。若是語音識別不可用,或是改變了狀態,應隨之設置 按鈕的enable ,咱們經過擴展來實現代理
// MARK: - *** delegate *** //這個方法會在按鈕的可用性改變時被調用。若是語音識別可用,錄音按鈕也將被啓用。 extension ViewController: SFSpeechRecognizerDelegate{ func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) { if available { speakerBtn.isEnabled = true } else { speakerBtn.isEnabled = false } } }
最後,咱們還須要更新一下 按鈕的點擊方法:
@IBAction func speakAction(_ sender: Any) { if audioEngine.isRunning { audioEngine.stop() recognitionRequest?.endAudio() speakerBtn.isEnabled = false speakerBtn.setTitle("開始說話", for: .normal) } else { startRecording() speakerBtn.setTitle("說完了", for: .normal) } }
Apple忠告
參考 WWDC 2016 - Session 509 - iOS
歡迎打賞 點贊,收藏,關注博主