在目前的軟體應用中,輸入方式還是以文字輸入方式為主,但是語音輸入的方式目前應用的越來越廣泛。這是一個利用 Olami SDK 編寫的一個24點iOS程式,是通過語音進行輸入。 Olami SDK的介紹在下麵這個網址 https://cn.olami.ai/wiki/?mp=sdk&content... ...
前言
在目前的軟體應用中,輸入方式還是以文字輸入方式為主,但是語音輸入的方式目前應用的越來越廣泛。這是一個利用 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 下載
- 去上面的網址下載Olami SDK.包括兩個文件,其中的一個是Olami的靜態函數庫,一個是其頭文件
第一步是初始化Olami的語音識別對象,並設置代理
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