標籤:
參考:http://blog.sina.com.cn/s/blog_923fdd9b0101flx1.html
通過Google語音介面的實現語音辨識
最近在項目中有需要實現語音辨識的功能。折騰了幾天才搞好。剛開始做的時候沒點頭緒 ,網上找的資料都是亂七八糟的,要不就是非常古老的實現方法,一些簡單的程式碼片段。所以我決定把我的經驗分享給大家。
要在IOS中實現語音辨識流程如下:
錄音->pcm格式->轉換wav->轉換flac->向Google發送請求->等待返回的json資料->解析資料;
首先如果你要使用Google的介面實現語音辨識必須知道下面著幾點:
1.如何發送POST請求。(可以使用開源庫ASIHttpRequest,AFNetWorking,這些庫都封裝了網路請求,使用起來非常簡單);
2.瞭解音頻格式pcm,wav,flac,(著三個音頻格式的關係是,因為Google介面只接受flac音頻格式,其他格式無法識別,IOS中無法錄製flac音頻格式,也無法錄製wav,只能錄製pcm,所以要一步一步轉換);
3.瞭解AVAudioRecorder類如何使用,怎麼配置.
在IOS中錄音就要使用AVAudioRecorder這個類,這個類的執行個體方法如下:
- (id)initWithURL:(NSURL *)url settings:(NSDictionary *)settings error:(NSError **)outError;
url:錄音完成後聲音存放的位置,
settings:設定錄製聲音的參數,只有一個關鍵的key跟大家講下AVFormatIDKey,這個key決定你錄製出來聲音的格式,我們要錄成lpcm格式,未壓縮的原音資料,以便我們轉換,所以使用kAudioFormatLinearPCM值.其他key可以在協助文檔看,
NSMutableDictionary *recordSetting =[[NSMutableDictionaryalloc]init];
[recordSetting setValue:[NSNumbernumberWithInt:kAudioFormatLinearPCM]forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumbernumberWithFloat:16000.0]forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumbernumberWithInt:1]forKey:AVNumberOfChannelsKey];
[recordSetting setValue:[NSNumbernumberWithInt:16]forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumbernumberWithInt:AVAudioQualityHigh]forKey:AVEncoderAudioQualityKey];
[recordSetting setValue:@(NO)forKey:AVLinearPCMIsBigEndianKey];
設定完這個對象後就可以開始錄音了.得到lpcm格式音頻資料後就開始我們的第一次轉換,轉換成wav,什麼是wav呢?點擊, 知道wav是什麼之後就可以開始轉碼了.轉碼是用C實現的,著部分代碼在下面我打包的檔案裡面;
檔案轉換成WAV之後還需要將WAV的轉換成FLAC才能上傳到Google介面進行語音辨識,幸好在在github上有人封裝好了一個FLAC的開源庫:https://github.com/jhurt/FLACiOS
下載這個源碼後要去掉OGG的支援,不然編譯不過。直接點擊檔案-,編譯後進入,Products目錄拿到.a和framework,把這個兩個檔案一起加入你的工程。
聲音處理完畢後就要往Google語音介面發請求了。我是使用ASI發的請求,大家可以用其他庫來發,畢竟ASI有點太老了,我只是用習慣了而已。這裡的filePath就是轉換後FLAC檔案的地址;
#define GOOGLE_AUDIO_URL@"http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN"
NSURL *URL = [NSURLURLWithString:GOOGLE_AUDIO_URL];
ASIFormDataRequest *request =[ASIFormDataRequestrequestWithURL:URL];
[request addRequestHeader:@"Content-Type"value:@"audio/x-flac;rate=16000"];
[requestappendPostDataFromFile:filePath];
[requestsetRequestMethod:@"POST"];
request.completionBlock = ^{
NSLog(@"json:%@",request.responseString);
NSData *data = request.responseData;
idret = nil;
ret =[NSJSONSerializationJSONObjectWithData:data options:NSJSONReadingMutableContainerserror:nil];
NSLog(@"ret %@",ret);
results(ret);
};
request.failedBlock = ^{
UIAlertView *alert =[[UIAlertViewalloc]initWithTitle:@"錯誤"message:@"網路請求錯誤" delegate:nilcancelButtonTitle:@"確定" otherButtonTitles:nil,nil];
[alert show];
NSLog(@"網路請求錯誤:%@",request.error);
};
[request startSynchronous];
-----------------------------------------------------------------------------------------------以下是Google返回的JSON解析--------------------------------------------------------------------------------------------
if(dic ==nil || [dic count] ==0){
return;
}
NSArray *array = [dicobjectForKey:@"hypotheses"];
if ([arraycount] ) {
NSDictionary *dic_hypotheses = [arrayobjectAtIndex:0];
NSString * sContent= [NSStringstringWithFormat:@"%@",[dic_hypothesesobjectForKey:@"utterance"]];
self.textField.text = sContent;
}
這裡是我寫的一個測試工程全部代碼
http://pan.baidu.com/s/1kTMBBk7;直接可以用
[ios]ios語音辨識