99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

iOS10中如何使用Speech 框架構(gòu)建語音轉(zhuǎn)文本應(yīng)用?

發(fā)布時間:2016-10-14 00:09  回復(fù):0  查看:2696   最后回復(fù):2016-10-14 00:09  
 2016  年的  WWDC  上, Apple  介紹了一個十分有用的語音識別  API ,那就是  Speech  框架。事實上, Siri  的語音識別正是由  Speech Kit  提供支持。就目前來說,可用的語音識別框架并非沒有,但是它們要么太貴,要么不夠好。在本 iOS教程中,我將會向你演示如何使用 Speech Kit  來創(chuàng)建一個像 Siri  一樣的應(yīng)用來進行語音到文本的轉(zhuǎn)換。
應(yīng)用界面設(shè)計
事前準(zhǔn)備: Xcode 8 beta  版和一臺運行  iOS 10 beta  版的設(shè)備 .
首先,讓我們來創(chuàng)建一個 iOS Single View Application  工程,并將其命名為  SpeechToTextDemo  。然后在Main.storyboard  上添加  UILabel  、  UITextView   UIButton  各一個。
此時 storyboard  應(yīng)該看起來像這樣:
iOS10中如何使用Speech 框架構(gòu)建語音轉(zhuǎn)文本應(yīng)用?

下一步,在 ViewController.swift  文件中為  UITextView   UIButton  定義  outlet  變量,將  UITextView  命名為 “textView”  UIButton  命名為  “microphoneButton”  之后,再創(chuàng)建一個空  action  方法來監(jiān)聽麥克風(fēng)按鈕 (microphoneButton)  的點擊事件:
@IBAction func microphoneTapped(_ sender: AnyObject) {
}
使用 Speech  框架
要使用 Speech  框架,第一件要做的事自然是引入這個框架,并遵循  SFSpeechRecognizerDelegate  協(xié)議。所以,我們先引入該框架,然后將它的協(xié)議添加到  ViewController.swift  類中。此時  ViewController.swift  應(yīng)該是這樣的:
import UIKitimport Speech
class ViewController: UIViewController, SFSpeechRecognizerDelegate {
   
   
    @IBOutlet weak var textView: UITextView!
    @IBOutlet weak var microphoneButton: UIButton!
     func viewDidLoad() {
        sup
    overrideer.viewDidLoad()
        
    }
    @IBAction func microphoneTapped(_ sender: AnyObject) {
    }
}
用戶權(quán)限
在使用 Speech  框架進行語音識別之前,你必須先請求用戶許可,原因是識別不僅發(fā)生在  iOS  設(shè)備本地,還需要依賴  Apple  的服務(wù)器。具體來說,所有音頻數(shù)據(jù)都會被傳輸?shù)教O果后臺進行處理。因此需要獲取用戶的權(quán)限。
我們將在 ViewDidLoad  方法中處理授權(quán)。其中包括用戶必須允許應(yīng)用使用的音頻輸入和語音識別權(quán)限。首先,聲明一個名為  speechRecognizer  的變量:
private let speechRecognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "en-US"))  //1
然后將 ViewDidLoad  方法修改為下面這樣:
override func viewDidLoad() {
    super.viewDidLoad()
   
    microphoneButton.isEnabled = false  //2
   
    speechRecognizer.delegate = self  //3
   
    SFSpeechRecognizer.requestAuthorization { (authStatus) in  //4
        
        var isButtonEnabled = false
        
        switch authStatus {  //5
        case .authorized:
            isButtonEnabled = true
            
        case .denied:
            isButtonEnabled = false
            print("User denied access to speech recognition")
            
        case .restricted:
            isButtonEnabled = false
            print("Speech recognition restricted on this device")
            
        case .notDetermined:
            isButtonEnabled = false
            print("Speech recognition not yet authorized")
        }
        
        OperationQueue.main.addOperation() {
            self.microphoneButton.isEnabled = isButtonEnabled
        }
    }
}
第一步,創(chuàng)建一個區(qū)域標(biāo)志符 (locale identifier)   en-US   SFSpeechRecognizer 實例,這時候語音識別就會知道用戶錄入的語種。簡單說,這就是語音識別的處理對象。
在語音識別被激活之前,默認設(shè)置麥克風(fēng)按鈕為禁用狀態(tài)。
然后,將語音識別的 delegate  設(shè)置為  ViewController  中的  self  。
之后,就到了請求語音識別權(quán)限的階段了,這時我們通過調(diào)用 SFSpeechRecognizer.requestAuthorization  來達到目的。
最后,檢查驗證狀態(tài),如果得到了授權(quán),則啟用麥克風(fēng)按鈕。否則,打印錯誤信息,繼續(xù)禁用麥克風(fēng)按鈕。
你可能會認為,現(xiàn)在我們啟動應(yīng)用將會看到一個授權(quán)提示框,很遺憾你錯了。運行應(yīng)用帶來的是崩潰。你可能會想問,這是為什么?
提供授權(quán)信息
Apple  要求應(yīng)用為所有請求的權(quán)限提供自定義消息,對于語音權(quán)限的情況,我們必須為兩個行為請求授權(quán):
麥克風(fēng)的使用
語音的識別
要自定義消息,你需要在 info.plist  文件中定義這些消息。
讓我們打開 info.plist  文件的源代碼。方法是在  info.plist  上點擊右鍵。然后選擇  Open As > Source Code 。最后,復(fù)制下面的  XML  代碼并將它們插入到   標(biāo)簽前。
xmlNSMicrophoneUsageDescription  Your microphone will be used to record your speech when you press the "Start Recording" button.
NSSpeechRecognitionUsageDescription  Speech recognition will be used to determine which words you speak into this device's microphone.
好了,現(xiàn)在你已經(jīng)將兩個 key  添加到  info.plist  中了:
NSMicrophoneUsageDescription –  音頻輸入授權(quán)請求的自定義信息。注意,音頻輸入授權(quán)請求只發(fā)生在用戶點擊麥克風(fēng)按鈕的時候。
NSSpeechRecognitionUsageDescription –  語音識別授權(quán)請求的自定義信息。
你可以隨意修改這些記錄的值。一切就緒,現(xiàn)在可以運行程序了,不出意外的話,編譯并運行應(yīng)用不會報任何錯。
注意:如果工程完成之后你沒有看到音頻輸入授權(quán)請求的話,首先務(wù)必確認你是否正在模擬器上運行應(yīng)用。iOS 模擬器并不會連接  Mac  的麥克風(fēng)。
處理語音識別
現(xiàn)在用戶授權(quán)已經(jīng)完成了,讓我們一鼓作氣,接著來實現(xiàn)語音識別。首先,在 ViewController  中定義下述對象:
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?private var recognitionTask: SFSpeechRecognitionTask?private let audioEngine = AVAudioEngine()
recognitionRequest  對象用于處理語音識別請求,為語音識別提供音頻輸入。
recognitionTask  可以將識別請求的結(jié)果返回給你,它帶來了極大的便利,必要時,可以取消或停止任務(wù)。
最后的 audioEngine  是音頻引擎。它的存在使得你能夠進行音頻輸入。
接下來,讓我們創(chuàng)建一個名為 startRecording()  的新函數(shù):
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()
   
    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 {
            
            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.microphoneButton.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.")
    }
   
    textView.text = "Say something, I'm listening!"
   
}
上述函數(shù)被調(diào)用的時機是開始錄音按鈕被按下的瞬間。它的主要功能是啟動語音識別并開始監(jiān)聽麥克風(fēng)。讓我們來逐行剖析一下這段代碼:
3-6  –  檢查  recognitionTask  的運行狀態(tài),如果正在運行,取消任務(wù)。
8-15  –  創(chuàng)建一個  AVAudioSession  對象為音頻錄制做準(zhǔn)備。這里我們將錄音分類設(shè)置為  Record ,模式設(shè)為 Measurement ,然后啟動。注意,設(shè)置這些屬性有可能會拋出異常,因此你必須將其置于  try catch  語句中。
17  –  實例化  recognitionResquest  。創(chuàng)建  SFSpeechAudioBufferRecognitionRequest  對象,然后我們就可以利用它將音頻數(shù)據(jù)傳輸?shù)?nbsp; Apple  的服務(wù)器。
19-21  –  檢查  audioEngine ( 你的設(shè)備 ) 是否支持音頻輸入以錄音。如果不支持,報一個  fatal error 。
23-25  –  檢查  recognitionRequest  對象是否已被實例化,并且值不為  nil  。
27  –  告訴  recognitionRequest  不要等到錄音完成才發(fā)送請求,而是在用戶說話時一部分一部分發(fā)送語音識別數(shù)據(jù)。
29  –  在調(diào)用  speechRecognizer   recognitionTask  函數(shù)時開始識別。該函數(shù)有一個完成回調(diào)函數(shù),每次識別引擎收到輸入時都會調(diào)用它,在修改當(dāng)前識別結(jié)果,亦或是取消或停止時,返回一個最終記錄。
31  –  定義一個  boolean  變量來表示識別是否已結(jié)束。
35  –  倘若結(jié)果非空,則設(shè)置  textView.text  屬性為結(jié)果中的最佳記錄。同時若為最終結(jié)果,將  isFinal  置為  true 。
39-47  –  如果請求沒有錯誤或已經(jīng)收到最終結(jié)果,停止  audioEngine ( 音頻輸入 ) ,  recognitionRequest  recognitionTask  。同時,將開始錄音按鈕的狀態(tài)切換為可用。
50-53  –   recognitionRequest  添加一個音頻輸入。值得留意的是,在  recognitionTask  啟動后再添加音頻輸入   完全沒有問題   Speech  框架會在添加了音頻輸入之后立即開始識別任務(wù)。
55  –   audioEngine  設(shè)為準(zhǔn)備就緒狀態(tài),并啟動引擎。
觸發(fā)語音識別
在創(chuàng)建語音識別任務(wù)時,我們首先得確保語音識別的可用性,因此,需要向 ViewController  添加一個  delegate  方法。如果語音識別不可用,或是改變了狀態(tài),應(yīng)隨之設(shè)置  microphoneButton.enable  屬性。針對這個方案,我們實現(xiàn)了  SFSpeechRecognizerDelegate  協(xié)議的  availabilityDidChange  方法。詳細實現(xiàn)如下所示:
func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {
    if available {
        microphoneButton.isEnabled = true
    } else {
        microphoneButton.isEnabled = false
    }
}
這個方法會在按鈕的可用性改變時被調(diào)用。如果語音識別可用,錄音按鈕也將被啟用。
最后,我們還需要更新一下 microphoneTapped(sender:)  方法:
@IBAction func microphoneTapped(_ sender: AnyObject) {
    if audioEngine.isRunning {
        audioEngine.stop()
        recognitionRequest?.endAudio()
        microphoneButton.isEnabled = false
        microphoneButton.setTitle("Start Recording", for: .normal)
    } else {
        startRecording()
        microphoneButton.setTitle("Stop Recording", for: .normal)
    }
}
這個函數(shù)的用途是檢查 audioEngine  是否在運行。如果正在運行,停止  audioEngine  ,終止  recognitionRequest  的音頻輸入,禁用  microphoneButton  ,并將按鈕的文字改為 開始錄音 。
 audioEngine  正在工作,則應(yīng)用應(yīng)該調(diào)用  startRecording()  ,以及設(shè)置按鈕的文字為 停止錄音 。
太棒了!一切就緒,可以準(zhǔn)備測試一下應(yīng)用了。首先將該應(yīng)用布署到一臺 iOS 10  的設(shè)備上,然后點擊 開始錄制 按鈕。來吧,說點什么試試!
[]( http://www.appcoda.com/wp-con...
注意:
Apple  對每臺設(shè)備的識別有限制。詳情未知,不過你可以嘗試聯(lián)系  Apple  獲得更多信息。
Apple  對每個應(yīng)用的識別也有限制。
如果你總是遭遇限制,務(wù)必聯(lián)系 Apple ,他們或許可以解決這個問題。
語音識別會消耗不少電量和流量。
語音識別每次只能持續(xù)大概一分鐘。
總結(jié)
在本教程中,我們講解了如何利用 Apple  向開發(fā)者開放的新語音  API  來識別語音并將其轉(zhuǎn)換為文本,你應(yīng)該對這些  API  的優(yōu)點深有體會并能夠合理使用了吧。 Speech  框架使用的語音識別框架與  Siri  相同。該  API  雖小,但功能十分強大,為開發(fā)者創(chuàng)造像是獲取音頻文件記錄一樣震撼的東西提供了極大的便利。
文章來源:SegmentFault
您還未登錄,請先登錄

熱門帖子

最新帖子

?