使用OLAMISDK實現一個語音輸入數字進行24點計算的iOS程式,olamisdkios
前言
在目前的軟體應用中,輸入方式還是以文字輸入方式為主,但是語音輸入的方式目前應用的越來越廣泛。這是一個利用 Olami SDK 編寫的一個24點iOS程式,是通過語音進行輸入。
Olami SDK的介紹在下面這個網址
https://cn.olami.ai/wiki/?mp=sdk&content=sdk/ios/reference.html
在這個網址中詳細的介紹了Olami SDK包含了那些函數和定義的委託。
App實現
下面就通過24點這個程式來介紹一下如何使用這個SDK。
這個APP可在 https://github.com/lym-ay/OlamiRecognizerMath24 下載
olamiRecognizer= [[OlamiRecognizer alloc] init];olamiRecognizer.delegate = self;
2.調用setAuthorization函數進行授權
[olamiRecognizer setAuthorization:@"d13bbcbef2a4460dbf19ced850eb5d83" api:@"asr" appSecret:@"3b08b349c0924a79869153bea334dd86" cusid:OLACUSID];
這個函數的參數的說明在OlamiRecognizer中有說明,也可以去線上API說明去查看
https://cn.olami.ai/wiki/?mp=sdk&content=sdk/ios/reference.html
有些參數必須去Olami的開發平台上註冊才可以獲的,網址是https://olami.ai,註冊登陸以後建立應用才可以看到了
3.設定語系
[olamiRecognizer setLocalization:LANGUAGE_SIMPLIFIED_CHINESE];
在進行錄音之前必須要先進行設定,否則會得不到結果。目前只支援簡體中文(LANGUAGE_SIMPLIFIED_CHINESE)
4.開始錄音
調用 start()介面開始進行錄音
[olamiRecognizer start];
5.得到錄音的文字和語義,並對其進行處理
通過調用stop()函數或者自動停止,都會獲得錄音的文字和對其進行的語義分析的結果
實現OlamiRecognizerDelegate onResult函數可以獲得結果,其結果以一個json字串的形式回調過來,對這個字串進行解析,就可以獲得想要的數字。例如對著話筒說”2345算24點”,得到的結果如下
{ "data": { "asr": { "result": "二 三 四 五 算 二 十 四 點", "speech_status": 0, "final": true, "status": 0 }, "nli": [ { "desc_obj": { "status": 0 }, "semantic": [ { "app": "math24", "input": "二三四五算二十四點", "slots": [ { "num_detail": { "recommend_value": "", "type": "number" }, "name": "number3", "value": "4" }, { "num_detail": { "recommend_value": "", "type": "number" }, "name": "number4", "value": "5" }, { "num_detail": { "recommend_value": "", "type": "number" }, "name": "number1", "value": "2" }, { "num_detail": { "recommend_value": "", "type": "number" }, "name": "number2", "value": "3" } ], "modifier": [ "play_calculate" ], "customer": "58df685e84ae11f0bb7b4893" } ], "type": "math24" } ] }, "status": "ok"}
這個是根據OSL文法描述語言定義的一套規則,返回的結果。這個結果的說明在 https://cn.olami.ai/wiki/?mp=api_nlu&content=api_nlu3.html 這個網址上有說明。
看到這裡大家可能會有疑惑,APP怎麼知道我說的是什麼意思呢?這就涉及到了OSL文法描述語言,OLAMI 文法描述語言(OLAMI Syntax Language,簡稱:OSL)是 OLAMI 平台針對自然語言處理所發展出的獨特文法標記語言,自然語言語義互動(Natural Language Interaction, 簡稱:NLI)管理系統採用 OSL 取代複雜的編碼編程,使用簡單、容易學習而且靈活有彈性。可以在這個網址查看詳細的說明
https://cn.olami.ai/wiki/?mp=osl&content=osl1.html
在編寫這個APP之前,會按照OSL的要求編寫好一套文法,這套文法可以被Olami的伺服器所理解,並進行語義分析然後給出結果,就是上面的json字串。在Olami官網上有寫好的一些領域的模組,可以直接使用。在 https://cn.olami.ai/wiki/?mp=nli&content=nli1.html 網址可以看到介紹如何使用以後的模組。這個24點就是利用已有的模組來編寫代碼的。
6.建立應用,設定和匯入grammar
首先去olami的首頁去登陸和註冊。登陸以後轉到這頁面
在這個頁面可以看到我的應用程式 math24,還可以查看key
當然這個頁面必須建立應用以後才有,點擊“建立新應用”,轉到下面這個頁面
填寫 應用程式名稱,應用描述,應用介紹以後,就可以建立了。回到上一個頁面,就可以看到建立的應用了。
點擊”進入NLI系統”就可以進入模組頁面
在官網已經內建了很多領域的grammar.在模組頁面大家點擊“匯入”按鈕,查看已有領域的模組
選擇一個要使用的,例如我要匯入”math24”這個模組,先選擇它,點擊“匯入” 按鈕
然後進入 math24模組,就可以看到例句
但是這個時候還是不能使用,需要先進行發布。點擊頁面上方的”發布”按鈕,進入發佈頁面
點擊“發布”按鈕
發布成功,現在就可以使用24模組了。
Olami還提供了測試grammar的功能,點擊“測試”按鈕,可以在頁面進行測試,而不必要先開發APP
最後還要回到“我的應用程式”介面,點擊”配置NLI模組”按鈕,讓自己建立的應用和模組關聯起來
7.onResult 函數的說明
在整個程式中,最主要的一個函數就是onResult函數
- (void)onResult:(NSData *)result { NSError *error; __weak typeof(self) weakSelf = self; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingMutableContainers error:&error]; if (error) { NSLog(@"error is %@",error.localizedDescription); }else{ NSString *jsonStr=[[NSString alloc]initWithData:result encoding:NSUTF8StringEncoding]; NSLog(@"jsonStr is %@",jsonStr); NSString *ok = [dic objectForKey:@"status"]; if ([ok isEqualToString:@"ok"]) { NSDictionary *dicData = [dic objectForKey:@"data"]; NSDictionary *asr = [dicData objectForKey:@"asr"]; if (asr) {//如果asr不為空白,說明目前是語音輸入 [weakSelf processASR:asr]; } NSDictionary *nli = [[dicData objectForKey:@"nli"] objectAtIndex:0]; NSDictionary *desc = [nli objectForKey:@"desc_obj"]; int status = [[desc objectForKey:@"status"] intValue]; if (status != 0) {// 0 說明狀態正常,非零為狀態不正常 NSString *result = [desc objectForKey:@"result"]; dispatch_async(dispatch_get_main_queue(), ^{ _resultTextView.text = result; }); }else{ NSDictionary *semantic = [[nli objectForKey:@"semantic"] objectAtIndex:0]; [weakSelf processSemantic:semantic]; } }else{ dispatch_async(dispatch_get_main_queue(), ^{ _resultTextView.text = @"請說出10以內的4個數"; }); } }}
這個函數就是對傳過來的結果進行處理
在這個函數中,調用了三個函數,分別來處理josn格式中的三個比較重要的節點
- (void)processASR:(NSDictionary*)asrDic { NSString *result = [asrDic objectForKey:@"result"]; if (result.length == 0) { //如果結果為空白,則彈出警告框 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"沒有接受到語音,請重新輸入!" message:nil preferredStyle:UIAlertControllerStyleAlert]; [self presentViewController:alertController animated:YES completion:^{ dispatch_time_t time=dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC); dispatch_after(time, dispatch_get_main_queue(), ^{ [alertController dismissViewControllerAnimated:YES completion:nil]; }); }]; }else{ dispatch_async(dispatch_get_main_queue(), ^{ NSString *str = [result stringByReplacingOccurrencesOfString:@" " withString:@""];//去掉字元中間的空格 _inputTextView.text = str; }); }}
這個用來處理ASR節點,獲得語音辨識的結果,如果沒有結果,則彈出一個對話方塊進行提示。ASR識別的文字顯示在第一個TextView中
- (void)processSemantic:(NSDictionary*)semanticDic { NSArray *slot = [semanticDic objectForKey:@"slots"]; [_slotValue removeAllObjects]; if (slot.count != 0) { for (NSDictionary *dic in slot) { NSString* val = [dic objectForKey:@"value"]; [_slotValue addObject:val]; } } NSArray *modify = [semanticDic objectForKey:@"modifier"]; if (modify.count != 0) { for (NSString *s in modify) { [self processModify:s]; } }}
這個用來處理Semantic節點,這個節點中包含了slot的值和modifier的值。OSL 文法描述語言中的 slot 可理解為語義中的變數,用於傳遞、提取資訊,是代碼處理的資料的來源。對於24點這個程式來說,就是進行計算的4的數的來源。關於slot的值可以參考 https://cn.olami.ai/wiki/?mp=osl&content=osl_slot.html,這裡有詳細說明。在24點程式中我們的要計算的數字就是從這裡獲得的。
- (void)processModify:(NSString*) str { if ([str isEqualToString:@"play_want"] || [str isEqualToString:@"play_want_ask"] || [str isEqualToString:@"needmore"] || [str isEqualToString:@"needmore_ask"]) {//要求使用者輸入值 dispatch_async(dispatch_get_main_queue(), ^{ _resultTextView.text = @"請說出10以內的4個數"; }); }else if ([str isEqualToString:@"rules"]){ dispatch_async(dispatch_get_main_queue(), ^{ _resultTextView.text = @"四個數字運算結果等於二十四"; }); }else if ([str isEqualToString:@"play_calculate"]){ NSString* str = [[Math24 shareInstance] calculate:_slotValue]; dispatch_async(dispatch_get_main_queue(), ^{ _resultTextView.text = str; }); }else if ([str isEqualToString:@"attention"]){ dispatch_async(dispatch_get_main_queue(), ^{ _resultTextView.text = @"四個數字必須是10以內的,不能超過10"; }); }}
這個用來處理語音和語義的結果。這個函數主要是處理json字串中的modifier節點。modifier 文法描述規則是 OSL 文法描述語言中,除了 slot 以外的另一種內建的資訊傳遞機制,一般用來表示語義目的,也可以理解為對於語義的一種注釋方式,以便讓應用程式的開發人員得知 grammar 所代表的相應意圖。詳細說明參考
https://cn.olami.ai/wiki/?mp=osl&content=osl_regex.html#11,通過modifier,我們才能知道程式的意圖是什嗎?例如是想發問,還是計算結果。
如上代碼所示,在24點鐘我們定義了7個modifier,根據字面意思大家也可以猜出來。這些都可以在OSL文法中自訂,然後通過Josn字串獲得,在程式中進行處理。這個是我們程式進行處理的一個判斷機制。
下載資源
可以在csdn下載頻道下載
http://download.csdn.net/detail/dfman1978/9840447
github
https://github.com/lym-ay/OlamiRecognizerMath24
另外這裡還有幾篇使用Olami SDK開發程式的文章
這個是一個聽書的程式
http://blog.csdn.net/ls0609/article/details/71519203
這個是一個關於天氣的程式
http://blog.csdn.net/zhangxy0605/article/details/71601604
這是一個根據OLAMI平台開發的日曆demo
http://blog.csdn.net/xinfinityx/article/details/72840977