duix-android/dh_aigc_android/README.md
English | 中文
Duix Mobile for Android is a lightweight, fully offline 2D digital human solution for Android, supporting real-time rendering of digital avatars driven by voice audio.
| Term | Meaning |
|---|---|
| PCM | Pulse-Code Modulation, raw audio stream with 16kHz sample rate, 16-bit depth, Mono channel |
| WAV | An audio file format that supports PCM encoding, suitable for short voice playback |
| RenderSink | Rendering data reception interface, implemented by the SDK, can be used for custom rendering or default display |
| DUIX | Main control object of the digital human, integrates model loading, rendering, broadcasting, and motion control |
| GLES | OpenGL ES, a graphics interface for rendering images on Android |
| SpecialAction | A JSON file attached to the model that marks action intervals (e.g., greetings, waving) |
duix-sdk directory to the project root directory.settings.gradle, add:include ':duix-sdk'
build.gradle, add the dependency:dependencies {
api project(":duix-sdk")
}
duix-sdk-release.aar module into the libs/ directory.dependencies {
api fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
}
| Item | Description |
|---|---|
| System | Supports Android 10+ systems. |
| CPU Architecture | armeabi-v7a, arm64-v8a |
| Hardware Requirements | Device CPU with 8 or more cores (Snapdragon 8 Gen 2), 8GB or more memory, available storage space of 1GB or more |
| Network | None (Fully local operation) |
| Development IDE | Android Studio Giraffe 2022.3.1 Patch 2 |
| Memory Requirements | Minimum 800MB memory available for the digital human |
graph TD
A[Check Configuration and Models] --> B[Build DUIX Instance]
B --> C[Call init to Initialize]
C --> D[Display Avatar / Render]
D --> E[PCM or WAV Audio Driving]
E --> F[Playback Control & Motion Triggering]
F --> G[Resource Release]
Before using the rendering service, ensure that the basic configuration and model files are synchronized to local storage. The SDK provides a simple demonstration of the model download and decompression process using VirtualModelUtil. If model download is slow or fails, developers can choose to cache the model package to their own storage service.
Function Definition:
ai.guiji.duix.sdk.client.VirtualModelUtil
// Check if base configuration is downloaded
boolean checkBaseConfig(Context context)
// Check if the model is downloaded
boolean checkModel(Context context, String name)
// Base configuration download
void baseConfigDownload(Context context, String url, ModelDownloadCallback callback)
// Model download
void modelDownload(Context context, String modelUrl, ModelDownloadCallback callback)
ModelDownloadCallback includes progress, completion, failure callbacks, etc., as defined in the SDK.
interface ModelDownloadCallback {
// Download progress
void onDownloadProgress(String url, long current, long total);
// Unzip progress
void onUnzipProgress(String url, long current, long total);
// Download and unzip complete
void onDownloadComplete(String url, File dir);
// Download and unzip failed
void onDownloadFail(String url, int code, String msg);
}
Call Example:
if (!VirtualModelUtil.checkBaseConfig(mContext)){
VirtualModelUtil.baseConfigDownload(mContext, baseConfigUrl, callback)
}
if (!VirtualModelUtil.checkModel(mContext, modelUrl)){
VirtualModelUtil.modelDownload(mContext, modelUrl, callback)
}
In the onCreate() stage of the rendering page, build the DUIX object and call the init interface.
Function Definition:
ai.guiji.duix.sdk.client.DUIX
// Build DUIX object
public DUIX(Context context, String modelName, RenderSink sink, Callback callback)
// Initialize DUIX service
void init()
DUIX Object Construction Explanation:
| Parameter | Type | Description |
|---|---|---|
| context | Context | System context |
| modelName | String | Can pass the model download URL (if downloaded) or cached filename |
| render | RenderSink | Rendering data interface, SDK provides a default rendering component inheriting from this interface, or you can implement it yourself |
| callback | Callback | Various callback events handled by the SDK |
Where Callback is defined as: ai.guiji.duix.sdk.client.Callback
interface Callback {
void onEvent(String event, String msg, Object info);
}
Call Example:
duix = DUIX(mContext, modelUrl, mDUIXRender) { event, msg, info ->
when (event) {
ai.guiji.duix.sdk.client.Constant.CALLBACK_EVENT_INIT_READY -> {
initOK()
}
ai.guiji.duix.sdk.client.Constant.CALLBACK_EVENT_INIT_ERROR -> {
initError()
}
// ...
}
}
// Asynchronous callback result
duix?.init()
In the init callback, confirm the initialization result.
Use the SDK-provided DUIXRenderer and DUIXTextureView to quickly implement rendering with transparency support. Alternatively, you can implement the RenderSink interface to customize the rendering logic.
The RenderSink definition is as follows: ai.guiji.duix.sdk.client.render.RenderSink
/**
* Rendering pipeline, returns rendering data through this interface
*/
public interface RenderSink {
// The frame's buffer data is arranged in BGR order
void onVideoFrame(ImageFrame imageFrame);
}
Call Example:
Use DUIXRenderer and DUIXTextureView to quickly implement rendering. These controls support transparency and can freely set the background and foreground.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
mDUIXRender =
DUIXRenderer(
mContext,
binding.glTextureView
)
binding.glTextureView.setEGLContextClientVersion(GL_CONTEXT_VERSION)
binding.glTextureView.setEGLConfigChooser(8, 8, 8, 8, 16, 0) // Transparency
binding.glTextureView.isOpaque = false // Transparency
binding.glTextureView.setRenderer(mDUIXRender)
binding.glTextureView.renderMode =
GLSurfaceView.RENDERMODE_WHEN_DIRTY // Must be called after setting the renderer
duix = DUIX(mContext, modelUrl, mDUIXRender) { event, msg, _ ->
}
// ...
}
PCM Format: 16kHz sample rate, single channel, 16-bit depth
Function Definition:
ai.guiji.duix.sdk.client.DUIX
// Notify service to start pushing audio
void startPush()
// Push PCM data
void pushPcm(byte[] buffer)
// Finish a segment of audio push (Call this after the audio push is complete, not after playback finishes)
void stopPush()
startPush, pushPcm, and stopPush need to be called in pairs. pushPcm should not be too long. After pushing the entire audio, call stopPush to end the session. Use startPush again for the next audio.
The audio data between each startPush and stopPush segment should be at least 1 second (32000 bytes), otherwise the mouth shape driver cannot be triggered, and blank frames can be used to fill in.
Call Example:
val thread = 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){
val data = buffer.copyOfRange(0, length)
duix?.pushPcm(data)
}
duix?.stopPush()
inputStream.close()
}
thread.start()
The model supports new motion intervals marked in SpecialAction.json
Function Definition:
ai.guiji.duix.sdk.client.DUIX
/**
* Play specific motion interval
* @param name The motion interval name, which can be obtained from @{ModelInfo.getSilenceRegion()} after init callback
* @param now Whether to play immediately: true: play now; false: wait for current silent or motion interval to finish
*/
void startMotion(String name, boolean now)
Call Example:
duix?.startMotion("Greeting", true)
Function Definition:
ai.guiji.duix.sdk.client.DUIX
/**
* Randomly play a motion interval
* @param now Whether to play immediately: true: play now; false: wait for current silent or motion interval to finish
*/
void startRandomMotion(boolean now);
Call Example:
duix?.startRandomMotion(true)
If using obfuscation, add the following in proguard-rules.pro:
-keep class ai.guiji.duix.DuixNcnn{*; }
modelUrl value in MainActivity.kt and use the SDK's built-in file download and decompression management to obtain the complete model files.duix?.setReporter() to monitor frame rendering information.| Issue | Possible Cause | Solution |
|---|---|---|
| init callback failed | Model path error or model not downloaded | Use checkModel to check model status |
| Rendering black screen | EGL configuration or texture view error | Use SDK-provided example settings |
| No PCM playback effect | Incorrect format or startPush not called | Ensure audio format is correct and call push method |
| Model download slow | Unstable network or restricted CDN | Support self-hosted model file storage service |
<a>4.0.1</a>
<a>3.0.5</a>
1. Updated arm32 CPU libonnxruntime.so version to fix compatibility issues.
2. Modified motion interval playback function, supports random and sequential playback, requires manual call to stop playback to return to silent interval.
<a>3.0.4</a>
1. Fixed model display issue due to low float precision on some devices.
<a>3.0.3</a>
1. Optimized local rendering.
| Module | Description |
|---|---|
| onnx | General AI model standard format |
| ncnn | High-performance neural network computing framework (Tencent) |
For more help, please contact the technical support team.