語(yǔ)音轉(zhuǎn)文本的三種方案

語(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楞泼。


獲取APPID.png

1.2 下載完SDK后驰徊,解壓縮后里面有文檔(Doc),F(xiàn)ramework(lib)堕阔,版本信息(release.txt)棍厂,Demo(sample)。這方面科大還是做的比較好的超陆,很多東西都一目了然的牺弹,初次使用的話可以研究一下Demo。


SDK文件內(nèi)容.png

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ò)誤.

bitcoe錯(cuò)誤.png

bitcode 設(shè)置方式為 Targets -> Build Settings,搜索bitcode欣福,設(shè)置為NO。


bitcode設(shè)置.png

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假瞬。


BD應(yīng)用管理.png

2.2 創(chuàng)建完應(yīng)用后下載SDK陕靠,下載完后可以看到文件夾中有頭文件(BDSClientHeaders),.a文件(BDSClientLib)脱茉,Demo資源(BDSClientResource)剪芥,Demo工程(BDSClientSample),

BDDemo.png

這里的Demo是不能直接使用的芦劣,你得先對(duì)工程的AppID粗俱,API Key,Secret Key進(jìn)行賦值


BDAppID配置.png

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é)議.....


BD頭文件.png

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的文件都給刪呢撞。损姜。。殊霞。摧阅。。


欲哭無(wú)淚.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绷蹲,一起剝皮案震驚了整個(gè)濱河市棒卷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祝钢,老刑警劉巖比规,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拦英,居然都是意外死亡蜒什,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門疤估,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)灾常,“玉大人,你說我怎么就攤上這事铃拇〕伲” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵慷荔,是天一觀的道長(zhǎng)雕什。 經(jīng)常有香客問我,道長(zhǎng)显晶,這世上最難降的妖魔是什么贷岸? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮吧碾,結(jié)果婚禮上凰盔,老公的妹妹穿的比我還像新娘。我一直安慰自己倦春,他們只是感情好户敬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布落剪。 她就那樣靜靜地躺著,像睡著了一般尿庐。 火紅的嫁衣襯著肌膚如雪忠怖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天抄瑟,我揣著相機(jī)與錄音凡泣,去河邊找鬼。 笑死皮假,一個(gè)胖子當(dāng)著我的面吹牛鞋拟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惹资,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼贺纲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了褪测?” 一聲冷哼從身側(cè)響起猴誊,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侮措,沒想到半個(gè)月后懈叹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡分扎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年澄成,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笆包。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡环揽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出庵佣,到底是詐尸還是另有隱情,我是刑警寧澤汛兜,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布巴粪,位于F島的核電站,受9級(jí)特大地震影響粥谬,放射性物質(zhì)發(fā)生泄漏肛根。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一漏策、第九天 我趴在偏房一處隱蔽的房頂上張望派哲。 院中可真熱鬧,春花似錦掺喻、人聲如沸芭届。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)褂乍。三九已至持隧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逃片,已是汗流浹背屡拨。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留褥实,地道東北人呀狼。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像损离,于是被迫代替她去往敵國(guó)和親赠潦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容