本文介绍了数字人端渲染Android SDK的接入方式。端渲染SDK无需借助音视频流媒体服务,直接利用终端设备对3D数字人进行渲染,免去了音视频的推拉流,降低了交互延迟。目前端渲染SDK仅支持3D数字人,暂不支持2D数字人。
文档版本 | 适用的SDK版本 |
1.0.2 | 1.0.2 |
一、系统要求
系统版本:支持Android 8.0及以上版本。
CPU类型:支持armeabi-v7a、arm64-v8a。
设备类型:仅限大屏设备,无法在手机端集成。
支持的数字人:仅支持3D数字人,暂不支持2D数字人。
硬件要求:需要高通845/RK3588同级别及以上的硬件水平。
二、集成步骤
在项目中使用时,您需要把AvatarClientRenderSDK.aar放入app模块下的libs文件夹中,并在build.gradle文件中添加导入。
implementation fileTree(include: ['*.aar'], dir: 'libs')
AvatarClientRenderSDK强依赖于lifecycle-common、okhttp、fastjson、tea-openapi四个库,您需要手动将相关依赖导入。
implementation 'androidx.lifecycle:lifecycle-common:2.4.0'
implementation 'com.alibaba:fastjson:1.2.83'
implementation 'com.squareup.okhttp3:okhttp:4.4.1'
implementation 'com.aliyun:tea-openapi:0.3.0'
此外,若需要打开远程日志及崩溃监测功能,还需要手动导入以下依赖。注意:开启远程日志功能会需要采集设备日志等信息,所有采集动作均使用阿里云移动研发平台Emas完成,所涉及到的用户信息采集可以参考Emas隐私权政策。
implementation('com.aliyun.ams:alicloud-android-ha-adapter:1.1.5.2-open@aar') {
transitive = true
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.okio'
}
implementation('com.aliyun.ams:alicloud-android-tlog:1.1.4.4-open@aar') {
transitive = true
exclude group: 'com.squareup.okhttp3'
exclude group: 'com.squareup.okio'
}
implementation('com.aliyun.ams:alicloud-android-ha-crashreporter:1.2.5')
在app/src/main/AndroidManifest.xml文件中添加如下代码,获取相应的设备权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
在代码中将license文件拷贝到本地应用目录中,鉴权模块将读取应用目录中的文件信息进行鉴权。可以参考Demo工程中,MainActivitiy的 copyLicenseFile方法实现。
三、接口说明
3.1 接口清单
接口类别 | 接口名称 | 说明 |
主流程接口 | initSDK | 鉴权、初始化 |
queryAvatarList | 获取当前租户下所有3D数字人资产的列表 | |
renderAvatar | 加载指定数字人 | |
sendMessage | 播报文本 | |
interruptPlay | 打断播报 | |
destroy | 销毁Unity 断开WebSocket | |
配置接口 | setVolume | 设置音量 |
setAvatarRotationY | 指定数字人水平角度 | |
setCameraType | 机位设置 | |
setBackground | 设置背景 | |
getAvatarConfig | 获取当前配置 | |
功能接口 | isPlaying | 检查当前播报状态 |
downloadAvatar | 下载指定数字人 | |
clearCache | 清除所有本地资源缓存 | |
getDeviceInfo | 获取设备信息,包括设备ID等 | |
回调接口 | onInitResult (int code, String message) | 初始化结果 |
onQueryAvatarListResult (String result) | 角色列表 | |
onRenderAvatarStart (String config) | 开始加载数字人 | |
onRenderAvatarSuccess (String avatarCode) | 数字人加载成功 | |
onRenderAvatarFailure (String avatarCode, int errorCode, String message) | 数字人加载失败 | |
onAssetDownloadProgress (String avatarCode, int currentFileNum, int totalFileNum) | 角色素材下载进度 | |
onAssetDownloadSuccess (String avatarCode) | 角色素材下载成功 | |
onAssetDownloadFailure (String avatarCode) | 角色素材下载失败 | |
onPlayStart(String uniqueCode) | 数字人驱动开始 | |
onPlayEnd(String uniqueCode) | 数字人驱动结束 | |
onGetAvatarConfig (String configJson) | 数字人配置信息 | |
onError (int errorCode, String errorMsg) | 各种异常 |
3.2 主流程接口
1. initSDK
初始化SDK,进行鉴权和初始化配置等
调用方式
avatarSDK = AvatarSDK.getInstance(context, avatarSDKListener);
// 1. 使用STS鉴权,推荐该方案
avatarSDK.initSDK(container, accessKeyId, accessKeySecret, securityToken, lifecycle, initConfig);
// 2. 直接使用账号的AKSK鉴权,需要客户端拿到AK&SK,可能存在安全风险,不推荐
//avatarSDK.initSDK(container, accessKeyId, accessKeySecret, lifecycle, initConfig);
参数说明
参数 | 类型 | 必填 | 描述 | 默认值 |
container | ViewGroup | 是 | 承载数字人角色的布局容器,可以为LinearLayout等 | |
accessKeyId | String | 是 | 阿里云用户标识,即通过STS的AssumeRole接口返回的 AccessKeyId 字段。 STS鉴权使用参考:使用STS临时访问凭证调用虚拟数字人服务。 | |
accessKeySecret | String | 是 | 阿里云用户密钥,即通过STS的AssumeRole接口返回的 AccessKeySecret 字段。 STS鉴权使用参考:使用STS临时访问凭证调用虚拟数字人服务。 | |
securityToken | String | 否 | 临时安全token,即通过STS的AssumeRole接口返回的 SecurityToken 字段。有效期等同于AssumeRole接口调用时DurationSecondsToken值,单位为毫秒。 STS鉴权使用参考:使用STS临时访问凭证调用虚拟数字人服务。 | 3600 |
lifecycle | androidx.lifecycle.Lifecycle | 是 | 绑定Activity生命周期,需要Activity继承自AppCompatActivity | |
initConfig | InitConfig | 否 | 对数字人位置、角度、环境背景、播报音量、日志做初始化配置 | true |
InitConfig说明
参数 | 类型 | 说明 | 默认值 |
volume | int | 数字人播报音量,取值范围[0,100] | 100 |
rotationY | int | 数字人水平角度,取值范围[-90, 90] | 0 |
cameraType | enum | 机位设置,包含以下枚举值: CAMERA_POS_DEFAULT : 相机默认位置 CAMERA_POS_HEAD : 相机在角色头部位置 CAMERA_POS_BODY : 相机在角色身体位置 CAMERA_POS_HALFBODY : 相机半身机位 CAMERA_POS_BOTTOM : 角色下部站位 CAMERA_POS_LEFT : 角色左侧站位 CAMERA_POS_RIGHT : 角色右侧站位 CAMERA_POS_HEAD_FOREHEAD : 相机在角色头部位置,额头 CAMERA_POS_HEAD_EYE : 相机在角色头部位置,眼睛 CAMERA_POS_HEAD_NOSE: 相机在角色头部位置,鼻子 CAMERA_POS_HEAD_MOUTH : 相机在角色头部位置,嘴巴 | CAMERA_POS_DEFAULT |
backgroundURL | String | 初始化的背景图片地址,接收url | 无 |
enableCrashReporter | boolean | 是否打开远程日志与崩溃监测 | true |
2. queryAvatarList
获取当前实例下的可用数字人角色列表。列表结果在onQueryAvatarListResult回调中返回。
调用方式
avatarSDK.queryAvatarList(1, 20);
参数说明
参数 | 类型 | 必填 | 描述 |
pageSize | int | 是 | 分页查询索引 |
pageNo | int | 是 | 分页查询结果数量 |
3. renderAvatar
根据avatarCode加载指定的数字人角色,若本地无角色相关素材,SDK会自动下载素材至本地。加载相关回调见onRenderAvatarStart、onRenderAvatarSuccess、onRenderAvatarFailure三个回调接口,下载相关回调见onAssetDownloadProgress、onAssetDownloadSuccess、onAssetDownloadFailure三个回调接口。
调用方式
avatarSDK.renderAvatar(code);
参数说明
参数 | 类型 | 必填 | 描述 |
code | String | 是 | 待加载的数字人唯一ID,由 queryAvatarList 接口中获取到的数据解析而得。数据格式见onQueryAvatarListResult接口回调说明。 |
4. sendMessage
播报一段文本,数字人会基于文本做TTS生成和表情动作驱动。
调用方式
avatarSDK.sendMessage(msg, uniqueCode);
参数说明
参数 | 类型 | 必填 | 描述 |
msg | String | 是 | 供数字人播报的文本,将依据此文本驱动数字人角色 |
uniqueCode | String | 是 | 数字人单句文本的唯一ID,将会在onPlayStart 和 onPlayEnd 中回调 |
5. interruptPlay
打断当前播报并清空所有未播报、待播报数据,立即恢复到空闲状态。
avatarSDK.interruptPlay();
6. destroy
释放资源,断开Websocket链接,销毁Unity进程,请勿在主应用进程中调用,将会导致应用直接退出。
调用方式
avatarSDK.destroy();
3.3 配置接口
注:所有配置均建议在initSDK接口中的initConfig 字段中做初始化配置。
1. setVolume
调节播报音量
调用方式
avatarSDK.setVolume(value);
参数说明
参数 | 类型 | 必填 | 描述 | 默认值 |
value | int | 是 | 数字人播报音量,非系统音量,取值范围[0, 100] | 100 |
2. setAvatarRotationY
指定数字人水平角度
调用方式
int rotation = 60;
avatarSDK.setAvatarRotationY(rotation);
参数说明
参数 | 类型 | 必填 | 描述 | 默认值 |
rotation | int | 是 | 数字人水平角度 [-90, 90] | 0 |
3. setCameraType
指定camera机位,包括全身、半身、特写等,枚举值见initSDK接口中的说明。
avatarSDK.setCameraType(CameraType.Default);
参数说明
参数 | 类型 | 必填 | 描述 | 默认值 |
cameraType | enum | 是 | 机位设置 | CAMERA_POS_DEFAULT |
4. setBackground
设置场景背景
调用方式
String path = "http://aaa.bbb/ccc.png"
avatarSDK.setBackground(imagePath);
参数说明
参数 | 类型 | 必填 | 描述 |
imagePath | String | 是 | 背景图片的url地址 |
4
5. getAvatarConfig
获取上述所有配置的值,在回调接口的onGetAvatarConfig方法中返回。
调用方式
avatarSDK.getAvatarConfig()
返回示例
{
"backgroundURL": "",
"cameraType": "CAMERA_POS_BODY",
"rotationY": 0,
"useCrashReporter": true,
"volume": 100
}
3.4 功能接口
1. isPlaying
查询当前播报状态
boolean isPlaying = avatarSDK.isPlaying();
2. clearCache
清除所有已下载到本地的文件,包括3D模型及背景图片等。
avatarSDK.clearCache();
3. downloadAvatar
下载指定数字人的资源到本地存储中,在下载回调接口中返回下载状态。
avatarSDK.downloadAvatar(code);
参数说明
参数 | 类型 | 必填 | 描述 |
code | String | 是 | 待加载的数字人唯一ID,由 queryAvatarList 接口中获取到的数据解析而得。数据格式见onQueryAvatarListResult接口回调说明。 |
4. getDeviceInfo
获取设备信息,包含当前设备的设备ID、设备类型
String deviceInfo = avatarSDK.getDeviceInfo();
3.5 回调接口
回调listener在生成SDK实例时传入
avatarSDK = AvatarSDK.getInstance(MainActivity.this, avatarSDKListener);
1. onInitResult (int code, String message)
在调用initSDK之后会触发的回调,返回SDK初始化结果,code为0时即为初始化成功。
2. onQueryAvatarListResult (String result)
在调用quaryAvatarList之后会触发的回调,返回可用的数字人角色列表。
返回数据示例:
{
"list": [
{
"code": "CH_sBXSW4166SgVnECq",
"name": "Jack",
"portrait": "https://nuwa-live-image.oss-cn-beijing.aliyuncs.com/yun-vh/unity/MO_zTRB2XUWJu/20230816164605.411.png"
}
],
"pageNo": 1,
"pageSize": 50,
"totalCount": 9,
"totalPage": 1
}
3. onRenderAvatarStart (String avatarCode)
开始渲染指定的数字人角色。
4. onRenderAvatarSuccess (String avatarCode)
数字人角色渲染成功。
5. onRenderAvatarFailure (String avatarCode, int errorCode, String message)
数字人角色渲染失败。
6. onAssetDownloadProgress (String avatarCode, int currentFileNum, int totalFileNum)
数字人资产下载进度。
参数说明:
参数名 | 说明 |
avatarCode | 角色唯一code |
currentFileNum | 已下载的素材文件数量 |
totalFileNum | 总共需要下载的素材文件数量 |
7. onAssetDownloadSuccess (String avatarCode)
数字人资产下载成功。
8. onAssetDownloadFailure (String avatarCode, int errorCode, String errorMsg)
数字人资产下载失败。
9. onPlayStart(String uniqueCode)
播报开始。
10. onPlayEnd(String uniqueCode)
播报结束。
11. onGetAvatarConfig (String configJson)
当前的数字人及场景配置,在调用getAvatarConfig接口之后触发。
返回数据示例:
{
"backgroundURL": "",
"cameraType": "CAMERA_POS_BODY",
"rotationY": 0,
"useCrashReporter": true,
"volume": 100
}
12. onError (int errorCode, String errorMsg)
异常回调,参考错误码说明。
四、错误码说明
错误码 | 错误信息 | 描述 |
16001000 | 鉴权失败 | 鉴权失败,检查license、SecurityToken、AccessKeyId和AccessKeyToken是否正确 |
16001001 | 接口参数错误 | 请检查接口入参 |
16001002 | 接口异常 | 业务接口返回异常,请查看详细的errorMessage |
16001003 | 服务启动异常 | 服务启动异常,请查看具体的errorMessage |
16001010 | 接口异常 | OpenApi的接口返回异常,请查看详细的errorMessage |
16021000 | 重复初始化 | 多次调用了初始化接口 |
16021001 | 初始化参数异常 | 请检查AccessKeyId、AccessKeyToken等鉴权信息是否正确填入 |
16021002 | 初始化异常 | 长链接未初始化完成,请等待,或查看是否有其他异常日志 |
16021003 | 初始化异常 | 渲染容器未初始化完成,请等待 |
16031000 | 数字人下载失败 | 资源下载失败,需要检查控制台是否已正确配置 |
16031001 | 数字人渲染失败 | 资源文件发生了损坏,需要重新下载对应的资源 |
五、常见问题
Q:调用鉴权接口打印错误信息: errorMsg : code: 503, The request has failed due to a temporary failure of the server. request id:
A:RAM用户没有访问数字人开放平台权限,需要赋予相应权限,参考《使用STS临时访问凭证调用虚拟数字人服务》
Q:sdk 集成必须打开android.useAndroidX=true么?
A:是的,如果有使用了support-v4、support-v7等依赖,需要在gradle.properties文件中添加android.enableJetifier=true
Q:在初始化时有报错,sdk返回 16001000鉴权失败
A:license文件没有被正确的复制,请参考Demo工程中的 copyLicenseFile方法实现。