Android SDK 接入指南(v0.0.6)

一.准备工作

概述

本文是Lite_SDK_Android版本的接入文档,用于指导SDK的使用方法,默认读者已经熟悉 IDE(Eclipse 或者 Android Studio)的基本使用方法,以及具有一定的 Android 编程知识基础。

快速体验demo

  • Android压缩包附带的apk文件中是虚拟人demo的安装包,可以直接安装到Android手机上。并快速体验在您的手机上的表现。
  • Android压缩包附带的demo文件夹中是虚拟人的示例工程,使用Android studio打开示例工程,完成以下步骤配置,然后直接运行起来测试。

a. 替换SettingActivity中的appid和appSecret

b.demo_configs.json中的config按需配置

c.MockAudioInputsData.json是支持自行输入音频数据的示例格式

开发环境搭建

(1)将开发包拷贝到工程

将SDK中libs目录下的aar包拷贝到自己工程的libs目录下,如没有该目录需新建。

在app文件夹下的build.gradle的dependencies中配置对应版本的aar依赖详细代码如下:

implementation files('libs/xmovdigitalhuman-xxx.aar')

(2)添加外部第三方依赖 详细代码如下:

    implementation "javax.vecmath:vecmath:1.5.2"
implementation "com.google.code.gson:gson:2.13.1"
implementation "com.squareup.okhttp3:okhttp:5.1.0"
implementation "org.msgpack:msgpack-core:0.9.3"
implementation "io.socket:socket.io-client:2.1.0"
// Protobuf 依赖
implementation("com.google.protobuf:protobuf-javalite:3.21.12")
// ExoPlayer dependency for WebM/Opus streaming
implementation "androidx.media3:media3-exoplayer:1.9.0"

根 build.gradle.kts文件中增加protobuf相关配置

这张图片展示了Android项目根build.gradle.kts文件的配置页面,核心是plugins代码块中的关键配置项,红框突出标注了<code spellcheck=alias(libs.plugins.protobuf) apply false这一内容。该图片与文档中“根build.gradle.kts文件中增加protobuf相关配置”的要求对应,清晰呈现了protobuf插件依赖的配置代码,是SDK接入准备工作里根Gradle文件配置环节的直观演示。" width="inherit" height="inherit" id="88">

图片展示了Android工程中libs.versions.toml文件的内容。其中,protobuf版本号被红色框突出显示为“0.9.4”。该文件还列出了JUnit、Espresso等依赖库的版本号。此图片与文档中“添加外部第三方依赖”步骤相关,用于说明在根build.gradle.kts文件中增加protobuf相关配置时,protobuf版本号的具体设置情况,以确保Android SDK接入时的依赖配置正确。

(3)配置AndroidManifest.xml文件

在manifest标签内添加必要的权限支持

<uses-permission android:name="android.permission.INTERNET"/>

(3) 混淆规则:

-keep public class com.xmov.metahuman.sdk.data.**{*;}
-keep public class com.xmov.metahuman.sdk.impl.data.**{*;}
-keep public class com.xmov.metahuman.sdk.impl.transport.http.**{*;}
-keep public interface com.xmov.metahuman.sdk.IXmovAvatar {*;}
-keep class com.xmov.metahuman.sdk.IXmovAvatar$Companion { *;}
-keep public interface com.xmov.metahuman.sdk.IAvatarListener {
public protected *;
}
-keep public interface com.xmov.metahuman.sdk.PreCacheListener {
public protected *;
}

通过上面的几个步骤,工程就配置完成了,接下来就可以在工程中使用虚拟人SDK进行开发了。

二.SDK使用说明

1.预缓存

预缓存是提前缓存视频资源或者charbin文件资源,可按需调用,不是必须调用的;调用时机在初始化方法之前调用

(1)预缓存视频

文件较多,需要几分钟时间,大屏常驻设备可提前调用缓存,按需调用

方法原型

fun preCache(
context: Context,
appId: String,
appSecret: String,
url: String,
listener: PreCacheListener?
)

参数描述

参数

类型

说明

context

Context

一般传Activity或者applicationContext对象

appId

String

星云开放平台上创建对应应用角色的appid

appSecret

String

星云开放平台上创建对应应用角色的appSecret

listener

PreCacheListener

回调监听

(2)预缓存charbin

时间较快,可提前调用,缩短初始化耗时

 fun preCacheCharBin(
context: Context,
appId: String,
appSecret: String,
url: String,
listener: PreCacheListener?
)

参数描述

参数

类型

说明

context

Context

一般传Activity或者applicationContext对象

appId

String

星云开放平台上创建对应应用角色的appid

appSecret

String

星云开放平台上创建对应应用角色的appSecret

listener

PreCacheListener

回调监听

示例代码

//预缓存视频资源
IXmovAvatar.get().preCache(this,AppConfig.appId,AppConfig.appSecret, DemoConfig.gatewayServerCache
,object :
PreCacheListener {
override fun onPreCacheComplete() {
runOnUiThread {
LogUtil.i("onPreCacheComplete")
dismissLoading()
TipsToast.showTips("预缓存完成")
MainActivity.start(this@SplashActivity)
finish()
}
}
override fun onPreCacheProgress(progress: Int) {
runOnUiThread {
LogUtil.i("onPreCacheProgress: $progress")
setLoadingTitle("预缓存中 $progress%")
}
}
})

//预缓存charbin
IXmovAvatar.get().preCacheCharBin(this,AppConfig.appId,AppConfig.appSecret, DemoConfig.gatewayServerCache
,object :
PreCacheListener {
override fun onPreCacheComplete() {
runOnUiThread {
LogUtil.i("onPreCacheComplete")
dismissLoading()
TipsToast.showTips("预缓存完成")
MainActivity.start(this@SplashActivity)
finish()
}
}
override fun onPreCacheProgress(progress: Int) {
runOnUiThread {
LogUtil.i("onPreCacheProgress: $progress")
setLoadingTitle("预缓存中 $progress%")
}
}
})

1.进度回调onPreCacheProgress(progress: Int) progress 范围是0-100,缓存的进度

2.完成回调 onPreCacheComplete() 缓存完成

3.失败回调 onPreCacheFailed(errorCode: Int, errorMessage: String)

2.初始化

使用SDK功能前,必须先进行初始化操作。

方法原型

fun init(
context: Context,
layout: ViewGroup,
initConfig: InitConfig,
listener: IAvatarListener?
)

参数描述

参数

类型

说明

context

Context

一般传Activity对象

layout

ViewGroup

加载虚拟人所在的父布局

initConfig

InitConfig

初始化配置类

listener

IAvatarListener

回调监听

InitConfig 类介绍

参数

类型

说明

appId

String

星云具身中应用对应的appId

appSecret

String

星云具身中应用对应的appSecret

gatewayServer

String

进入房间的地址:"https://nebula-agent.xingyun3d.com/user/v1/ttsa/session"

config

String

json string 设置一些配置项

初始化示例代码

     IXmovAvatar.get().init(this, mBinding.avatarLayout, initConfig.appId, initConfig.appSecret,initConfig.gatewayServer,object : IAvatarListener {
override fun onInitEvent(code: Int, message: String?) {
LogUtil.d("onInitEvent code:$code,message:$message")
}

override fun onWidgetEvent(widgetData: IRawEventFrameData?) {
LogUtil.d("onWidgetEvent widgetData:$widgetData")
}

override fun onNetworkInfo(sdkNetworkInfo: SDKNetworkInfo?) {
LogUtil.d("onNetworkInfo $sdkNetworkInfo")
}

override fun onMessage(sdkMessage: SDKMessage?) {
LogUtil.d("onMessage $sdkMessage")
}

override fun onStateChange(state: String?) {
LogUtil.d("onStateChange $state")
}

override fun onStatusChange(status: SDKStatus?) {
LogUtil.d("onStatusChange $status")
}

override fun onStateRenderChange(state: String?, duration: Long) {
LogUtil.d("onStateRenderChange state:$state,duration:$duration")
}

override fun onVoiceStateChange(status: String?,clientSpeakId: String?) {
LogUtil.d("onVoiceStateChange state:$status")
runOnUiThread {
if ("voice_end" == status) {
} else if ("voice_start" == status) {
}
}
}

override fun onDebugInfo(debugInfo: JSONObject) {
// LogUtil.d("onDebugInfo debugInfo:$debugInfo")
}

override fun onReconnectEvent(code: Int, message: String?) {
toast("重连:code=$code message=$message")
}

override fun onOfflineEvent() {
toast("进入离线状态")
}

override fun onSDKRuntimeError(code: Int, message: String?) {
Log.d(TAG, "onSDKRuntimeError code:$code,message:$message")
toast("onSDKRuntimeError code:$code,message:$message")
}
override fun onSpeakStateChange(
speakState: String?,
clientSpeakId: String?,
errorMsg: String?
) {
Log.d(TAG, "onSpeakStateChange :speakState=$speakState clientSpeakId=$clientSpeakId errorMsg=$errorMsg")
toast("onSpeakStateChange :speakState=$speakState clientSpeakId=$clientSpeakId errorMsg=$errorMsg")
}
override fun onWalkStateChange(walkState: String?) {
Log.d(TAG, "onWalkStateChange $walkState")
toast("onWalkStateChange $walkState")
}
})

1.初始化回调

onInitEvent(code: Int, message: String?)方法返回参数分为外层code和result,含义如下:

字段

类型

含义

code

Int

code为0:成功;其他:失败

message

String

返回信息

2.事件回调(字幕回调)

onWidgetEvent(widgetData: IRawEventFrameData?)

IRawEventFrameData实体类

字段

类型

含义

startFrame

Int

开始帧

event

JSONArray

type: "subtitle_on" 字幕类型,text 字幕文案

3.声音播报回调

onVoiceStateChange(status: String?,clientSpeakId: String?)

字段

类型

含义

status

String

"voice_start" 播报开始"voice_end" 播报结束

clientSpeakId

String

speakid,可在调用speak时传入,不传内部自动生成一个id

4.重连在线模式回调

onReconnectEvent(code: Int, message: String?)

字段

类型

含义

code

Int

code为0:成功;其他:失败

message

String

返回信息

5.SDK在运行过程中的错误回调

可在该回调中,进行重新初始化逻辑,保证设备长期运行

onSDKRuntimeError(code: Int, message: String?)

字段

类型

含义

code

Int

错误code码

message

String

错误信息

6.speak事件回调

返回speak事件的开始,结束,错误状态

onSpeakStateChange(speakState: String?,clientSpeakId: String?,errorMsg: String?)

字段

类型

含义

speakState

String

speak事件状态 speak_start speak_end speak_error

clientSpeakId

String

speakid,可在调用speak时传入,不传内部自动生成一个id

errorMsg

String

错误信息 仅在speakState为speak_error下返回

7.walk事件回调

onWalkStateChange(String walkState)

字段

类型

含义

walkState

String

walk事件状态 speak_walk_start speak_walk_end

3.config配置

在进行初始化时,initConfig中的config是一个json 字符串,可以定制化做一些配置

config字段名介绍

字段名

数据类型

说明

默认值

示例值

input_audio

boolean

是否开启自己的音频输入true为开启,false为关闭(sdk内部的音频输入)

FALSE

FALSE

output_audio

boolean

是否开启SDK内音频输出true为使用sdk内部音频输出false不使用sdk内部音频输出

TRUE

TRUE

input_audio_sample_rate

Int

输入音频的采样率(仅在使用输入音频时使用)

24000

16000

enable_client_interrupt

boolean

开启enableClientInterrupt,播报状态切换其他状态时会立即关闭数字人口型渲染及音频字幕。

FALSE

TRUE

max_reconnect_count

Int

最大重连次数(默认5次)断网情况下会切换到离线模式,当sdk检测到有网会进行重连

5

5

init_time_out

Int

初始化渲染第一帧超时阈值(默认30s)

30

30

render_time_out

Int

视频渲染超时阈值(默认15秒)

15

15

resolution

JSONObject

分辨率配置对象,用于定义画面的宽高参数(跟随角色分辨率保持一致)

{"height": 1920, "width": 1080}

{"height": 1920, "width": 1080}

resolution.height

number

画面高度,单位为像素(px)

1920

1920

resolution.width

number

画面宽度,单位为像素(px)

1080

1080

layout

LayoutConfig

数字人布局配置结构化对象



walk_config

WalkConfig

数字人行走配置结构化对象



LayoutConfig介绍

(1)container(容器配置)

字段名

数据类型

说明

默认值

示例值

size

Int[]

容器尺寸,数组第一位为宽度,第二位为高度


[1080, 1920]

(2)avatar(数字人布局配置)注意:align需要容器为约束布局ConstraintLayout 类型生效

字段名

数据类型

取值范围

说明

默认值

示例值

v_align

string

"top" / "middle" / "bottom"

数字人在容器内的垂直对齐方式(vertical align),控制数字人在容器垂直方向的位置(容器为约束布局ConstraintLayout 类型生效)

"middle"

"middle"

h_align

string

"left" "center" "right"

数字人在容器内的水平对齐方式(horizontal align),控制数字人在容器水平方向的位置(容器为约束布局ConstraintLayout 类型生效)

"center"

"center"

scale

Float | string

>0 或者 40vh

数字人缩放比例,1 为原始尺寸,0.5 为缩小至 50%,大于 1 为放大 // 设置0.4 是基于分辨率的0.4,例如:10801920的数字人。设置0.4之后大小为432768 // 设置40vh 非数字,且包含vh时,根据vh计算scale 计算公式是 vh值 / 100 * 容器高度 / 分辨率高度 = scale 例如0.4vh,实际scale =(40/100* 810)/1920=0.16875,此时数字人的大小为182.25*324

1

0.5

offset_x

number

任意数值

数字人在水平对齐基础上的偏移量(正数向右,负数向左)

0

20

offset_y

number

任意数值

数字人在垂直对齐基础上的偏移量(正数向下,负数向上)

0

20

WalkConfig介绍

配置项

类型

取值约束

说明

示例

walk_points

object

1. 键:自定义点位名称(字符串,如 A/B/C/D、start/center/end 等);



init_point

string

walk_points中的键名

设置数字人的当前点位


配置示例

{
"max_reconnect_count": 5,
"render_time_out": 12,
"input_audio": false,
"output_audio": true,
"enable_client_interrupt": true,
"resolution": {
"width": 1080,
"height": 1920
},
"layout": {
"container": {
"size": [
2712,
1220
]
},
"avatar": {
"h_align": "center",
"v_align": "middle",
"scale": 1,
"offset_x": 0,
"offset_y": 0
}
},
"walk_config": {
"walk_points": {
"A": -500,
"B": -400,
"C": -300,
"D": -200,
"E": -100,
"F": 0,
"G": 100,
"H": 200,
"I": 300,
"J": 400,
"K": 500,
"O": 600,
"P": 700,
"Q": 800,
"L": 900,
"M": 1000
},
"init_point": 0
}
}

4.Speak

4.1 SDK内部音频播报

方法原型

fun speak(
ssml: String?,
isStart: Boolean,
isEnd: Boolean,
enableSpeechCache: Boolean? = null,
clientSpeakId: String? = null
)

参数说明

参数

参数类型

说明

ssml(必填)

String

传入说话内容的文本信息(支持ka动作)

isStart(必填)

boolean

是否开始节点

isEnd(必填)

boolean

是否输入结束

enableSpeechCache(可选)

boolean?

是否启用缓存(默认null)

clientSpeakId(可选)

String?

当前会话的speak id (默认null)

支持全文本和流式文本输入

(1)全文本输入时代码示例:

IXmovAvatar.get().speak("welcomeMessage", true, true, false,null)

(2) 流式文本输入时代码示例

//开头
IXmovAvatar.get().speak("msg 1", true, false, false,null)
IXmovAvatar.get().speak("msg 2", false, false, false,null)
...
//结尾
IXmovAvatar.get().speak("msg 2", false, true, false,null)

4.2 SDK外部音频播报

使用该方法时必须要设置config必须要配置"input_audio": true, "output_audio": true

方法原型

fun speak(
ssml: String?,
isStart: Boolean,
isEnd: Boolean,
ttsData: JSONObject,
enableSpeechCache: Boolean? = null,
clientSpeakId: String? = null
)

参数说明

参数

参数类型

说明

ssml(必填)

String

传入说话内容的文本信息(支持ka动作)

isStart(必填)

boolean

是否开始节点

isEnd(必填)

boolean

是否输入结束

ttsData(必填)

JSONObject

音频数据(格式参考demo中的MockAudioInputsData.json文件)

enableSpeechCache(可选)

boolean?

是否启用缓存(默认null)

clientSpeakId(可选)

String?

当前会话的speak id (默认null)

5.断线重连

本sdk支持,当网络波动或者无网情况下,自动进入离线状态,当有网络时会自动重连。

也支持客户手动切换到离线状态,然后再重连(注意 重连只能是离线状态下进行重连,其他状态进行重连会报错)

方法原型

fun switchModel(isOffline: Boolean)

参数说明

参数

参数类型

说明

isOffline(必填)

Boolean

true:切换到离线模式false:进行重连到在线模式

示例代码

IXmovAvatar.get().switchModel(true) 

6.销毁

销毁sdk实例,断开连接 进行资源释放。虚拟人退出时调用

方法原型

  fun destroy()

示例代码

IXmovAvatar.get().destroy()

7.设置行走配置

在初始化成功后重新设置初始点位

方法原型

fun changeWalkConfig(walkConfig: WalkConfig)

示例代码

val walkConfig = WalkConfig().apply { 
initPoint = -1000f
walkPoints.apply {
put("A", -1000.0f)
put("B", -800.0f)
put("C", -600.0f)
put("D", -400.0f)
put("E", -200.0f)
put("F", 0.0f)
put("G", 200.0f)
put("H", 400.0f)
put("I", 600.0f)
put("J", 800.0f)
put("K", 1000.0f)
}
}
IXmovAvatar.newInstance().changeWalkConfig(walkConfig)

8.获取数字人X偏移量

在行走过程中可以用来获取当前数字人的X偏移量,单位px

方法原型

fun getGlViewOffsetX(): Float

9.日志开关

在调试阶段可以打开日志,方便分析问题,应用发布时可关闭日志,提升性能,默认是打开日志的

关闭日志方法原型

fun hideDebugInfo()

示例代码

IXmovAvatar.get().hideDebugInfo()

打开日志方法原型

fun showDebugInfo()

示例代码

IXmovAvatar.get().showDebugInfo()

三.虚拟人状态

虚拟人常用的一下动作状态切换

1.倾听

代码示例

IXmovAvatar.get().listen()

2.思考

代码示例

IXmovAvatar.get().think()

3.打断

代码示例

IXmovAvatar.get().interrupt()

四.返回码

该返回码为虚拟人SDK自身的返回码,具体错误在碰到之后查阅

主要用于onInitEvent、onReconnectEvent、onSDKRuntimeError回调

返回码

返回码描述

0

成功

1000

进入房间失败(包含服务端接口返回的报错,json解析报错)

1001

正在初始化中,请稍后再试(仅在onInitEvent回调中)

1002

视频帧渲染超时(仅在onSDKRuntimeError回调中)

1003

socket连接退出 (仅在onSDKRuntimeError回调中)

1004

断开socket连接

1005

同步时间帧发生错误

1006

加载charbin失败 (仅在onSDKRuntimeError回调中)

1007

服务升级

1008

暂无可用房间

1009

渲染失败(仅在onInitEvent回调中)

2000

在未成功初始化时执行其他状态操作 (仅在onMessage回调中)

3000

sdk 未在离线状态下进行重连 (仅在onReconnectEvent回调中)