# digital-human-android **Repository Path**: wx-rdc/digital-human-android ## Basic Information - **Project Name**: digital-human-android - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-05 - **Last Updated**: 2026-05-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Duix Mobile for Android SDK 轻量级、纯离线的 Android 平台 2D 数字人解决方案,支持通过语音音频驱动数字人形象并进行实时渲染。 ## 一、应用场景 - **部署成本低**:适用于大屏终端、政务展厅、银行等无人值守场景 - **网络依赖小**:完全本地运行,无需联网,可在地铁、偏远地区稳定运行 - **功能多样化**:支持导览讲解、问答客服、智能陪伴等业务形态 ## 二、核心功能 - 数字人形象定制与本地渲染 - 实时语音驱动播报(支持 WAV 播放和 PCM 流式推送) - 动作播放控制(指定动作、随机动作) - 自动资源下载管理 - ASR 语音识别 / LLM 对话 / TTS 语音合成(本地离线 + 在线 API 双模式) ## 三、项目结构 | 模块 | 类型 | 说明 | |------|------|------| | `duix-sdk` | Android Library | 核心 SDK — C++ 原生引擎 + Kotlin/Java SDK 封装 | | `test` | Android Application | Demo/测试应用,演示完整 ASR→LLM→TTS→渲染 流程 | ``` Native C API (gjduix.h / gjsimp.h) └── JNI 桥接: duix-sdk/src/main/cpp/android/DuixJni.cpp └── Java 类: ai.guiji.duix.DuixNcnn ← JNI native 方法 └── Kotlin SDK: ai.guiji.duix.sdk.client.DUIX └── DigitalHumanCoordinator (编排 ASR → LLM → TTS → 渲染) ``` 核心 C++ 模块(`duix-sdk/src/main/cpp/`): | 目录 | 功能 | |------|------| | `android/` | JNI 入口(`DuixJni.cpp`) | | `duix/` | 音频处理引擎(PCM 会话、WeNet ONNX 推理、BNF 特征提取)、SIMP 神经网络渲染 | | `dhunet/` | UNet 人脸合成(ncnn/OpenCV)、图像混合 | | `dhmfcc/` | MFCC 特征提取、sherpa-onnx ASR/TTS/VAD、RKLLM 大模型、PCM 管理 | | `aes/` | AES 解密(模型文件加密存储) | | `third/` | 预编译依赖库(OpenCV、ncnn、ONNX Runtime、sherpa-onnx、RKLLM) | ## 四、编译环境 | 项目 | 要求 | |------|------| | JDK | **JDK 17**(`sourceCompatibility = 17`,`jvmTarget = '17'`) | | Gradle | 8.5 | | Android Gradle Plugin | 8.2.2 | | Kotlin | 2.3.0 | | NDK | 25.1.8937393 | | CMake | 4.1.2 | | compileSdk / minSdk / targetSdk | 34 / 24 / 34 | | CPU 架构 | **仅 arm64-v8a**(sherpa-onnx 和 RKLLM 预编译库仅支持此架构) | > **注意**:仓库中不包含 `gradlew` 脚本(已 gitignore),需通过 `gradle wrapper` 或 Android Studio 重新生成。 > Maven 仓库使用阿里云镜像,在中国大陆以外构建时需要替换为 `google()` / `mavenCentral()`。 ## 五、API Key 配置 在线模式的 API Key 通过 `local.properties` 或环境变量注入为 `BuildConfig` 字段: ```properties # local.properties(或设置环境变量): LLM_API_KEY=your_key # 默认值: "null" LLM_MODEL=deepseek-ai/DeepSeek-R1-0528-Qwen3-8B # 默认值 TTS_API_KEY=your_key # 默认值: "null" TTS_MODEL=FunAudioLLM/CosyVoice2-0.5B # 默认值 ASR_API_KEY=your_key # 默认值: "null" ASR_MODEL=FunAudioLLM/SenseVoiceSmall # 默认值 ``` ## 六、模型文件说明 - 模型文件**不在仓库中**(`test/src/main/assets/embedded_models/` 和 `/models` 已 gitignore) - 模型在磁盘上通常经过 **AES 加密**,由 native `aes/` 层在使用前解密 - 模型下载与校验由 `VirtualModelUtil.java` 管理 ## 七、SDK 集成方式 ### 7.1 Module 引用(推荐) ```gradle // settings.gradle include ':duix-sdk' // 模块 build.gradle dependencies { api project(":duix-sdk") } ``` ### 7.2 AAR 引用 将编译产出 `duix-sdk-release.aar` 放入 `libs/` 目录: ```gradle dependencies { api fileTree(include: ['*.jar', '*.aar'], dir: 'libs') } ``` ## 八、术语说明 | 术语 | 含义 | |------|------| | PCM | 16kHz 采样率、16bit 位深、Mono 单通道的原始音频流 | | WAV | 支持 PCM 编码的音频文件格式,适合短语音播放 | | RenderSink | 渲染数据接收接口,帧缓冲区以 **BGR 字节序**排列 | | DUIX | 数字人主控对象,集成模型加载、渲染、播报、动作控制 | | SpecialAction | 模型附带的 JSON 文件,标注动作区间(如打招呼、挥手等) | ## 九、使用流程 ```mermaid graph TD A[检查配置与模型] --> B[构建 DUIX 实例] B --> C[调用 init 初始化] C --> D[展示形象 / 渲染] D --> E[PCM 或 WAV 音频驱动] E --> F[播放控制与动作触发] F --> G[资源释放] ``` ## 十、核心接口 ### 10.1 模型检查与下载 `ai.guiji.duix.sdk.client.VirtualModelUtil` ```java boolean checkBaseConfig(Context context) boolean checkModel(Context context, String name) void baseConfigDownload(Context context, String url, ModelDownloadCallback callback) void modelDownload(Context context, String modelUrl, ModelDownloadCallback callback) ``` ```kotlin if (!VirtualModelUtil.checkBaseConfig(mContext)) { VirtualModelUtil.baseConfigDownload(mContext, baseConfigUrl, callback) } if (!VirtualModelUtil.checkModel(mContext, modelUrl)) { VirtualModelUtil.modelDownload(mContext, modelUrl, callback) } ``` ### 10.2 初始化与渲染 `ai.guiji.duix.sdk.client.DUIX` ```kotlin // 构建 DUIX 对象 duix = DUIX(context, modelName, renderSink) { event, msg, info -> when (event) { Constant.CALLBACK_EVENT_INIT_READY -> initOK() Constant.CALLBACK_EVENT_INIT_ERROR -> initError() } } duix?.init() ``` 使用 SDK 提供的 `DUIXRenderer` + `DUIXTextureView` 实现透明通道渲染: ```kotlin mDUIXRender = DUIXRenderer(mContext, binding.glTextureView) binding.glTextureView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) // 透明 binding.glTextureView.isOpaque = false binding.glTextureView.setRenderer(mDUIXRender) binding.glTextureView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY ``` > `RenderSink.onVideoFrame(ImageFrame)` 中的帧缓冲区以 **BGR 字节序**排列。 ### 10.3 PCM 流式驱动播报 **格式要求:16kHz 采样率、单通道、16bit 位深** ```java void startPush() // 通知开始推送 void pushPcm(byte[] buffer) // 推送 PCM 数据 void stopPush() // 结束当前段(推送完即调用,不等播放完成) ``` > **关键约束**:每段 `startPush` → `stopPush` 之间的音频数据**至少 1 秒(32000 字节)**,否则无法触发口型驱动,可用空白帧填充。 ```kotlin Thread { duix?.startPush() val inputStream = assets.open("pcm/2.pcm") val buffer = ByteArray(320) var length = 0 while (inputStream.read(buffer).also { length = it } > 0) { duix?.pushPcm(buffer.copyOfRange(0, length)) } duix?.stopPush() inputStream.close() }.start() ``` ### 10.4 WAV 播放驱动 `playAudio(wavPath)` 兼容旧接口,内部实际通过 PCM 推流实现。 ### 10.5 动作控制 ```kotlin duix?.startMotion("打招呼", true) // 播放指定动作区间 duix?.startRandomMotion(true) // 随机播放动作 duix?.stopAudio() // 终止当前播报 ``` ## 十一、Proguard 配置 > 所有 native 方法注册在 `ai.guiji.duix.DuixNcnn` 类上,**必须 keep**。 ```proguard -keep class ai.guiji.duix.DuixNcnn{*; } ``` ## 十二、构建命令 ```bash # Android 构建(需要先重新生成 gradlew): ./gradlew assembleDebug # 构建 test 应用 APK ./gradlew :duix-sdk:assembleRelease # 构建 SDK AAR → duix-sdk/build/outputs/aar/ # Native 独立测试(需设置 ANDROID_NDK_HOME): cd duix-sdk/src/main/cpp export ANDROID_NDK_HOME=~/Android/Sdk/ndk/29.0.14206865 ./build_test_arm.sh # 部署到设备并运行测试: cd build_test_arm && ./deploy_to_device.sh ``` > Native 独立测试程序(`iostest/` 下)**不参与 Android Gradle 构建**,需单独通过 CMake 编译。 ## 十三、注意事项 1. 初始化渲染前需确保模型文件已下载到指定位置 2. PCM 音频不宜过长,缓存在内存中,过长可能导致内存溢出 3. 设备性能不足时可用 `duix?.setReporter()` 监控帧渲染信息 4. 测试 APK 签名使用 `demo.jks`(密码 `123456`),debug 构建也强制签名 5. aapt 不压缩后缀:`.zip` `.onnx` `.rknn` `.rkllm` `.txt` `.fst` `.utf8` ## 十四、常见问题 | 问题 | 可能原因 | 解决方案 | |------|----------|----------| | init 回调失败 | 模型路径错误或未下载完成 | 使用 `checkModel` 检查模型状态 | | 渲染黑屏 | EGL 配置或纹理视图设置错误 | 参照 SDK 示例中的 EGL 设置方法 | | PCM 无播报效果 | 格式不符或未调用 `startPush` | 确保 16k/16bit/Mono 格式并正确调用推送方法 | | 模型下载慢 | 网络不稳定或 CDN 受限 | 支持自建模型文件托管服务 | ## 十五、版本记录 **4.1.1** - 集成 sherpa-onnx ASR/TTS/VAD 引擎 - 支持本地离线 + 在线 API 双模式(ASR / LLM / TTS) - 新增语音唤醒(Wake Word)、语言切换功能 - 支持 RKLLM 本地大模型推理(Rockchip NPU) **4.0.1** - 支持 PCM 音频流驱动,提升音频播放响应速度 - 优化动作区间播放,可根据模型配置指定动作区间 - 自定义音频播放器,去除 Exoplayer 依赖 **3.0.5** - 更新 arm32 位 libonnxruntime.so 版本以修复兼容问题 - 修改动作区间播放函数,支持随机和顺序播放 **3.0.4** - 修复部分设备 GL 默认 float 低精度导致形象无法正常显示 **3.0.3** - 优化本地渲染 ## 十六、相关文档 | 文档 | 说明 | |------|------| | `AGENTS.md` | 开发环境与架构速查(面向 AI 编码助手) | | `todo.md` | Sherpa-ONNX ASR/TTS 集成执行计划 | | `docs/` | 技术设计文档(ASR、TTS、LLM、语音唤醒、语言切换等) | | `duix-sdk/src/main/cpp/iostest/` | Native 测试程序 README | ## 十七、开源依赖 | 模块 | 说明 | |------|------| | [onnx](https://github.com/onnx/onnx) | 通用 AI 模型标准格式 | | [ncnn](https://github.com/Tencent/ncnn) | 高性能神经网络计算框架(腾讯) | | [sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx) | 语音识别/合成/唤醒引擎 | | [OpenCV](https://opencv.org/) | 计算机视觉库 | | RKLLM | Rockchip NPU 大模型推理框架 |