iOS10語(yǔ)音識(shí)別框架SpeechFramework應(yīng)用詳解
摘要: iOS10語(yǔ)音識(shí)別框架SpeechFramework應(yīng)用
一、引言
iOS10系統(tǒng)是一個(gè)較有突破性的系統(tǒng),其在Message,Notification等方面都開放了很多實(shí)用性的開發(fā)接口。本篇博客將主要探討iOS10中新引入的SpeechFramework框架。有個(gè)這個(gè)框架,開發(fā)者可以十分容易的為自己的App添加語(yǔ)音識(shí)別功能,不需要再依賴于其他第三方的語(yǔ)音識(shí)別服務(wù),并且,Apple的Siri應(yīng)用的強(qiáng)大也證明了Apple的語(yǔ)音服務(wù)是足夠強(qiáng)大的,不通過(guò)第三方,也大大增強(qiáng)了用戶的安全性。
二、SpeechFramework框架中的重要類
SpeechFramework框架比較輕量級(jí),其中的類并不十分冗雜,在學(xué)習(xí)SpeechFramework框架前,我們需要對(duì)其中類與類與類之間的關(guān)系有個(gè)大致的熟悉了解。
SFSpeechRecognizer:這個(gè)類是語(yǔ)音識(shí)別的操作類,用于語(yǔ)音識(shí)別用戶權(quán)限的申請(qǐng),語(yǔ)言環(huán)境的設(shè)置,語(yǔ)音模式的設(shè)置以及向Apple服務(wù)發(fā)送語(yǔ)音識(shí)別的請(qǐng)求。
SFSpeechRecognitionTask:這個(gè)類是語(yǔ)音識(shí)別服務(wù)請(qǐng)求任務(wù)類,每一個(gè)語(yǔ)音識(shí)別請(qǐng)求都可以抽象為一個(gè)SFSpeechRecognitionTask實(shí)例,其中SFSpeechRecognitionTaskDelegate協(xié)議中約定了許多請(qǐng)求任務(wù)過(guò)程中的監(jiān)聽方法。
SFSpeechRecognitionRequest:語(yǔ)音識(shí)別請(qǐng)求類,需要通過(guò)其子類來(lái)進(jìn)行實(shí)例化。
SFSpeechURLRecognitionRequest:通過(guò)音頻URL來(lái)創(chuàng)建語(yǔ)音識(shí)別請(qǐng)求。
SFSpeechAudioBufferRecognitionRequest:通過(guò)音頻流來(lái)創(chuàng)建語(yǔ)音識(shí)別請(qǐng)求。
SFSpeechRecognitionResult:語(yǔ)音識(shí)別請(qǐng)求結(jié)果類。
SFTranscription:語(yǔ)音轉(zhuǎn)換后的信息類。
SFTranscriptionSegment:語(yǔ)音轉(zhuǎn)換中的音頻節(jié)點(diǎn)類。
了解了上述類的作用于其之間的聯(lián)系,使用SpeechFramework框架將十分容易。
三、申請(qǐng)用戶語(yǔ)音識(shí)別權(quán)限與進(jìn)行語(yǔ)音識(shí)別請(qǐng)求
開發(fā)者若要在自己的App中使用語(yǔ)音識(shí)別功能,需要獲取用戶的同意。首先需要在工程的Info.plist文件中添加一個(gè)Privacy-Speech Recognition Usage Description鍵,其實(shí)需要對(duì)應(yīng)一個(gè)String類型的值,這個(gè)值將會(huì)在系統(tǒng)獲取權(quán)限的警告框中顯示,Info.plist文件如下圖所示:
使用SFSpeechRecognize類的requestAuthorization方法來(lái)進(jìn)行用戶權(quán)限的申請(qǐng),用戶的反饋結(jié)果會(huì)在這個(gè)方法的回調(diào)block中傳入,如下:
//申請(qǐng)用戶語(yǔ)音識(shí)別權(quán)限 [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) { }];
SFSpeechRecognizerAuthorzationStatus枚舉中定義了用戶的反饋結(jié)果,如下:
typedef NS_ENUM(NSInteger, SFSpeechRecognizerAuthorizationStatus) { //結(jié)果未知 用戶尚未進(jìn)行選擇 SFSpeechRecognizerAuthorizationStatusNotDetermined, //用戶拒絕授權(quán)語(yǔ)音識(shí)別 SFSpeechRecognizerAuthorizationStatusDenied, //設(shè)備不支持語(yǔ)音識(shí)別功能 SFSpeechRecognizerAuthorizationStatusRestricted, //用戶授權(quán)語(yǔ)音識(shí)別 SFSpeechRecognizerAuthorizationStatusAuthorized, };
如果申請(qǐng)用戶語(yǔ)音識(shí)別權(quán)限成功,開發(fā)者可以通過(guò)SFSpeechRecognizer操作類來(lái)進(jìn)行語(yǔ)音識(shí)別請(qǐng)求,示例如下:
//創(chuàng)建語(yǔ)音識(shí)別操作類對(duì)象 SFSpeechRecognizer * rec = [[SFSpeechRecognizer alloc]init]; //通過(guò)一個(gè)音頻路徑創(chuàng)建音頻識(shí)別請(qǐng)求 SFSpeechRecognitionRequest * request = [[SFSpeechURLRecognitionRequest alloc]initWithURL:[[NSBundle mainBundle] URLForResource:@"7011" withExtension:@"m4a"]]; //進(jìn)行請(qǐng)求 [rec recognitionTaskWithRequest:request resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) { //打印語(yǔ)音識(shí)別的結(jié)果字符串 NSLog(@"%@",result.bestTranscription.formattedString); }];
四、深入SFSpeechRecognizer類
SFSpeechRecognizer類的主要作用是申請(qǐng)權(quán)限,配置參數(shù)與進(jìn)行語(yǔ)音識(shí)別請(qǐng)求。其中比較重要的屬性與方法如下:
//獲取當(dāng)前用戶權(quán)限狀態(tài) + (SFSpeechRecognizerAuthorizationStatus)authorizationStatus; //申請(qǐng)語(yǔ)音識(shí)別用戶權(quán)限 + (void)requestAuthorization:(void(^)(SFSpeechRecognizerAuthorizationStatus status))handler; //獲取所支持的所有語(yǔ)言環(huán)境 + (NSSet<NSLocale *> *)supportedLocales; //初始化方法 需要注意 這個(gè)初始化方法將默認(rèn)以設(shè)備當(dāng)前的語(yǔ)言環(huán)境作為語(yǔ)音識(shí)別的語(yǔ)言環(huán)境 - (nullable instancetype)init; //初始化方法 設(shè)置一個(gè)特定的語(yǔ)言環(huán)境 - (nullable instancetype)initWithLocale:(NSLocale *)locale NS_DESIGNATED_INITIALIZER; //語(yǔ)音識(shí)別是否可用 @property (nonatomic, readonly, getter=isAvailable) BOOL available; //語(yǔ)音識(shí)別操作類協(xié)議代理 @property (nonatomic, weak) id<SFSpeechRecognizerDelegate> delegate; //設(shè)置語(yǔ)音識(shí)別的配置參數(shù) 需要注意 在每個(gè)語(yǔ)音識(shí)別請(qǐng)求中也有這樣一個(gè)屬性 這里設(shè)置將作為默認(rèn)值 //如果SFSpeechRecognitionRequest對(duì)象中也進(jìn)行了設(shè)置 則會(huì)覆蓋這里的值 /* typedef NS_ENUM(NSInteger, SFSpeechRecognitionTaskHint) { SFSpeechRecognitionTaskHintUnspecified = 0, // 無(wú)定義 SFSpeechRecognitionTaskHintDictation = 1, // 正常的聽寫風(fēng)格 SFSpeechRecognitionTaskHintSearch = 2, // 搜索風(fēng)格 SFSpeechRecognitionTaskHintConfirmation = 3, // 短語(yǔ)風(fēng)格 }; */ @property (nonatomic) SFSpeechRecognitionTaskHint defaultTaskHint; //使用回調(diào)Block的方式進(jìn)行語(yǔ)音識(shí)別請(qǐng)求 請(qǐng)求結(jié)果會(huì)在Block中傳入 - (SFSpeechRecognitionTask *)recognitionTaskWithRequest:(SFSpeechRecognitionRequest *)request resultHandler:(void (^)(SFSpeechRecognitionResult * __nullable result, NSError * __nullable error))resultHandler; //使用代理回調(diào)的方式進(jìn)行語(yǔ)音識(shí)別請(qǐng)求 - (SFSpeechRecognitionTask *)recognitionTaskWithRequest:(SFSpeechRecognitionRequest *)request delegate:(id <SFSpeechRecognitionTaskDelegate>)delegate; //設(shè)置請(qǐng)求所占用的任務(wù)隊(duì)列 @property (nonatomic, strong) NSOperationQueue *queue;
SFSpeechRecognizerDelegate協(xié)議中只約定了一個(gè)方法,如下:
//當(dāng)語(yǔ)音識(shí)別操作可用性發(fā)生改變時(shí)會(huì)被調(diào)用 - (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available;
通過(guò)Block回調(diào)的方式進(jìn)行語(yǔ)音識(shí)別請(qǐng)求十分簡(jiǎn)單,如果使用代理回調(diào)的方式,開發(fā)者需要實(shí)現(xiàn)SFSpeechRecognitionTaskDelegate協(xié)議中的相關(guān)方法,如下:
//當(dāng)開始檢測(cè)音頻源中的語(yǔ)音時(shí)首先調(diào)用此方法 - (void)speechRecognitionDidDetectSpeech:(SFSpeechRecognitionTask *)task; //當(dāng)識(shí)別出一條可用的信息后 會(huì)調(diào)用 /* 需要注意,apple的語(yǔ)音識(shí)別服務(wù)會(huì)根據(jù)提供的音頻源識(shí)別出多個(gè)可能的結(jié)果 每有一條結(jié)果可用 都會(huì)調(diào)用此方法 */ - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didHypothesizeTranscription:(SFTranscription *)transcription; //當(dāng)識(shí)別完成所有可用的結(jié)果后調(diào)用 - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecognition:(SFSpeechRecognitionResult *)recognitionResult; //當(dāng)不再接受音頻輸入時(shí)調(diào)用 即開始處理語(yǔ)音識(shí)別任務(wù)時(shí)調(diào)用 - (void)speechRecognitionTaskFinishedReadingAudio:(SFSpeechRecognitionTask *)task; //當(dāng)語(yǔ)音識(shí)別任務(wù)被取消時(shí)調(diào)用 - (void)speechRecognitionTaskWasCancelled:(SFSpeechRecognitionTask *)task; //語(yǔ)音識(shí)別任務(wù)完成時(shí)被調(diào)用 - (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishSuccessfully:(BOOL)successfully;
SFSpeechRecognitionTask類中封裝了屬性和方法如下:
//此任務(wù)的當(dāng)前狀態(tài) /* typedef NS_ENUM(NSInteger, SFSpeechRecognitionTaskState) { SFSpeechRecognitionTaskStateStarting = 0, // 任務(wù)開始 SFSpeechRecognitionTaskStateRunning = 1, // 任務(wù)正在運(yùn)行 SFSpeechRecognitionTaskStateFinishing = 2, // 不在進(jìn)行音頻讀入 即將返回識(shí)別結(jié)果 SFSpeechRecognitionTaskStateCanceling = 3, // 任務(wù)取消 SFSpeechRecognitionTaskStateCompleted = 4, // 所有結(jié)果返回完成 }; */ @property (nonatomic, readonly) SFSpeechRecognitionTaskState state; //音頻輸入是否完成 @property (nonatomic, readonly, getter=isFinishing) BOOL finishing; //手動(dòng)完成音頻輸入 不再接收音頻 - (void)finish; //任務(wù)是否被取消 @property (nonatomic, readonly, getter=isCancelled) BOOL cancelled; //手動(dòng)取消任務(wù) - (void)cancel;
關(guān)于音頻識(shí)別請(qǐng)求類,除了可以使用SFSpeechURLRecognitionRequest類來(lái)進(jìn)行創(chuàng)建外,還可以使用SFSpeechAudioBufferRecognitionRequest類來(lái)進(jìn)行創(chuàng)建:
@interface SFSpeechAudioBufferRecognitionRequest : SFSpeechRecognitionRequest @property (nonatomic, readonly) AVAudioFormat *nativeAudioFormat; //拼接音頻流 - (void)appendAudioPCMBuffer:(AVAudioPCMBuffer *)audioPCMBuffer; - (void)appendAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer; //完成輸入 - (void)endAudio; @end
五、語(yǔ)音識(shí)別結(jié)果類SFSpeechRecognitionResult
SFSpeechRecognitionResult類是語(yǔ)音識(shí)別結(jié)果的封裝,其中包含了許多套平行的識(shí)別信息,其每一份識(shí)別信息都有可信度屬性來(lái)描述其準(zhǔn)確程度。SFSpeechRecognitionResult類中屬性如下:
//識(shí)別到的多套語(yǔ)音轉(zhuǎn)換信息數(shù)組 其會(huì)按照準(zhǔn)確度進(jìn)行排序 @property (nonatomic, readonly, copy) NSArray<SFTranscription *> *transcriptions; //準(zhǔn)確性最高的識(shí)別實(shí)例 @property (nonatomic, readonly, copy) SFTranscription *bestTranscription; //是否已經(jīng)完成 如果YES 則所有所有識(shí)別信息都已經(jīng)獲取完成 @property (nonatomic, readonly, getter=isFinal) BOOL final;
SFSpeechRecognitionResult類只是語(yǔ)音識(shí)別結(jié)果的一個(gè)封裝,真正的識(shí)別信息定義在SFTranscription類中,SFTranscription類中屬性如下:
//完整的語(yǔ)音識(shí)別準(zhǔn)換后的文本信息字符串 @property (nonatomic, readonly, copy) NSString *formattedString; //語(yǔ)音識(shí)別節(jié)點(diǎn)數(shù)組 @property (nonatomic, readonly, copy) NSArray<SFTranscriptionSegment *> *segments;
當(dāng)對(duì)一句完整的話進(jìn)行識(shí)別時(shí),Apple的語(yǔ)音識(shí)別服務(wù)實(shí)際上會(huì)把這句語(yǔ)音拆分成若干個(gè)音頻節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)可能為一個(gè)單詞,SFTranscription類中的segments屬性就存放這些節(jié)點(diǎn)。SFTranscriptionSegment類中定義的屬性如下:
//當(dāng)前節(jié)點(diǎn)識(shí)別后的文本信息 @property (nonatomic, readonly, copy) NSString *substring; //當(dāng)前節(jié)點(diǎn)識(shí)別后的文本信息在整體識(shí)別語(yǔ)句中的位置 @property (nonatomic, readonly) NSRange substringRange; //當(dāng)前節(jié)點(diǎn)的音頻時(shí)間戳 @property (nonatomic, readonly) NSTimeInterval timestamp; //當(dāng)前節(jié)點(diǎn)音頻的持續(xù)時(shí)間 @property (nonatomic, readonly) NSTimeInterval duration; //可信度/準(zhǔn)確度 0-1之間 @property (nonatomic, readonly) float confidence; //關(guān)于此節(jié)點(diǎn)的其他可能的識(shí)別結(jié)果 @property (nonatomic, readonly) NSArray<NSString *> *alternativeSubstrings;
溫馨提示:SpeechFramework框架在模擬器上運(yùn)行會(huì)出現(xiàn)異常情況,無(wú)法進(jìn)行語(yǔ)音識(shí)別請(qǐng)求。會(huì)報(bào)出kAFAssistantErrorDomain的錯(cuò)誤,還望有知道解決方案的朋友,給些建議,Thanks。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- iOS使用Charts框架繪制折線圖
- iOS使用Charts框架繪制餅狀圖
- IOS 陀螺儀開發(fā)(CoreMotion框架)實(shí)例詳解
- iOS中使用JSPatch框架使Objective-C與JavaScript代碼交互
- IOS框架Spring常用的動(dòng)畫效果
- 詳解iOS的Core Animation框架中的CATransform3D圖形變換
- iOS開發(fā)中使用CoreLocation框架處理地理編碼的方法
- iOS + node.js使用Socket.IO框架進(jìn)行實(shí)時(shí)通信示例
- 深入理解IOS控件布局之Masonry布局框架
- iOS系統(tǒng)的底層通知框架庫(kù)示例詳解
相關(guān)文章
iOS開發(fā)中實(shí)現(xiàn)顯示gif圖片的方法
這篇文章主要介紹了iOS開發(fā)中實(shí)現(xiàn)顯示gif圖片的方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-09-09iOS實(shí)現(xiàn)去除html標(biāo)簽的方法匯總
相信大家在做網(wǎng)站的時(shí)候,經(jīng)常會(huì)遇到去除html標(biāo)簽的問(wèn)題,下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS如何實(shí)現(xiàn)去除html標(biāo)簽的一些方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-10-10iOS中實(shí)現(xiàn)imageView任意角度旋轉(zhuǎn)的方法
這篇文章主要給大家介紹了關(guān)于iOS中實(shí)現(xiàn)imageView任意角度旋轉(zhuǎn)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12IOS打開照相機(jī)與本地相冊(cè)選擇圖片實(shí)例詳解
這篇文章主要介紹了IOS打開照相機(jī)與本地相冊(cè)選擇圖片實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06IOS中用正則表達(dá)式判斷輸入的內(nèi)容為8-16位且同時(shí)包含數(shù)字和字母
這篇文章主要介紹了IOS中用正則表達(dá)式判斷輸入的內(nèi)容為8-16位且同時(shí)包含數(shù)字和字母,需要的朋友可以參考下2017-06-06IOS在SwiftUI中顯示模態(tài)視圖的實(shí)例代碼
這篇文章主要介紹了IOS在SwiftUI中顯示模態(tài)視圖的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02