开放能力
开发平台
行业应用
生态合作
开发与教学
资讯 社区 控制台
技术能力
语音技术
文字识别
人脸与人体
图像技术
语言与知识
视频技术
AR与VR
数据智能
场景方案
部署方案
行业应用
智能教育
智能医疗
智能零售
智能工业
企业服务
智能政务
信息服务
智能园区

虚拟形象iOS开发文档

虚拟形象iOS开发文档

简介

百度虚拟形象sdk是基于图像识别、语音识别与合成、人像建模等人工智能技术,以电子屏、VR等设备为载体,实现人机交互的虚拟人,面向餐饮、金融、广电、教育、营销等行业,提供全新智能对客服务,降低人力成本,提升服务质量和效率。同时基于百度AR技术,塑造卡通形象,打造更有亲和力的虚拟形象。

开发指南

概述

DigitalHuman SDK 以DigitalHuman API的形式提供给开发者,包含JAVA,objc两种语言形式。

功能

DigitalHuman SDK 实现功能包括:

  • 播报

    输入文本进行语音播报

  • 对话

    输入文本或录音进行对话聊天

  • 模型渲染

    初始化完成即可将虚拟形象渲染在页面上

  • 切换配饰

    切换虚拟形象的配饰,包括但不限于服装和发型

  • 动作和表情触发

    输入不同参数来触发不同的动作和表情

  • 视角变换

    切换虚拟形象全身和半身

开发环境

Xcode: 建议12.0及以上

需要用到的权限:Microphone麦克风使用权限、网络

SDK与demo文件

鉴权

使用sdk需要用到dumixar.license文件进行授权,license文件对bundleID和过期时间有鉴权限制。需要加载license文件,DigitalHuman才能正常启动。原始SDK中不包含license。

快速入门

需要集成 libc++.tbd苹果官方的c++库

初始化

初始化并且启动SDK

//samples.m
@property (nonatomic, strong) BARDigitalHuman *digitHuman;

// 代码
NSString *url = @""; // 语音播报和asr服务用到的websocket连接
NSString *casePath = @""; // AR Case的本地文件地址
<id>BARDigitHumanLogViewProtocol logView; // 实现BARDigitHumanLogViewProtocol协议的一个class,用来输出sdk内部的log和cpu、内存、网络的的使用情况。
self.digitHuman = [[BARDigitalHuman alloc] initWithUrl:url frame:self.view.frame arCasePath:casePath logView:logView];

// 将输出的view添加到app的view层级中
[self.view addSubview:self.digitHuman.arView];

鉴权和启动

    // license 文件
		NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"dumixar" ofType:@"license"]];

    __weak typeof(self) weakSelf = self;
    [self.digitHuman setLicenseData:data localAuthResult:^(BOOL result) {
        if () {
          // 启动sdk
        	[weakSelf.digitHuman start];
        } else {
          NSLog(@"鉴权失败"); 
        }
    }];

播报模式

数字人播报输入的文本。

NSString *text = @"你好";
[weakSelf.digitHuman sendReadingMessage:text]; 

对话模式

  • 输入对话语音,数字人对于语音进行回答。
		[weakSelf.digitHuman chatStartRecord]; // 启动录音, 启动后sdk会捕获外部环境的声音,直到判断一句话已经结束,会在回调方法里面标识出来。
		
		// 设置录音的回调方法。此方法会返回识别的录音的文本信息,如果判断此段文本语义上已经结束了,会返回第二个参数的completed变量为真值。
    [self.digitHuman setChatGetSubTitleBlock:^(NSString *subTitle, BOOL completed) {
        
        if (completed) {
            // 结束录音
            [weakSelf.digitHuman chatStopRecord];
            // 将识别到的文本发送到服务端,会返回数字人的语音对话,然后SDK播放这段对话

            [weakSelf.digitHuman sendChatMessage:subTitle];
            
        }
    }];
  • 输入对话文本,数字人对于文本进行回答。
NSString *text = @"你好";
[weakSelf.digitHuman chatSendMessage:text]; 

设置对话的UNIT信息

每次发送对话消息,都需要附带unitDict信息

NSDictionary *unitDict = @{
            @"access_token": @"24.65247541da47f53752156c27686d8ea3.2592000.1614147995.282335-23178123",
            @"log_id": @"UNITTEST_10000",
            @"version": @"2.0",
            @"service_id": @"S42464",
            @"session_id": sessionId, // sessionId为setChatGetSessionIdBlock接口返回的sessionId
            @"user_id": @"88888",
            @"skill_ids": @"1067861" // 1067861:问候技能  1067825:闲聊技能
        };
[weakSelf.digitHuman chatSendMessage:text unitDict:unitDict];

获取对话的UNIT sessionId

    [self.digitHuman setChatGetSessionIdBlock:^(NSString *sessionId) {
        weakSelf.barContext.chatSessionId = sessionId;
    }];

监听回调

设置sdk的播报、对话请求的状态变化的回调。包括,开始请求、播放中、播放完成、播放失败。

请参考下面API列表的『数字人请求的状态』

    [self.digitHuman setChangeRequestStatusBlock:^(BARDigitalHumanStatus status) {
        NSLog(@"inapp status:%ld", status);
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (status == BARDigitalHumanStatusStart) {
            	// 开始请求
            
            } else if (status == BARDigitalHumanStatusEnd) {
            	// 播放完成
            } else if (status == BARDigitalHumanStatusFailed) {
							// 请求失败
						} else {
							// 播放中
            }
        });

    }];

切换配饰

以切换发型为例,详细功能请参考Api说明。

// 修改为短发发型
NSMutableDictionary *msg = [[NSMutableDictionary alloc] init];
[msg setObject:@"change_hair_operation" forKey:@"event_name"];
[msg setObject:@{@"node": @"avatar", @"hair": @"short"} forKey:@"event_data"];
[weakSelf.digitHuman changeRenderParameter:msg];

数字人播报的文本回调

    [self.digitHuman setOutputSubtitleBlock:^(NSString *subtitle, NSInteger duration) {
        // 展示字幕
        
    }];

API列表

initWithUrl:frame:arCasePath:logView

- (instancetype _Nonnull )initWithUrl:(NSString *_Nonnull)url frame:(CGRect)frame arCasePath:(NSString *_Nullable)arCasePath logView:(id<BARDigitHumanLogViewProtocol>_Nullable)logView;

初始化SDK系统环境。初始化成功后,会给arView属性赋值,将这个view放到app的view层级中,用来展示数字人。

参数:

  1. url : 语音播报和asr服务用到的websocket连接地址
  2. frame : 输出view的frame
  3. arCasePath : ar case的本地地址
  4. logView - id: sdk内记录log的一个protocol对象

返回:

BARDigitHuman对象

  (NSArray *)setLicenseData:(NSData *)licenseData localAuthResult:(void (^)(BOOL result))authResult;

参数

  1. licenseData : license文件的NSData格式数据
  2. 鉴权的回调,authResult为YES代表鉴权成功,为NO代表鉴权失败

start

开启数字人,在鉴权回调成功后调用

- (void)start;

参数:

​ 无

返回值:

​ void

stop

关闭数字人,情况sdk里面的资源

- (void)stop;

参数:

​ 无

返回值:

​ 无

sendReadingMessage:

发送播报文本

sdk会按照文本内容播报

- (void)sendReadingMessage:(NSString *)text;

参数:

  1. text :要播报的文本

返回值:

​ void

interruptReading

中止、打断

- (void)interruptReading;

会停止播放语音

changeRenderParameter:

修改发型、服饰

发送消息,可以修改数字人的发型和服饰

- (void)changeRenderParameter:(NSDictionary *)message;

参数:

  1. msg - NSDictionary :消息字典

消息列表:

含义 event_name event_data 备注
换装(裙装/西装) change_outfit_operation node avatar 节点:预留字段
outfit dress/suit 服装:裙装/西装
换发型(短发/马尾辫) change_hair_operation node avatar 节点:预留字段
hair short/ponytail 发型:短发/马尾
动作触发 animation_operation node avatar 节点:预留字段
repeat_count n(整数) 动画循环次数:0代表无穷
chip idle(聆听态)/right_hand(右伸手)/front_hand(前伸手)/wave(招手)/emphasize(强调) 动画短名称:聆听态/右伸手/前伸手/招手/强调
operation play/stop 操作:播放/停止
相机位置切换 camera_position_operation position ArrayList<Float> 数组,数组长度为3 全身相机姿态参数:0,8,47半身相机姿态参数:0,10.5,25调用例子中见调用示例,三个Float代表相机位置的三维坐标,其中第二个(y坐标)控制相机高低,第三个(z坐标)控制远近,如果效果不佳,可以根据这个参数意义微调。
胸章Logo切换 change_logo_operation node avatar
logo none/baidu/baidu_paw/net/net_icon 对应胸牌:无胸牌、百度胸牌、百度熊掌、智能云胸牌、智能云图标调用例子中见调用示例

返回值:

void

gestureTouchesBegan:touches:scale:

手势开始

- (void)gestureTouchesBegan:(nonnull NSSet<UITouch *> *)touches scale:(CGFloat)scale

参数:

  1. Touches - NSSet<UITouch *> : 手势的信息
  2. scale - CGFloat : 放大系数

返回值:

void

chatStartRecord

对话模式,开始录音

会打开microphone,进行录音

- (void)chatStartRecord;

参数:

​ void

返回值:

​ void

chatStopRecord

对话模式,结束录音

会关闭microphone

- (void)chatStopRecord;

参数:

​ void

返回值:

​ void

chatSendMessage:

对话模式,输入文本

输入对话文本到服务端

- (void)chatSendMessage:(NSString *)text;

参数:

  1. text : 对话文本

返回值:

​ void

chatSendMessage:unitDict:

对话模式,输入文本和UNIT服务需要的参数

输入对话文本到服务端

- (void)chatSendMessage:(NSString *)text unitDict:(NSDictionary *)unitDict;

参数:

  1. text : 对话文本
  2. unitDict : UNIT服务需要的参数

    • access_token
    • log_id
    • version
    • service_id
    • session_id : chatGetSessionIdBlock接口返回sessionId,放到这里
    • user_id
    • skill_ids : // 1067861:问候技能 1067825:闲聊技能

返回值:

​ void

属性 Property

arView

输出的数字人view

获取view 可以通过arView,然后将这个view放到app的view层级中

@property (nonatomic, strong, readonly) UIView * _Nullable arView;
changeRequestStatusBlock

数字人请求的状态

typedef void (^BARDigitHumanChangeRequestStatusBlock)(BARDigitalHumanStatus status);
// 状态改变回调block 
@property (nonatomic, copy) BARDigitHumanChangeRequestStatusBlock _Nullable changeRequestStatusBlock;
ARPSampleDemoRequestStatusStart = 1, // 开始请求

ARPSampleDemoRequestStatusRun = 2, // 收到数据,播放中

ARPSampleDemoRequestStatusEnd = 3, // 播放完成

ARPSampleDemoRequestStatusFailed = 4 // 请求失败
engineCaseLoadFinishBlock

AR引擎加载完成的回调

// case加载完成回调block
@property (nonatomic, copy) void(^ _Nullable engineCaseLoadFinishBlock)(void);
outputSubtitleBlock

输出字幕信息

这是语音播报或者对话模式下的字幕信息

@property (nonatomic, copy) void(^ _Nullable outputSubtitleBlock)(NSString * _Nonnull subtitle, NSInteger duration);
chatGetSubTitleBlock

对话模式 - 获取录音文本

回调函数的第一个字段subTitle是语音识别的文本,第二个字段completed代表文本语义上是否结束。如果为YES,应该执行chatStopRecord接口

@property (nonatomic, copy) void(^ _Nullable chatGetSubTitleBlock)(NSString *subTitle, BOOL completed);
chatGetSessionIdBlock

获取对话模式返回的sessionId,每次对话交互都会回调这个接口。得到的sessionId,在传到chatSendMessage:unitDict:的第二个参数里面,这样可以保持有session的对话

@property (nonatomic, copy) void(^ _Nullable chatGetSessionIdBlock)(NSString *sessionId);