移动端 Android SDK 接入

最近更新时间:2026-04-02 14:45:51

我的收藏

1. 软件和硬件要求

系统
支持 Android 6 以上系统
处理器架构
支持 arm64-v8a CPU 架构
处理器性能要求
支持高通骁龙8+、海思麒麟 980+、联发科 mt6878+ 等
开发 IDE
Android Studio
内存要求
大于 500MB

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-release-202603061641_1.6.3_app.aar
由于使用了 OkHttp 库,所以需要在项目的 build.gradle(Module:app)文件中添加 OkHttp 的依赖。
dependencies {
implementation fileTree(dir: 'libs', include: ['*.aar'])
// 添加依赖
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.parse.bolts:bolts-tasks:1.4.0'
}

3.2 配置权限

在 AndroidManifest.xml 中添加:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
// 设备绑定时需要添加此权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

3.3 基础使用示例

// 1. 创建参数
VirtualHumanParam param = new VirtualHumanParam();
param.appId = "your_app_id";
param.secretKey = "your_secret_key";
param.commonModelPath = "/path/to/common_model";
param.humanModelPath = "/path/to/human_model";

// 2. 设置回调
param.eventCallback = (code, message) -> {
Log.i("VH", "Event: " + code + ", " + message);
};
param.errorCallback = (code, message) -> {
Log.e("VH", "Error: " + code + ", " + message);
};

// 3. 创建控制器
VirtualHumanController controller = new VirtualHumanController(context, param);

// 4. 初始化
int result = controller.initHuman();
if (result != 0) {
Log.e("VH", "Init failed: " + result);
return;
}

// 5. 设置渲染视图
VirtualHumanSurfaceView view = new VirtualHumanSurfaceView(context);
controller.setRenderView(view);

// 6. 启动渲染
controller.startHuman();

// 7. 推送音频数据
byte[] audioData = ...; // PCM 16bit 16kHz
controller.appendAudioData(audioData, false);

// 8. 停止并释放
controller.stop();

4. 核心类

VirtualHumanController

数智人渲染控制器,管理 Native 渲染引擎。
public VirtualHumanController(Context context, VirtualHumanParam param)
参数:
context: Android Context
param: 数智人参数配置

initHuman()

初始化数智人引擎。
public int initHuman()
返回值:
0: 成功
20001: 模型加载错误
20010: License 鉴权失败
20011: 参数无效
20013: 模型尺寸不支持
20014: 缺少 READ_PHONE_STATE 权限(仅设备绑定鉴权场景)
示例:
int result = controller.initHuman();
if (result == 0) {
Log.i("VH", "初始化成功");
} else if (result == 20010) {
Log.e("VH", "License 失效");
}

setRenderView()

设置渲染视图。
public void setRenderView(IVirtualHumanRenderView view)
参数:
view: 实现 IVirtualHumanRenderView 接口的视图(VirtualHumanSurfaceView 或 VirtualHumanTextureView)
示例:
VirtualHumanSurfaceView view = new VirtualHumanSurfaceView(context);
controller.setRenderView(view);

startHuman()

启动数智人渲染。
public void startHuman()
说明:
必须在 initHuman() 成功后调用

appendAudioData()

推送音频数据驱动数智人播放。
public void appendAudioData(byte[] audioData, boolean isEnd)
public void appendAudioData(byte[] audioData, boolean isEnd, String metaData)
参数:
audioData: 音频数据(PCM 16bit 16kHz 单声道)
isEnd: 是否为最后一帧
metaData: 元数据(可选,用于同步自定义信息)
音频格式要求:
采样率:16000Hz
位深度:16bit
声道:单声道(Mono)
编码:PCM
// 流式推送
controller.appendAudioData(chunk1, false, "metadata_1");
controller.appendAudioData(chunk2, false, "metadata_2");
controller.appendAudioData(chunk3, true, "metadata_final");

// 一次性推送
byte[] audioData = loadAudioFile();
controller.appendAudioData(audioData, true);


appendAction()

插入动作。
说明:
sdkVersion 1.7.0+ 支持。
仅精品模式下生效。
动作执行结果通过事件回调通知(10006开始、10007完成、10008失败)。
public void appendAction(String actionCode, long timestampMs)
参数:
actionCode: 动作标识,对应模型中的 action_code(可通过 getAppendableActionList() 查询可用列表)。
timestampMs: 目标时间戳(毫秒),该动作执行到一半时的时间点。
示例:
// 查询可用动作列表后,在指定时刻插入动作
String actionList = controller.getAppendableActionList();
// 如果想当前片段播完后立即执行该动作,可以加上该动作时长的一半时间。
long targetTs = controller.getRunningDurationMs() + 2500;
// 动作标识在actionList列表可看到
controller.appendAction("heart", targetTs);


getAppendableActionList()

获取当前模型支持的可插入动作列表。
说明:
sdkVersion 1.7.0+ 支持。
仅精品模式下生效。
public String getAppendableActionList()
返回值:
JSON 字符串,格式:[{"action_code":"heart","duration_ms":2400}, ...]
引擎未初始化时返回 "[]"
示例:
String json = controller.getAppendableActionList();
// 解析示例
JSONArray actions = new JSONArray(json);
for (int i = 0; i < actions.length(); i++) {
JSONObject action = actions.getJSONObject(i);
String code = action.getString("action_code"); // 动作标识
int durationMs = action.getInt("duration_ms"); // 动作时长(毫秒)
Log.i("VH", "动作: " + code + ", 时长: " + durationMs + "ms");
}


getRunningDurationMs()

获取数智人运行时长。
说明:
sdkVersion 1.7.0+ 支持。
public long getRunningDurationMs()
返回值:
基于帧流已输出帧数计算的运行时长(每帧固定 40ms),与内部帧时间戳保持一致
与系统时钟无关,不受实际渲染耗时影响
未启动时返回 0
示例:
long durationMs = controller.getRunningDurationMs();
Log.i("VH", "已运行: " + durationMs + "ms");


interrupt()

打断当前播放。
public void interrupt()
说明:
立即停止当前播放内容
清空音频缓冲区

pause() / resume()

暂停/恢复渲染。
public void pause()
public void resume()
说明:
pause(): 暂停渲染,但保持引擎运行状态
resume(): 恢复渲染

setMuted()

设置静音状态。
public void setMuted(boolean muted)
参数:
muted: true 为静音,false 为取消静音

setFillMode()

设置渲染填充模式。
public void setFillMode(VirtualHumanViewType fillMode)
参数:
fillMode: 填充模式枚举
VirtualHumanViewType.fill: 保持比例,留黑边
VirtualHumanViewType.fit: 保持比例,裁切超出
VirtualHumanViewType.stretch: 拉伸填充,可能变形

stop()

停止并释放所有资源。
public void stop()
说明:
停止渲染
释放 Native 资源
关闭线程池
调用后需要重新 initHuman() 才能使用

getFillMode()

获取当前渲染填充模式。
public VirtualHumanViewType getFillMode()
返回值:
当前 VirtualHumanViewType 枚举值

getRenderView()

获取当前绑定的渲染 View。
public IVirtualHumanRenderView getRenderView()
返回值:
当前渲染 View,未设置时返回 null


setLogLevel()

设置日志级别。
public static void setLogLevel(int level)
参数:
VirtualHumanController.LOG_LEVEL_OFF: 关闭日志
VirtualHumanController.LOG_LEVEL_ERROR: 错误
VirtualHumanController.LOG_LEVEL_WARN: 警告
VirtualHumanController.LOG_LEVEL_INFO: 信息
VirtualHumanController.LOG_LEVEL_DEBUG: 调试
VirtualHumanController.LOG_LEVEL_TRACE: 追踪
示例:
VirtualHumanController.setLogLevel(VirtualHumanController.LOG_LEVEL_INFO);

setLogCallback()

设置日志回调。
public static void setLogCallback(IDataCallback logCallback)
参数:
logCallback: 日志回调接口
示例:
VirtualHumanController.setLogCallback((level, message) -> {
Log.i("VH", "Log[" + level + "]: " + message);
});

getVersion()

获取 SDK 版本。
public static String getVersion()
返回值:
SDK 版本字符串

runPerformanceTest()

运行性能检测。
注意:
该方法基于设备实时硬件配置执行基准测试,测试结果由当前设备的 SOC型号、负载状态及运行环境共同决定,因此同一设备在不同时刻可能存在差异。

public static void runPerformanceTest(Context context, VirtualHumanParam param, IDataCallback callback)
public static void runPerformanceTest(Context context, VirtualHumanParam param, IDataCallback callback, boolean forceRefresh)
参数:
context: Android Context
param: 数智人参数配置
callback: 检测结果回调
forceRefresh: 是否强制刷新(忽略缓存)
回调参数:
code:
0: 性能达标
1: 性能不足
负数: 检测失败
message: 详细信息
说明:
使用内置测试音频检测设备性能
会自动初始化、测试、销毁,无需手动管理生命周期
支持缓存机制,默认使用缓存结果(除非 forceRefresh=true)
示例:
VirtualHumanController.runPerformanceTest(context, param, (code, message) -> {
if (code == 0) {
Log.i("VH", "性能达标");
} else if (code == 1) {
Log.w("VH", "性能不足");
} else {
Log.e("VH", "检测失败: " + message);
}
});

// 强制刷新,忽略缓存
VirtualHumanController.runPerformanceTest(context, param, callback, true);

checkDeviceWhitelist()

检查设备黑白名单。
注意:
由于 Android 设备碎片化程度较高,黑白名单结果仅供参考,我们将持续维护并定期更新数据,以确保其准确性与可靠性。
public static void checkDeviceWhitelist(Context context, VirtualHumanParam param, IDataCallback callback)
public static void checkDeviceWhitelist(Context context, VirtualHumanParam param, IDataCallback callback, boolean forceRefresh)
参数:
context: Android Context
param: 数智人参数配置
callback: 检测结果回调
forceRefresh: 是否强制刷新(忽略缓存)
回调参数:
code:
0: 白名单(性能达标)
1: 黑名单(性能不足)
2: 未知设备(不在黑白名单中)
-1: SOC 获取失败
-2: 网络请求失败或初始化失败
message: 详细信息
说明:
根据设备 SOC 和模型参数判断设备是否在黑白名单中
会请求远程配置并自动初始化引擎
支持内存缓存机制(进程级别),默认使用缓存(除非 forceRefresh=true)
示例:
VirtualHumanController.checkDeviceWhitelist(context, param, (code, message) -> {
switch (code) {
case 0:
Log.i("VH", "白名单:设备性能达标");
break;
case 1:
Log.w("VH", "黑名单:设备性能不足");
break;
case 2:
Log.i("VH", "未知设备:不在黑白名单中");
break;
case -1:
Log.e("VH", "SOC 获取失败");
break;
case -2:
Log.e("VH", "检测失败: " + message);
break;
}
});

// 强制刷新,忽略缓存
VirtualHumanController.checkDeviceWhitelist(context, param, callback, true);


VirtualHumanParam

数智人参数配置类。
字段
// ===== 必填字段 =====

// License 鉴权
public String appId; // 应用 ID
public String secretKey; // 密钥

// 模型路径
public String commonModelPath; // 通用模型路径
public String humanModelPath; // 人物模型路径

// ===== 可选字段 =====

// 设备标识(仅设备绑定授权场景需要)
public String deviceName; // 设备唯一标识,必须保持固定不变

// 性能优化
public int skipFrameInterval = 7; // 跳帧间隔(0=不跳帧,7=每8帧跳1帧)
public boolean dualGen = false; // 是否启用双线程推理

/*
* 数字人在静默时无额外手部动作,交互更真实自然。
* 注:如果形象本身不支持该特性,则该配置项不生效。
* 默认值为true
*/
public boolean enableSilenceList = true;

// 回调
public IDataCallback eventCallback; // 事件回调
public IDataCallback errorCallback; // 错误回调
示例
VirtualHumanParam param = new VirtualHumanParam();

// 必填
param.appId = "your_app_id";
param.secretKey = "your_secret_key";
param.commonModelPath = "/sdcard/models/common_model";
param.humanModelPath = "/sdcard/models/human_001";

// 可选:设备标识(仅设备绑定授权场景需要)
// 重要:同一台设备必须始终使用相同的 deviceName,否则会导致鉴权失败
param.deviceName = "SN20240101001"; // 使用设备序列号(推荐)
// 或使用其他固定标识:
// param.deviceName = "ASSET-A-001"; // 资产编号
// param.deviceName = "00:11:22:33:44:55"; // MAC 地址

// 可选:性能优化
param.skipFrameInterval = 7; // 跳帧优化
param.dualGen = true; // 双线程加速

// 可选:回调
param.eventCallback = (code, message) -> {
Log.i("VH", "Event: " + code);
};
param.errorCallback = (code, message) -> {
Log.e("VH", "Error: " + code + ", " + message);
};
说明:
APP 绑定授权(bindDevice=false):deviceName 可以为空或不设置
设备绑定授权(bindDevice=true):
deviceName 必须设置,用于设备唯一性标识
同一台物理设备必须始终使用相同的 deviceName
如果 deviceName 变化,服务器会认为是不同设备,导致鉴权失败或消耗额外授权额度
建议使用设备出厂铭牌上的序列号、资产编号等固定不变的标识
不要使用随机值或每次变化的值

VirtualHumanSurfaceView

基于 SurfaceView 的渲染视图。
特点
✅ 性能更好,适合全屏渲染
✅ 独立的 Surface Layer
❌ UI 控件叠加需要额外处理(setZOrderOnTop 后普通 View 会被遮挡)
使用示例
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.tencent.virtualhuman_2d_sdk.VirtualHumanSurfaceView
android:id="@+id/vh_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</FrameLayout>
VirtualHumanSurfaceView view = findViewById(R.id.vh_view);
controller.setRenderView(view);

VirtualHumanTextureView

基于 TextureView 的渲染视图。
特点
✅ 支持透明背景
✅ UI 控件可以正常叠加显示
✅ 支持动画和变换
❌ 性能稍逊于 SurfaceView
使用示例
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- 背景层 -->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/background" />

<!-- 渲染层 -->
<com.tencent.virtualhuman_2d_sdk.VirtualHumanTextureView
android:id="@+id/vh_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<!-- 叠加控件层 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="操作按钮" />

</FrameLayout>
VirtualHumanTextureView view = findViewById(R.id.vh_view);
controller.setRenderView(view);

VirtualHumanViewType

渲染填充模式枚举。
枚举值
public enum VirtualHumanViewType {
fill, // 保持比例,留黑边(默认)
fit, // 保持比例,裁切超出
stretch // 拉伸填充,可能变形
}
示例
// 保持比例,留黑边
controller.setFillMode(VirtualHumanViewType.fill);

// 保持比例,裁切超出
controller.setFillMode(VirtualHumanViewType.fit);

// 拉伸填充
controller.setFillMode(VirtualHumanViewType.stretch);

5. 回调接口

IDataCallback

通用数据回调接口。
public interface IDataCallback {
void onDataCallback(int code, String message);
}
用途
1. 事件回调(param.eventCallback)
2. 错误回调(param.errorCallback)
3. 日志回调(setLogCallback)
4. 性能检测回调(runPerformanceTest)
5. 黑白名单检测回调(checkDeviceWhitelist)

6. 回调码

错误码

错误码
常量
说明
20001
ERROR_INIT_MODEL
模型加载失败
20010
ERROR_LICENSE_INVALID
License 鉴权失败
20011
ERROR_INIT_PARAM_INVALID
初始化参数无效
20012
ERROR_PERFORMANCE
设备性能不足
20013
ERROR_MODEL_SIZE_NOT_SUPPORTED
模型尺寸不支持(小屏版 SDK 不支持高尺寸模型)
20014
ERROR_PERMISSION_DENIED
缺少必要权限(设备绑定鉴权需要 READ_PHONE_STATE)

事件码

事件码
说明
10001
播放开始
10002
播放结束
10003
元数据开始
10004
元数据结束
10005
首帧渲染完成
50001
性能统计信息(包含平均耗时、最大耗时等)