語(yǔ)音轉(zhuǎn)文本的三種方案
手機(jī)語(yǔ)音功能越來(lái)越實(shí)用葫督,也越來(lái)越多人實(shí)用叽赊,雖然小菜鳥本人不喜歡使用語(yǔ)音功能,但是語(yǔ)音功能越來(lái)越受到追捧顺呕,也預(yù)研究了一下語(yǔ)音轉(zhuǎn)文本的功能枫攀,這次主要嘗試了使用科大訊飛語(yǔ)音識(shí)別、百度語(yǔ)音識(shí)別塘匣、系統(tǒng)原生的的語(yǔ)音識(shí)別脓豪。
1.科大訊飛的語(yǔ)音識(shí)別
1.1 使用科大訊飛的SDK必須先要到科大的官網(wǎng)上注冊(cè)應(yīng)用巷帝,并開通語(yǔ)音聽寫功能服務(wù)忌卤,獲取APPID,并下載SDK楞泼。
1.2 下載完SDK后驰徊,解壓縮后里面有文檔(Doc),F(xiàn)ramework(lib)堕阔,版本信息(release.txt)棍厂,Demo(sample)。這方面科大還是做的比較好的超陆,很多東西都一目了然的牺弹,初次使用的話可以研究一下Demo。
1.3 導(dǎo)入Framework时呀,把文件夾下的lib中的iflyMSC.framework導(dǎo)入工程中张漂,并添加iflyMSC.framework所依賴的其他庫(kù),主要的依賴庫(kù)有以下這些谨娜,其中官網(wǎng)中的CoreTelephoney.framework應(yīng)該修改成CoreTelephony.framework
庫(kù)名稱 | 是否必要 | 功能 |
---|---|---|
libz.tbd | 必要 | 用于壓縮航攒、加密算法。 |
AVFoundation.framework | 必要 | 用于系統(tǒng)錄音和播放 趴梢。 |
SystemConfiguration.framework | 系統(tǒng)庫(kù) | 用于系統(tǒng)設(shè)置漠畜。 |
Foundation.framework | 必要 | 基本庫(kù)。 |
CoreTelephony.framework | 必要 | 用于電話相關(guān)操作坞靶。 |
AudioToolbox.framework | 必要 | 用于系統(tǒng)錄音和播放憔狞。 |
UIKit.framework | 必要 | 用于界面顯示。 |
CoreLocation.framework | 必要 | 用于定位彰阴。 |
Contacts.framework | 必要 | 用于聯(lián)系人瘾敢。 |
AddressBook.framework | 必要 | 用于聯(lián)系人。 |
QuartzCore.framework | 必要 | 用于界面顯示。 |
CoreGraphics.framework | 必要 | 用于界面顯示廉丽。 |
libc++.tbd | 必要 | 用于支持C++倦微。 |
Libicucore.tbd | Aiui必要 | 系統(tǒng)正則庫(kù)。 |
1.4 關(guān)閉bitcode正压,如果沒有關(guān)閉bitcode則會(huì)出現(xiàn)You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE)錯(cuò)誤.
bitcode 設(shè)置方式為 Targets -> Build Settings,搜索bitcode欣福,設(shè)置為NO。
1.5 在info.plist添加權(quán)限說明
<key>NSMicrophoneUsageDescription</key>
<string></string>
<key>NSLocationUsageDescription</key>
<string></string>
<key>NSLocationAlwaysUsageDescription</key>
<string></string>
<key>NSContactsUsageDescription</key>
<string></string>
1.6 使用科大訊飛要先注冊(cè)服務(wù)焦履,
NSString *initString = [[NSString alloc] initWithFormat:@"appid=%@",APPID];
[IFlySpeechUtility createUtility:initString];
1.7 語(yǔ)音識(shí)別實(shí)現(xiàn)
//創(chuàng)建語(yǔ)音識(shí)別對(duì)象
_iFlySpeechRecognizer = [IFlySpeechRecognizer sharedInstance];
_iFlySpeechRecognizer.delegate = self;
//設(shè)置為聽寫模式
[_iFlySpeechRecognizer setParameter: @"iat" forKey: [IFlySpeechConstant IFLY_DOMAIN]];
//asr_audio_path 是錄音文件名拓劝,設(shè)置value為nil或者為空取消保存,默認(rèn)保存目錄在Library/cache下嘉裤。
[_iFlySpeechRecognizer setParameter:nil forKey:[IFlySpeechConstant ASR_AUDIO_PATH]];
//設(shè)置語(yǔ)音輸入等待時(shí)長(zhǎng)
[_iFlySpeechRecognizer setParameter:@"10000" forKey: [IFlySpeechConstant VAD_BOS]];
[_iFlySpeechRecognizer setParameter:@"10000" forKey: [IFlySpeechConstant VAD_EOS]];
1.8 啟動(dòng)語(yǔ)音識(shí)別
//啟動(dòng)識(shí)別服務(wù)
_iFlySpeechRecognizer.delegate = self;
[_iFlySpeechRecognizer startListening];
1.9 語(yǔ)音識(shí)別結(jié)果回調(diào)
- (void)onResults:(NSArray *)results isLast:(BOOL)isLast{
NSLog(@"%@",results);
}
1.10 語(yǔ)音識(shí)別完成回調(diào)郑临,該回調(diào)在語(yǔ)音識(shí)別完成或中斷了會(huì)調(diào)用,如果errorCode.errorCode為0,則是錄音完成屑宠。
- (void)onCompleted:(IFlySpeechError *)errorCode {
}
科大訊飛整個(gè)的使用流程基本就這樣了厢洞,科大的SDK用起來(lái)還是比較舒服的,SDK的注釋跟文檔也是很清晰的典奉,開發(fā)使用起來(lái)還是很簡(jiǎn)單的躺翻。
2.百度的語(yǔ)音識(shí)別
2.1 同樣的使用百度語(yǔ)音識(shí)別要到百度開發(fā)者中心創(chuàng)建應(yīng)用,勾選語(yǔ)音識(shí)別項(xiàng)卫玖,獲取到AppID公你,API Key,Secret Key假瞬。
2.2 創(chuàng)建完應(yīng)用后下載SDK陕靠,下載完后可以看到文件夾中有頭文件(BDSClientHeaders),.a文件(BDSClientLib)脱茉,Demo資源(BDSClientResource)剪芥,Demo工程(BDSClientSample),
這里的Demo是不能直接使用的芦劣,你得先對(duì)工程的AppID粗俱,API Key,Secret Key進(jìn)行賦值
2.3 導(dǎo)入.a庫(kù)虚吟,把文件夾下的BDSClientLib中的libBaiduSpeechSDK.a導(dǎo)入工程中寸认,再把BDSClientHeaders的頭文件也導(dǎo)入工程中,并添加libBaiduSpeechSDK.a所依賴的其他庫(kù)串慰,主要的依賴庫(kù)有以下這些
庫(kù)名稱 | 功能 |
---|---|
libc++.tbd | 提供對(duì)C/C++特性支持 |
libz.1.2.5.tbd | 提供gzip支持 |
AudioToolbox | 提供錄音和播放支持 |
AVFoundation | 提供錄音和播放支持 |
CFNetwork | 提供對(duì)網(wǎng)絡(luò)訪問的支持 |
CoreLocation | 提供對(duì)獲取設(shè)備地理位置的支持偏塞,以提高識(shí)別準(zhǔn)確度 |
CoreTelephony | 提供對(duì)移動(dòng)網(wǎng)絡(luò)類型判斷的支持 |
SystemConfiguration | 提供對(duì)網(wǎng)絡(luò)狀態(tài)檢測(cè)的支持 |
GLKit | 內(nèi)置識(shí)別控件所需 |
2.4 關(guān)閉bitcode,這里的設(shè)置跟1.4是一樣的邦鲫。
2.5 在info.plist添加權(quán)限說明
<key>NSMicrophoneUsageDescription</key>
<string></string>
<key>NSLocationUsageDescription</key>
<string></string>
<key>NSLocationAlwaysUsageDescription</key>
<string></string>
<key>NSContactsUsageDescription</key>
<string></string>
2.6 百度語(yǔ)音識(shí)別同樣要注冊(cè)服務(wù)灸叼,
//初始化錄音對(duì)象
self.asrEventManager = [BDSEventManager createEventManagerWithName:BDS_ASR_NAME];
//配置key
[self.asrEventManager setParameter:@[API_KEY, SECRET_KEY] forKey:BDS_ASR_API_SECRET_KEYS];
[self.asrEventManager setParameter:APP_ID forKey:BDS_ASR_OFFLINE_APP_CODE];
//這里BDS_ASR_ENABLE_LOCAL_VAD不設(shè)置為NO神汹,則會(huì)報(bào)錯(cuò)
[self.asrEventManager setParameter:@(NO) forKey:BDS_ASR_ENABLE_LOCAL_VAD];
2.7 啟動(dòng)語(yǔ)音識(shí)別
- (void)beginListen:(void (^)(NSString *, BOOL, NSError *))block {
self.block = block;
//這里不得不吐槽一下,這代理都沒說要遵守哪些協(xié)議的古今。屁魏。。捉腥。
[self.asrEventManager setDelegate:self];
[self.asrEventManager sendCommand:BDS_ASR_CMD_START];
}
百度的SDK這里有個(gè)吐槽點(diǎn)氓拼,要遵守協(xié)議,但是居然沒有說明是哪個(gè)協(xié)議抵碟,去Demo看了才知道是哪哪個(gè)協(xié)議.....
2.8 語(yǔ)音識(shí)別結(jié)果回調(diào)桃漾,同樣的這里的回調(diào)結(jié)果狀態(tài)居然用的是int類型,其實(shí)是有定義了枚舉的拟逮,百度這樣的大廠寫這樣的代碼有點(diǎn)撬统。。敦迄。恋追。。颅崩。
- (void)VoiceRecognitionClientWorkStatus:(int)workStatus obj:(id)aObj {
//百度這個(gè)做的真不怎么樣几于,都定義了枚舉蕊苗,結(jié)果還用int沿后,這寫都還的去看demo才知道。朽砰。尖滚。。瞧柔。
switch (workStatus) {
case EVoiceRecognitionClientWorkStatusFinish: {
NSString *text = [self fetchTextWithObj:aObj];
if (self.block) {
self.block(text, YES, nil);
}
break;
}
case EVoiceRecognitionClientWorkStatusCancel: {
if (self.block) {
self.block(@"", YES, nil);
}
}
break;
case EVoiceRecognitionClientWorkStatusError: {
NSError *error = nil;
if ([aObj isKindOfClass:[NSError class]]) {
error = (NSError *)aObj;
} else {
error = [NSError errorWithDomain:@"未知錯(cuò)誤" code:1000 userInfo:nil];
}
if (self.block) {
self.block(@"", YES, error);
}
}
break;
}
}
整體來(lái)說漆弄,百度的語(yǔ)音識(shí)別使用期來(lái)是不難的,但是百度這個(gè)SDK的注釋跟代碼有點(diǎn)不敢恭維造锅,特別是遵守什么協(xié)議也沒說明白撼唾,狀態(tài)類型定義了枚舉,協(xié)議中居然用的int類型哥蔚,具體的使用還得去看Demo才能找到倒谷。。糙箍。渤愁。。
3.原生的語(yǔ)音識(shí)別
3.1 原生的語(yǔ)音識(shí)別功能是iOS10之后的才有的功能
3.2 在info.plist中添加一下權(quán)限
<key>NSMicrophoneUsageDescription</key>
<string></string>
<key>NSSpeechRecognitionUsageDescription</key>
<string></string>
3.3 引入語(yǔ)音識(shí)別頭文件
#import <Speech/Speech.h>
3.4 創(chuàng)建語(yǔ)音識(shí)別對(duì)象
@property (nonatomic, strong) SFSpeechRecognizer *recognizer; ///< 語(yǔ)音識(shí)別
@property (nonatomic, strong) AVAudioEngine * audioEngine; ///< 語(yǔ)音輸入
@property (nonatomic, strong) SFSpeechAudioBufferRecognitionRequest * recognitionRequest; ///< 語(yǔ)音識(shí)別請(qǐng)求
@property (nonatomic, strong) SFSpeechRecognitionTask * recognitionTask ; ///< 語(yǔ)音識(shí)別任務(wù)
3.4 判斷是否有語(yǔ)音是被權(quán)限
if (@available(iOS 10.0, *)) {
[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
switch (status) {
case SFSpeechRecognizerAuthorizationStatusAuthorized:{
//可以使用
self.canListen = YES;
}
break;
case SFSpeechRecognizerAuthorizationStatusNotDetermined:{
self.errorDomain = @"用戶還沒選擇是否允許錄音";
self.canListen = NO;
}
break;
case SFSpeechRecognizerAuthorizationStatusRestricted: {
self.errorDomain = @"該設(shè)備不支持錄音";
self.canListen = NO;
}
break;
case SFSpeechRecognizerAuthorizationStatusDenied: {
self.errorDomain = @"用戶拒絕了錄音";
self.canListen = NO;
}
break;
}
}];
}
3.5 初始化語(yǔ)音輸入對(duì)象深夯,系統(tǒng)的有語(yǔ)言識(shí)別限制抖格,你必須先設(shè)置你識(shí)別的語(yǔ)言環(huán)境。
//語(yǔ)音識(shí)別為中文@"zh_CN"
self.recognizer = [[SFSpeechRecognizer alloc] initWithLocale:[NSLocale localeWithLocaleIdentifier:@"zh_CN"]];
self.recognizer.delegate = self;
self.audioEngine = [[AVAudioEngine alloc] init];
[self.audioEngine.inputNode installTapOnBus:0 bufferSize:1024 format: [self.audioEngine.inputNode outputFormatForBus:0] block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
[self.recognitionRequest appendAudioPCMBuffer:buffer];
}];
3.6 啟動(dòng)語(yǔ)音識(shí)別&語(yǔ)音識(shí)別回調(diào)
- (void)beginListen:(void (^)(NSString *, BOOL, NSError *))block {
if (@available(iOS 10.0, *)) {
if (!self.canListen) {
if (block) {
block(@"", YES, [NSError errorWithDomain:self.errorDomain code:1000 userInfo:nil]);
}
return;
}
self.block = block;
self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc]init];
__weak typeof(self) weakSelf = self;
if (@available(iOS 10.0, *)) {
self.recognitionTask = [self.recognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {//這里為語(yǔ)音識(shí)別回調(diào)
typeof(weakSelf) self = weakSelf; if (!self) return;
if (self.block) {
self.text = result.bestTranscription.formattedString;
self.block(self.text, NO, error);
}
}];
} else {
// Fallback on earlier versions
}
[self.audioEngine prepare];
NSError *error = nil;
[self.audioEngine startAndReturnError:&error];
}
}
相對(duì)來(lái)說,使用系統(tǒng)原生的雹拄,步驟相對(duì)復(fù)雜收奔,需要自己控制語(yǔ)音輸入,判斷系統(tǒng)權(quán)限等滓玖;
4.三種語(yǔ)音轉(zhuǎn)文本的對(duì)比
語(yǔ)音識(shí)別方案 | 支持系統(tǒng) | 離線 | 使用復(fù)雜度 |
---|---|---|---|
科大訊飛 | 8.0以上 | 收費(fèi)支持 | 低 |
百度 | 8.0以上 | 收費(fèi)支持 | 中 |
原生 | 10.0以上 | 支持 | 高 |
5 Demo
本來(lái)有Demo筹淫,但是在上傳github的時(shí)候操作出錯(cuò),把Demo的文件都給刪呢撞。损姜。。殊霞。摧阅。。