关于百度UNIT交互语音的集成详解

最近公司需要开发机器人聊天带语音的功能 ,通过一些筛选,最终选择了百度UNIT交互已经百度本身的语音集成到程序里,这里做下记录,方便以后学习,也希望可以帮助到需要的人(测试时候必须真机测试 否则会报错)

模拟器运行报错

屏幕快照 2017-11-06 14.58.53.png

首先到百度语音平台下载对应的SDK 选择UNIT iOS SDK下载 如下截图

屏幕快照 2017-11-06 14.36.51.png

下载完成之后得到文件 运行Unitdemo演示程序

屏幕快照 2017-11-06 14.40.40.png

运行成功如截图

IMG_1370.PNG

运行正常然后按照演的demo脱文件UnitSDK和文件libs文件到需要集成的APP中

屏幕快照 2017-11-07 10.32.03.png

这里需要注意 libs文件中的BDSClientResources文件需要拖入是取消第一个选择


屏幕快照 2017-11-07 10.34.02.png

填入对应的Framwork文件 截图取至百度云语音集成平台

屏幕快照 2017-11-07 10.35.23.png

如果Xcode版本可以自动添加.m文件 手动去Build Phases删除AudioDataQueue文件 否则会报C++错误 删除.mm文件 否则会报错

接下来上具体集成代码

// 按需求引入头文件
#import "AIPUnitSDK.h"
// 内置识别控件
#import "BDRecognizerViewController.h"
// 识别相关
#import "BDSEventManager.h"
#import "BDSASRDefines.h"
#import "BDSASRParameters.h"
// 唤醒相关
#import "BDSWakeupDefines.h"
#import "BDSWakeupParameters.h"
// 引入代理协议BDRecognizerViewDelegate
-(void)viewdidload{

    inputview = [[UITextField alloc]initWithFrame:CGRectMake(20, 5, kScreenWidth-40, 40)];
    inputview.layer.cornerRadius = 10;
    inputview.layer.masksToBounds = YES;
    inputview.layer.borderWidth = 1;
    inputview.layer.borderColor = [[UIColor lightGrayColor] CGColor];
    inputview.returnKeyType = UIReturnKeySend;  //(如上图的send ,在真机上会显示发送二字的)
    inputview.delegate = self;
    
//    [_inputTextViewBkView addSubview:_inputTextView];
    [textviwe addSubview:inputview];
    [self.view addSubview:textviwe];
    
    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0, 0, 30, 30);
    [button addTarget:self action:@selector(sdkUIRecognitionAction:) forControlEvents:UIControlEventTouchUpInside];
    [button setImage:[UIImage imageNamed:@"speaker"] forState:UIControlStateNormal];
    inputview.rightView = button;
    inputview.rightViewMode = UITextFieldViewModeAlways;

[SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeGradient];
    [SVProgressHUD show];
// API_KEY  SECRET_KEY 必须去百度语音官网创建应用程序获得 要和程序boundleID保持一致 具体过程百度语音官网上很详细
    [[AIPUnitSDK sharedInstance] getAccessTokenWithAK:API_KEY SK:SECRET_KEY completion:^{
        [SVProgressHUD dismiss];
    }];
 [[AIPUnitSDK sharedInstance] setSceneID:3087];
//    self.titleLabel.text = @"选股机器人";
    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if ([AIPUnitSDK sharedInstance].accessToken != nil) {
            [weakSelf askWord:@"你好"];
        } else {
            weakSelf.waitTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(waitAccessToken) userInfo:nil repeats:YES];
        }
    });
    
    // 配置语音
    self.asrEventManager = [BDSEventManager createEventManagerWithName:BDS_ASR_NAME];
    //设置DEBUG_LOG的级别
    [self.asrEventManager setParameter:@(EVRDebugLogLevelTrace) forKey:BDS_ASR_DEBUG_LOG_LEVEL];
    //配置API_KEY 和 SECRET_KEY
    [self.asrEventManager setParameter:@[API_KEY2, SECRET_KEY2] forKey:BDS_ASR_API_SECRET_KEYS];
    [self.asrEventManager setParameter:APPID2 forKey:BDS_ASR_OFFLINE_APP_CODE];
    //配置端点检测
    NSString *modelVAD_filepath = [[NSBundle mainBundle] pathForResource:@"bds_easr_basic_model" ofType:@"dat"];
    [self.asrEventManager setParameter:modelVAD_filepath forKey:BDS_ASR_MODEL_VAD_DAT_FILE];
    [self.asrEventManager setParameter:@(YES) forKey:BDS_ASR_ENABLE_MODEL_VAD];
}
- (void)waitAccessToken {
    if ([AIPUnitSDK sharedInstance].accessToken != nil) {
        [self.waitTimer invalidate];
        self.waitTimer = nil;
        [self askWord:@"你好"];
    }
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [inputview resignFirstResponder];
}


#pragma mark - Button Action
- (void)hint:(UIButton *)sender {
    [inputview resignFirstResponder];
    if (sender.currentTitle.length == 0) {
        return;
    }
    [_mainArray addObject:@{@"chat":sender.currentTitle,@"type":@(1)}];
    self.bottomLayoutConstraint.constant = 0;
    [self askWord:sender.currentTitle];
}


- (void)sdkUIRecognitionAction:(UIButton *)button
{
  
    [inputview resignFirstResponder];
    [self.asrEventManager setParameter:@"" forKey:BDS_ASR_AUDIO_FILE_PATH];
    [self configFileHandler];
    [self configRecognizerViewController];
    [self.recognizerViewController startVoiceRecognition];
}
- (void)configRecognizerViewController {
    
    BDRecognizerViewParamsObject *paramsObject = [[BDRecognizerViewParamsObject alloc] init];
    paramsObject.isShowTipAfterSilence = YES;
    paramsObject.isShowHelpButtonWhenSilence = NO;
    paramsObject.tipsTitle = @"您可以这样问";
    paramsObject.tipsList = [NSArray arrayWithObjects:@"我要吃饭", @"我要买电影票", @"我要订酒店", nil];
    paramsObject.waitTime2ShowTip = 0.5;
    paramsObject.isHidePleaseSpeakSection = YES;
    paramsObject.disableCarousel = NO;
    
    self.recognizerViewController = [[BDRecognizerViewController alloc] initRecognizerViewControllerWithOrigin:CGPointMake((self.view.bounds.size.width - 300)/2.0f, 100)
                                                                                                         theme:nil
                                                                                              enableFullScreen:NO
                                                                                                  paramsObject:paramsObject
                                                                                                      delegate:self];
//    [self.view addSubview:self.recognizerViewController.view];
//    self.recognizerViewController.view.backgroundColor = [UIColor redColor];
    speekView = [[UIView alloc]initWithFrame:CGRectMake(20, 30, kScreenWidth-40, 220)];
//    speekView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.recognizerViewController.view.bounds.size.width, self.recognizerViewController.view.bounds.size.height)];
    speekView.backgroundColor = [UIColor whiteColor];
    speekView.alpha = 0.6;
    speekView.layer.cornerRadius = 15;
    speekView.layer.masksToBounds = YES;
    speekView.layer.borderWidth = 1;
    speekView.layer.borderColor = [[UIColor lightGrayColor] CGColor];
    [self.view addSubview:speekView];
    
}
- (void)configFileHandler {
    self.fileHandler = [self createFileHandleWithName:@"recoder.pcm" isAppend:NO];
}
#pragma mark - BDRecognizerViewDelegate
- (void)onEndWithViews:(BDRecognizerViewController *)aBDRecognizerViewController withResult:(id)aObj {
    if ([aObj isKindOfClass:[NSDictionary class]]) {
        NSDictionary* dict = (NSDictionary *)aObj;
        inputview.text = dict[@"results_recognition"][0];
        [self textFieldShouldReturn:inputview];
    }
}
#pragma mark - MVoiceRecognitionClientDelegate
- (void)VoiceRecognitionClientWorkStatus:(int)workStatus obj:(id)aObj {
    
//    NSLog(@"调用语音");
    
    switch (workStatus) {
        case EVoiceRecognitionClientWorkStatusNewRecordData: {
            NSLog(@"EVoiceRecognitionClientWorkStatusNewRecordData");
            //[self.fileHandler writeData:(NSData *)aObj];
            break;
        }

        case EVoiceRecognitionClientWorkStatusStartWorkIng: {
            NSDictionary *logDic = [self parseLogToDic:aObj];
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK: start vr, log: %@\n", logDic]];
            [self onStartWorking];
            break;
        }
        case EVoiceRecognitionClientWorkStatusStart: {
            [self printLogTextView:@"CALLBACK: detect voice start point.\n"];
            break;
        }
        case EVoiceRecognitionClientWorkStatusEnd: {
            [self printLogTextView:@"CALLBACK: detect voice end point.\n"];
            break;
        }
        case EVoiceRecognitionClientWorkStatusFlushData: {
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK: partial result - %@.\n\n", [self getDescriptionForDic:aObj]]];
            break;
        }
        case EVoiceRecognitionClientWorkStatusFinish: {
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK: final result - %@.\n\n", [self getDescriptionForDic:aObj]]];
            if ([aObj isKindOfClass:[NSDictionary class]]) {
                NSDictionary* dict = (NSDictionary *)aObj;
                inputview.text = dict[@"results_recognition"][0];
                [self textFieldShouldReturn:inputview];
            }
            
            [self onEnd];
           
            break;
        }
        case EVoiceRecognitionClientWorkStatusMeterLevel: {
            break;
        }
        case EVoiceRecognitionClientWorkStatusCancel: {
            [self printLogTextView:@"CALLBACK: user press cancel.\n"];
            [self onEnd];
            break;
        }
        case EVoiceRecognitionClientWorkStatusError: {
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK: encount error - %@.\n", (NSError *)aObj]];
            [self onEnd];
            break;
        }
        case EVoiceRecognitionClientWorkStatusLoaded: {
            [self printLogTextView:@"CALLBACK: offline engine loaded.\n"];
            break;
        }
        case EVoiceRecognitionClientWorkStatusUnLoaded: {
            [self printLogTextView:@"CALLBACK: offline engine unLoaded.\n"];
            break;
        }
        case EVoiceRecognitionClientWorkStatusChunkThirdData: {
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK: Chunk 3-party data length: %lu\n", (unsigned long)[(NSData *)aObj length]]];
            break;
        }
        case EVoiceRecognitionClientWorkStatusChunkNlu: {
            NSString *nlu = [[NSString alloc] initWithData:(NSData *)aObj encoding:NSUTF8StringEncoding];
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK: Chunk NLU data: %@\n", nlu]];
            break;
        }
        case EVoiceRecognitionClientWorkStatusChunkEnd: {
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK: Chunk end, sn: %@.\n", aObj]];
            //            if (!self.longSpeechFlag) {
            [self onEnd];
            //            }
            break;
        }
        case EVoiceRecognitionClientWorkStatusFeedback: {
            NSDictionary *logDic = [self parseLogToDic:aObj];
            [self printLogTextView:[NSString stringWithFormat:@"CALLBACK Feedback: %@\n", logDic]];
            break;
        }
        case EVoiceRecognitionClientWorkStatusRecorderEnd: {
            [self printLogTextView:@"CALLBACK: recorder closed.\n"];
            break;
        }
        case EVoiceRecognitionClientWorkStatusLongSpeechEnd: {
            [self printLogTextView:@"CALLBACK: Long Speech end.\n"];
            [self onEnd];
            break;
        }
        default:
            break;
    }
}

- (NSString *)getFilePath:(NSString *)fileName {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    if (paths && [paths count]) {
        return [[paths objectAtIndex:0] stringByAppendingPathComponent:fileName];
    } else {
        return nil;
    }
}
- (NSFileHandle *)createFileHandleWithName:(NSString *)aFileName isAppend:(BOOL)isAppend {
    NSFileHandle *fileHandle = nil;
    NSString *fileName = [self getFilePath:aFileName];
    
    int fd = -1;
    if (fileName) {
        if ([[NSFileManager defaultManager] fileExistsAtPath:fileName]&& !isAppend) {
            [[NSFileManager defaultManager] removeItemAtPath:fileName error:nil];
        }
        
        int flags = O_WRONLY | O_APPEND | O_CREAT;
        fd = open([fileName fileSystemRepresentation], flags, 0644);
    }
    
    if (fd != -1) {
        fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
    }
    
    return fileHandle;
}
- (void)voiceRecogButtonHelper
{
    //    [self configFileHandler];
    [self.asrEventManager setDelegate:self];
    [self.asrEventManager setParameter:nil forKey:BDS_ASR_AUDIO_FILE_PATH];
    [self.asrEventManager setParameter:nil forKey:BDS_ASR_AUDIO_INPUT_STREAM];
    [self.asrEventManager sendCommand:BDS_ASR_CMD_START];
    [self onInitializing];
}
- (void)printLogTextView:(NSString *)logString
{
    NSLog(@"logString = %@",logString);
}
- (NSString *)getDescriptionForDic:(NSDictionary *)dic {
    if (dic) {
        return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:dic
                                                                              options:NSJSONWritingPrettyPrinted
                                                                                error:nil] encoding:NSUTF8StringEncoding];
    }
    return nil;
}
- (NSDictionary *)parseLogToDic:(NSString *)logString
{
    NSArray *tmp = NULL;
    NSMutableDictionary *logDic = [[NSMutableDictionary alloc] initWithCapacity:3];
    NSArray *items = [logString componentsSeparatedByString:@"&"];
    for (NSString *item in items) {
        tmp = [item componentsSeparatedByString:@"="];
        if (tmp.count == 2) {
            [logDic setObject:tmp.lastObject forKey:tmp.firstObject];
        }
    }
    return logDic;
}
- (void)onInitializing
{
    self.voiceRecogButton.enabled = NO;
    [self.voiceRecogButton setTitle:@"Initializing..." forState:UIControlStateNormal];
}

- (void)onStartWorking
{
    //    self.finishButton.enabled = YES;
    //    self.cancelButton.enabled = YES;
    [self.voiceRecogButton setTitle:@"Speaking..." forState:UIControlStateNormal];
}

- (void)onEnd
{
    //    self.longSpeechFlag = NO;
    //    self.finishButton.enabled = NO;
    //    self.cancelButton.enabled = NO;
    self.voiceRecogButton.enabled = YES;
    [self.voiceRecogButton setTitle:@"语音识别" forState:UIControlStateNormal];
}
#pragma mark - UIKeyboard Notification
-(void)KeyboardWillHide:(NSNotification*)notification
{
    self.bottomLayoutConstraint.constant = 0;
    
}
-(void)KeyboardWillShow:(NSNotification*)notification
{
    CGRect rect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    self.bottomLayoutConstraint.constant = rect.size.height;
    [self.view layoutIfNeeded];
//    [inputview resignFirstResponder];
}

#pragma mark - UITextFieldDelegate
- (void)askWord:(NSString *)word {
    __weak typeof(self) weakSelf = self;
    [SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeGradient];
    [SVProgressHUD show];
    [[AIPUnitSDK sharedInstance] askWord:word completion:^(NSError *error, NSDictionary* resultDict) {
        [SVProgressHUD dismiss];
        NSLog(@"%@",resultDict[@"action_list"]);
        for (NSDictionary* dict in resultDict[@"action_list"]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                int i = 0;
                NSMutableArray* action = [[NSMutableArray alloc] init];
                for (; i < [dict[@"hint_list"] count] && i<3; i++) {
                    NSDictionary* item = dict[@"hint_list"][i];
                    [action addObject:item[@"hint_query"]];
                }
//                NSLog(@"%d",page);
                if (page == 0) {
                    [weakSelf.mainArray addObject:@{@"chat":dict[@"say"],@"type":@(0),@"action":action,@"isShowImg":@(0)}];
                    [AIVoiceTable reloadData];
                    [AIVoiceTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.mainArray.count-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
                    inputview.text = @"";
                    
                }else{
                    actionArray = action;
//                    [weakSelf.mainArray addObject:@{@"chat":gpName,@"type":@(0),@"action":action}];
                    [self getyuqingZS];
                }
//                NSLog(@"%lu",(unsigned long)_mainArray.count);
//                [weakSelf.mainTableView reloadData];
                
            });
            if ([dict[@"action_id"] isEqualToString:@"start_work_satisfy"]) {
                NSLog(@"开始扫地");
            } else if ([dict[@"action_id"] isEqualToString:@"stop_work_satisfy"]) {
                NSLog(@"停止工作");
            } else if ([dict[@"action_id"] isEqualToString:@"move_action_satisfy"]) {
                NSLog(@"移动");
            } else if ([dict[@"action_id"] isEqualToString:@"timed_charge_satisfy"]) {
                NSLog(@"定时充电");
            } else if ([dict[@"action_id"] isEqualToString:@"timed_task_satisfy"]) {
                NSLog(@"定时扫地");
            } else if ([dict[@"action_id"] isEqualToString:@"sing_song_satisfy"]) {
                NSLog(@"唱歌");
            }
        }
    }];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    return YES;
}
// 语音调用方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    if (textField.text.length > 0) {
        [speekView removeFromSuperview];
        [_mainArray addObject:@{@"chat":textField.text,@"type":@(1),@"isShowImg":@(0)}];
        [AIVoiceTable reloadData];
        [self askWord:textField.text];
//        [self getyuqingZS];
        gpName = textField.text;
        //        [yqDataArray addObject:textField.text];
        page ++;
        [inputview resignFirstResponder];
    }
    return YES;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textFiel{
    return YES;
}

上边的代码是集成了百度语音SDK的代理方法 以及UNIT交互的一些方法

以上就是集成百度语音SDK以及UNIT交互的具体过程 关于UNIT交互页面局部使用XIB写的 这块儿就不在记录 直接按照演示demo完成就可以

你可能感兴趣的:(关于百度UNIT交互语音的集成详解)