1. 软件和硬件要求
系统 | 支持 Android6 以上系统 |
处理器架构 | 支持 arm64-v8a CPU 架构 |
处理器性能要求 | 支持高通骁龙8+ , 海思麒麟 980+ ,联发科mt6878+ 等 |
开发 IDE | Android Studio |
内存要求 | 大于 500M |
2. 模型包说明
模型包分为基础模型包和人物形象包两种,具体介绍如下:
基础模型包
基础模型包与形象无关, 是运行 2D 端渲染的必备条件,模型包目录名称为:
common_model/ 如果有多个人物模型,可以共用一个基础模型包。人物形象包
人物形象包里包含了 2D 数智人驱动的图像数据和推理模型。每个人物形象一个模型包, 加载不同的人物模型包,即可更换形象。模型包目录名称为:
human_xxxxx_540p_v2/,其中 xxxxx 为定制形象的名称。 目前 SDK 包里含一个公共形象,包名是:human_bingwen_540p_v3,您可直接使用。
注意:
SDK 接入方需要将模型包放到 App 的沙盒中,初始化 SDK 时需要将2个模型的绝对路径作为参数传递给 SDK。
模型包可以动态下载,动态下载和更新的逻辑,需要接入方 App 自行实现。
3. 数智人客户端渲染 SDK 接入
数智人 SDK 的调用流程如下:

3.1 引入 aar 包和第三方库
将数智人端渲染 SDK 的 aar 包引导到项目中, aar 包文件命名为:
virtualhuman_2d_sdk_v202502071637.aar由于使用了 OkHttp 库,所以需要在项目的 build.gradle(Module:app)文件中添加 OkHttp 的依赖。
dependencies{implementation fileTree(dir: 'libs', include: ['*.aar'])// 添加依赖implementation'com.squareup.okhttp3:okhttp:4.9.0'implementation 'com.parse.bolts:bolts-tasks:1.4.0'}
3.2 设置日志级别和回调函数
// 设置日志级别VirtualHumanController.setLogLevel(Int level);// 设置日志回调VirtualHumanController.setLogCallback(IDataCallback logCallback);
日志等级
日志等级 | 等级标识(level) |
关闭日志 | 0 |
错误日志 | 1 |
警告日志 | 2 |
信息日志 | 3 |
调试日志 | 4 |
追踪日志 | 5 |
IDataCallback 回调参数
参数名称 | 数据类型 | 参数类型 | 说明 |
level | int | 必要 | 日志等级 |
logMsg | String | 必要 | 日志信息 |
3.3 创建数智人控制器 (VirtualHumanController)
VirtualHumanParam vhParam = new VirtualHumanParam();// 本地模型路径vhParam.humanModelPath = "/data/user/0/com.tencent.virtualhuman_2d_demo/files/test_model/human_model";// 本地模型路径vhParam.commonModelPath = "/data/user/0/com.tencent.virtualhuman_2d_demo/files/test_model/common_model";vhParam.appId = "License的appId";vhParam.secretKey = "License的secretKey";vhParam.deviceName = "设备标记,建议用铭牌信息";// 错误回调函数vhParam.errorCallback = (code, message) -> {Log.d(TAG, "Code: " + code + ", Message: " + message);};// 事件回调函数vhParam.eventCallback = (code, message) -> {Log.d(TAG, "Code: " + code + ", Message: " + message);};controller = new VirtualHumanController(this, vhParam);int ret = controller.initHuman();if (ret == 0) {controller.setRenderView(virtualHumanView);// 设置渲染视图controller.startHuman();// 开始渲染} else {Log.i(TAG, "init fail=" + ret);}
VirtualHumanParam 参数说明
参数名称 | 数据类型 | 必选 | 说明 |
humanModelPath | String | 是 | 本地模型路径。 |
commonModelPath | String | 是 | 本地通用模型路径。 |
appId | String | 是 | License 里的 AppId。 |
secretKey | String | 是 | License 里的 SecretKey。 |
eventCallback | IDataCallback | 否 | 事件回调函数,事件通知。 |
eventCallback | IDataCallback | 是 | 异常回调函数,监控异常信息。 |
deviceName | String | 否 | 设备别名,建议用铭牌信息 |
IDataCallback
参数名称 | 数据类型 | 必选 | 说明 |
code | int | 是 | code |
message | String | 是 | 信息 |
错误列表 (会持续补充)
code | message |
20001 | 初始化算法模型错误。 |
20010 | 鉴权失败。 |
20012 | 设备性能不足,不能流畅运行。 |
信息列表
code | message |
10001 | 整段播报开始。 |
10002 | 整段播报结束。 |
10003 | controller.appendAudioData('音频数据',boolean,‘标记’)。 当调用 appendAudioData 传入标记参数时。10003代表播放该段音频数据时的开始事件,并将标记在回调事件中返回。 |
10004 | controller.appendAudioData('音频数据',boolean,‘标记’)。 当调用 appendAudioData 传入标记参数时。10003代表播放该段音频数据时的结束事件,并将标记在回调事件中返回。 |
10005 | 数智人首帧图像渲染的回调事件。 |
3.4 创建数智人视图 (VirtualHumanView)
VirtualHumanView 是数智人渲染的基础 View,接入方可以在 Activity 或者任意 View 中使用 VirtualHumanView 来显示数智人。有两种配置方式:
可以直接在 XML 里配置:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/ll_floating_ball"android:layout_width="180dp"android:layout_height="320dp"android:background="#8f15ab71"android:gravity="center"android:orientation="horizontal"><com.tencent.virtualhuman_2d_sdk.VirtualHumanViewandroid:id="@+id/virtual_human_view"app:TVHFillMode="fill" // 渲染 View 的填充模式android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout></LinearLayout>
也可以动态增加:
<?xml version="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/ll_container"android:layout_width="480dp"android:layout_height="480dp"android:background="#8f15ab71"android:gravity="center"android:orientation="horizontal"></LinearLayout></LinearLayout>
代码示例
// context是当前Activity界面的上下文VirtualHumanView virtualHumanView = new VirtualHumanView(context);virtualHumanView.setFillMode(VirtualHumanViewType.fill);LinearLayout ll_container = findViewById(R.id.ll_container);ll_container.addView(virtualHumanView);
可以设置渲染 View 的填充模式:
VirtualHumanViewType.stretch | 拉伸图像 |
VirtualHumanViewType.fit | 裁切图像 |
VirtualHumanViewType.fill | 保留黑边(透明边) |
给控制器设置渲染 View
参数说明
参数名称 | 数据类型 | 参数类型 | 说明 |
virtualHumanView | VirtualHumanView | 必要 |
controller.setRenderView(virtualHumanView);
3.5 流式输入音频驱动数智人
输入的音频格式为 s16le(signed 16 bits little endian,有符号16位小端)PCM, 采样率 16000, 单声道。
参数名称 | 数据类型 | 参数类型 | 说明 |
decodedBytes | Byte[] | 是 | PCM 的音频数据。 |
isFinal | Boolean | 是 | 是否是音频尾帧。 |
metaData | String | 否 | 传入对应音频数据的标记,当播报该音频分片时会有对应事件10003/10004。 |
代码示例
controller.appendAudioData(decodedBytes, isFinal);controller.appendAudioData(decodedBytes, isFinal, metaData);
3.6 打断
代码示例
controller.interrupt();
3.7 暂停
代码示例
controller.pause();
3.8 恢复
代码示例
controller.resume();
4. Demo App 运行说明
随 SDK 附带了一个能完整运行的 Demo App。 项目工程结构如下:

4.1 修改 local.properties 文件
local.properties 文件包含了所有用到的 AppKey 等密钥, 请修改为客户申请的。

4.2 运行 Demo
单击运行按钮, 即可运行 2D 端渲染 Demo 应用。
4.3 针对早期设备的降级方案
端渲染数智人 SDK 是使用客户端的计算能力,完成 AI 算法推理和图像合成,对移动设备的性能有一定的要求。
1. 我们提供一份安卓机型兼容性的 黑白名单,接入方可以根据 Build.MODEL 获取到的值和黑白名单进行对比,确认该机型的性能是否满足数智人的渲染要求,黑白名单会随着市场上新机型的产生不断迭代更新。
2. 我们还提供了一种运行时判定安卓机型的性能是否满足数智人渲染要求的方式。
代码示例
1、参考上文创建数智人控制器controller = new VirtualHumanController(DemoActivity.this, vhParam);int ret = controller.initHuman();// 初始化数智人if (ret == 0) {2、 不调用setRenderView,直接开始渲染controller.startHuman();} else {Log.i(TAG, "init fail=" + ret);}3、监听错误回调errorCallback的返回值,假如在一段时间内出现了20012这个错误码,说明该设备性能不足,不能流畅运行
5. 从旧版本升级
5.1 如何把 1.1.x 版本升级到 1.3.x 版本
1. 第三方库的依赖新增:
implementation 'com.parse.bolts:bolts-tasks:1.4.0'2.
vhParam.bindDevice 参数移除。3. 原来的
controller.setRenderView(virtualHumanView); 改成如下写法:int ret = controller.initHuman();if (ret == 0) {controller.setRenderView(virtualHumanView);controller.startHuman();} else {Log.i(TAG, "init fail=" + ret);}