前述:自從看了羅永浩在錘子手機(jī)發(fā)布會上,展示了一下語音識別技術(shù),錘子手機(jī)集成的是訊飛語音技術(shù)。感覺好牛逼,很高大上的樣子。因?yàn)檫@樣我對語音識別技術(shù)開始感興趣了。最近在網(wǎng)上逛網(wǎng)站、技術(shù)博客時(shí),看到了一篇介紹蘋果自帶的語音識別組件Speech的文章。并且仔細(xì)查看了該組建的開發(fā)文檔。所以著手寫了這篇文章。
一、SPeech組成部分
SFSpeechRecognizer.h 語音識別器
SFSpeechRecognitionRequest.h 語音識別請求
SFSpeechRecognitionTask.h ? 語音識別任務(wù)
SFSpeechRecognitionTaskHint.h 語音識別的類型
SFSpeechRecognitionResult.h 語音識別的結(jié)果
SFTranscriptionSegment.h 轉(zhuǎn)錄的子串
SFTranscription.h 語音錄制的文本形式
二、語音識別前的驗(yàn)證及準(zhǔn)備
聲明三個(gè)屬性:
@property (weak, nonatomic) IBOutlet UITextView *wordTextView;
@property (weak, nonatomic) IBOutlet UIButton *recordBtn;
@property(nonatomic,strong) SFSpeechRecognizer *recognizer;
//識別功能
@property(nonatomic,strong) SFSpeechAudioBufferRecognitionRequest *recognitionRequest;
@property(nonatomic,strong) SFSpeechRecognitionTask *recognitionTask;
@property(nonatomic,strong) AVAudioEngine *engine;
[SFSpeechRecognizer supportedLocales] //當(dāng)前蘋果支持語音識別的時(shí)區(qū) 目前支持62門語言
NSLocale *cale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh-CN"]; //時(shí)區(qū)對象
self.recognizer = [[SFSpeechRecognizer alloc] initWithLocale:cale]; //用時(shí)區(qū)來初始化識別器 目前只支持識別一個(gè)時(shí)區(qū)
self.recognizer.delegate = self; //設(shè)置代理
//識別器代理方法 語音識別識別改變的代理方法
-(void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available {
//設(shè)置控制語音識別按鈕的是否可點(diǎn)擊
}
//檢查設(shè)備是否支持語音識別
//注意//注意要在info中加入私有白名單?Privacy - Speech Recognition Usage Description
[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
BOOL isButtonEnabled = false;
switch (status) {
case SFSpeechRecognizerAuthorizationStatusDenied:
//設(shè)置按鈕是否可點(diǎn)擊
isButtonEnabled = false;
NSLog(@"用戶被拒絕訪問語音識別");
break;
case SFSpeechRecognizerAuthorizationStatusAuthorized:
isButtonEnabled = true;
NSLog(@"可以語音識別");
break;
case SFSpeechRecognizerAuthorizationStatusRestricted:
isButtonEnabled = false;
NSLog(@"不能在該設(shè)備上進(jìn)行語音識別");
break;
case SFSpeechRecognizerAuthorizationStatusNotDetermined:
isButtonEnabled = false;
NSLog(@"沒有授權(quán)");
break;
default:
break;
}
//注意當(dāng)前線程是子線程
NSLog(@"%@",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
//回到主線程刷新UI,設(shè)置按鈕是否可點(diǎn)擊
self.recordBtn.enabled = isButtonEnabled;
});
}];
三、語音識別
//開始錄制 - 識別語音轉(zhuǎn)文字
- (void)startRecording {
if (self.recognitionTask) {
[self.recognitionTask cancel];
self.recognitionTask = nil;
}
//判斷語音錄入是否可用
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
//注意要在info中加入私有白名單?Privacy - Microphone Usage Description
BOOL audioBool = [audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
//Category
AVAudioSessionCategoryPlayAndRecord?錄制音頻時(shí)使用這個(gè)類別
AVAudioSessionCategoryAmbient?使用這個(gè)類別的背景聲音,如雨,汽車發(fā)動機(jī)噪音,等等
AVAudioSessionCategorySoloAmbient ?使用這個(gè)類別的背景聲音。其他的音樂將停止演奏
AVAudioSessionCategoryPlayback?使用這類音樂曲目
AVAudioSessionCategoryPlayAndRecord?在錄制和回放音頻時(shí)使用這個(gè)類別
BOOL audioBool1 = [audioSession setMode:AVAudioSessionModeMeasurement error:nil];
//mode?
AVAudioSessionModeMeasurement?適用于希望盡量減少系統(tǒng)提供的信號效果的應(yīng)用程序 處理輸入和/或輸出音頻信號
//激活音頻會話
BOOL audioBool2 = [audioSession setActive:true withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
if (audioBool || audioBool1 || audioBool2) {
NSLog(@"可以使用");
} else {
NSLog(@"這里說明有的功能不支持");
}
//創(chuàng)建識別請求:?從任意音頻緩沖區(qū)識別語音的請求
self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
AVAudioInputNode *inputNode = self.engine.inputNode;
//報(bào)告這個(gè)識別是否是最終結(jié)果
self.recognitionRequest.shouldReportPartialResults = true;
//開始識別任務(wù)
self.recognitionTask = [self.recognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
BOOL isFinal = false;
if (result) {
//語音轉(zhuǎn)文本
self.wordTextView.text = [[result bestTranscription] formattedString];
isFinal = [result isFinal];
}
if (error || isFinal) {
//沒有識別到,
[self.engine stop];
銷毀節(jié)點(diǎn)
[inputNode removeTapOnBus:0];
self.recognitionRequest = nil;
self.recognitionTask = nil;
self.recordBtn.enabled = true;
}
}];
AVAudioFormat *recordingFormat = [inputNode outputFormatForBus:0];
////連接上次的語音輸入
[inputNode installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
[self.recognitionRequest appendAudioPCMBuffer:buffer];
}];
//識別器準(zhǔn)備
[self.engine prepare];
BOOL audioEngineBool = [self.engine startAndReturnError:nil];
NSLog(@"audioEngineBool----%d",audioEngineBool);
}
小伙伴們,這樣就識別成功了。