移动端Android SDK

本文介绍了如何使用阿里云百炼大模型服务提供的实时多模交互移动端 Android SDK,包括SDK下载安装、关键接口及代码示例。

MultiModalDialog SDK是阿里云通义团队提供的支持音视频端到端多模实时交互的SDK。通过SDK对接通义大模型以及后端多种Agent,能够支持用户接入语音对话、天气、音乐、新闻等多种能力,并支持视频和图像的大模型对话能力。

多模态实时交互服务架构

多模态实时交互服务接入架构-通用-流程图

前提条件

  • 开通阿里云百炼实时多模交互应用,获取Workspace IDAPP IDAPI Key

  • 下载SDK和 Demo bailian-multi-modal-android-sdk-1.0.5.zip并配置必要的环境、依赖。

  • 导入示例代码,按照调用流程接入SDK。

  • 您可以直接运行压缩包中的 APK 测试程序,填入上方三个必要参数,即可进行测试。

SDK接入

交互数据链路说明

SDK支持WebsocketRTC 两个链路与服务端交互,多模交互支持AudioOnlyAudioAndVideo 两种模式:

  • 音频交互:推荐使用Websocket 连接,连接速度较快,性能要求较低。

    • WS 链路音频格式说明:

      • 上行:支持 pcm 和 opus 格式音频进行语音识别。

      • 下行:支持 pcm 和 mp3 音频流。

  • 音视频交互:仅支持RTC 传输方式连接进行交互,提供端到端的音视频多模交互能力。

    • RTC 链路音频格式说明:

      • 上行:支持 pcm 传入 SDK,传输采用 opus 格式。

      • 下行:支持从 SDK 获取 pcm,传输采用 opus 格式。

交互模式说明

SDK支持 Push2TalkTap2TalkDuplex(全双工)三种交互模式。

  • Push2Talk: 长按说话,抬起结束的收音方式。

  • Tap2Talk: 点击开始说话,自动判断用户说话结束的收音方式。

  • Duplex: 全双工交互,连接开始后支持任意时刻开始说话,支持语音打断。

调用说明

SDK及其调用Demo。

SDK引用

导入依赖库。

  • app/src/main/libs

    • convsdk-release_*.aar //阿里云VoiceChatSDK

    • multimodal_dialog_sdk.aar // 阿里云多模对话SDK

    • com.aliyun.aio:AliVCSDK_ARTC // 阿里云RTC SDK

  • 其他DemoAPP引入的依赖:

    参考app/build.gradle

    implementation libs.androidbootstrap
    implementation libs.okhttp
    implementation libs.okio //Android OKHttp3应用要增加一个收入IOokio包
    implementation libs.http.logging.interceptor
    implementation libs.core.ktx
    //导入视频云sdk
    implementation libs.alivcsdk.artc

关键参数

参数名称

是否必须

说明

url

String

请求的服务端地址。

Websocket链路地址:wss://dashscope.aliyuncs.com/api-ws/v1/inference

RTC链路地址:

https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation

api_key

String

百炼服务接入API Key 请您在百炼平台创建API_KEY,移动端为了安全考虑,您也可以在服务端接入短时Token,并下发给客户端使用。

workspace_id

String

百炼管控台,工作空间id。

app_id

String

您在管控台创建的应用id。

chain_mode

String

RTC/Websocket。

Demo简介

  • EntranceActivity 入口页面,需要修改url/api_key/app_id等信息。

    • 可以通过页面选择使用RTC或者Websocket请求链路。

    • 可以通过页面选择对话使用Tap2Talk或者Duplex等模式。

  • MultimodalDialogActivity,对话交互实现类。

    • Demo页面中引用TYAudioRecorder 作为录音输入,您可以替换为自己的实现。

    • Demo页面使用AudioPlayer作为音频播放输出,您可以选择使用自己的实现类。

    • Demo在音频交互模式下,支持VQA(图生文)功能,即通过语音说“拍照识别xxx”,触发服务下发拍照意图。之后:

      • 您可以将本地拍照并上传OSS(或其他内容服务生成公共链接),触发单张图片的识别和对话。

      • 您也可以直接上传图片的base64请求服务或者图片的对话结果。

    • DemoVideoAndAudio音视频交互模式下,目前通过外部采集的方式输入图像序列,方便眼镜等IoT设备的采集和视频对话接入。

接口设计

MultimodalDialog 对话入口类
  1. MultiModalDialog

    初始化对话类,传入必要的全局参数。

    /**
         * 初始化     
         * @param context: 上下文
         * @param url: 服务器地址
         * @param chainMode: 链路模式
         * @param workspaceId: 工作空间id
         * @param appId: 应用id
         * @param dialogMode: 对话模式
         * */
        fun MultiModalDialog(
            context: Context,
            url: String?,
            chainMode: ChainMode?,
            workspaceId: String?,
            appId: String?,
            dialogMode: DialogMode?
        )
  2. createConversation

    创建会话。

    /**
         * 初始化成功后,启动对话流程
         * @param params 初始化参数
         * @param chatCallback 主回调,除了初始化过程的所有消息,都会从这里透出给上层
         */
        fun createConversation(@NonNull MultiModalRequestParam params,chatCallback: IConversationCallback)
  3. start

    开始对话。

    /**
         * 连接,启动对话
         */
        fun start()
  4. stop

    结束对话。

    /**
         * 断开,结束对话
         */
        fun stop()
  5. destroy

        /**
         * 销毁实例
         */
        fun destroy()
  6. setConversationTimeout

    设置超时时间。

        /**
         * 设置对话超时时间,当服务未在指定时间内检出用户说话,上报timeout事件
         * @param timeout 超时时间,单位ms
         */
        fun setConversationTimeout(timeout: Long)
  7. interrupt

    打断交互。

        /**
         * 打断AI说话
         */
        fun interrupt()
  8. startSpeech

    通知服务端开始上传音频,注意需要在Listening状态才可以调用。只需要在Push2Talk模式下调用。

    /**
     * 通知服务端开始上传音频,注意需要在Listening状态才可以调用。
     * 只需要在Push2Talk模式下调用。
     */
    fun startSpeech()
  9. sendAudioData

    通知服务端上传音频。

    /**
     * 通知服务端上传音频。
     * @param audioData 音频帧数据
     */
    fun sendAudioData(audioData: ByteArray?)
  10. stopSpeech

    通知服务端结束上传音频。只需要在Push2Talk模式下调用。

    /**
     * 通知服务端结束上传音频。只需要在Push2Talk模式下调用。
     * Push2Talk 用户结束说话
     */
    fun stopSpeech()
  11. requestToRespond

    请求服务端回答指定问题orTTS播放出来。

    /**
         * 请求服务端回答指定问题orTTS播放出来
         * @param type: transcript 表示直接把文本转语音,prompt 表示把文本送大模型回答
         * @param text:对应的文本
         * @param params: 额外参数
         */
        fun requestToRespond(type: String, text: String, params: JSONObject)
  12. 其他接口。

        /**
         * 当前配置是否是全双工模式
         */
        fun isDuplexMode(): Boolean
    
        /**
         * Push2Talk 用户取消说话
         */
        fun cancelSpeech()
    
        /**
         * 发送语音回复结束
         * */
        fun sendResponseEnded()
        
        /**
         * 发送语音回复开始
         * */
        fun sendResponseStarted()
    
        /**
         * 推送视频帧
         *
         * @param videoFrame 视频帧
         * @param callback: 送帧结果回调
         */
        fun sendVideoFrame(videoFrame: TYVideoFrame,callback: IVideoChatPushFrameCallback)
    
    
        
关键参数枚举
参数

说明

ChainMode

Websocket

仅支持AudioOnly

RTC

支持AudioOnlyAudioAndVideo两种交互

DialogMode

TAP2TALK

手动开始,自动结束

PUSH2TALK

手动开始,手动结束

DUPLEX

全双工交互

MultiModalRequestParam 端云交互参数详情
Start - Input Message

请求开始会话消息。服务收到Start消息后,向客户端发送Started消息。

一级参数

二级参数

类型

是否必选

说明

task_group

string

任务组名称,固定为"aigc",请直接复制使用

task

string

任务名称,固定为"multimodal-generation",请直接复制使用

function

string

调用功能,固定为"generation",请直接复制使用

model

string

阿里云百炼模型名称,固定为"multimodal-dialog",请直接复制使用

input

directive

string

指令名称:Start

workspace_id

string

客户在阿里云百炼业务空间ID(Workspace ID),可在百炼管控台“业务空间详情”中查看,目前仅支持主账号默认工作空间

app_id

string

客户创建的应用ID(APP ID),可在多模态交互管控台“我的应用”页面查看

dialog_id

string

对话ID,默认不填时是开启新会话,服务端会自动生成并在事件中下发,格式示例:"12345678-1234-1234-1234-1234567890ab",共36个字符。当希望继续之前的对话时,把当时服务端下发的dialog_id在这里传入

parameters

upstream

object

参数说明参考下方 parameters.upstream的参数说明表格

downstream

object

参数说明参考下方 parameters.downstream的参数说明表格

client_info

object

参数说明参考下方 parameters.client_info的参数说明表格

biz_params

object

参数说明参考下方 parameters.biz_params的参数说明表格

parameters.upstream的参数说明如下

一级参数

类型

是否必选

说明

type

string

上行类型:

AudioOnly 仅语音通话

mode

string

客户端使用的模式,默认tap2talk。

可选项:

  • push2talk: 客户端控制模式。

  • tap2talk: 点击模式。

  • duplex: 双工模式。

三种模式的对比可以参考下方的客户端使用的三种模式对比表格。

audio_format

string

音频格式,支持pcm,opus,raw-opus,默认为pcm

注意:opus 和 raw-opus的区别是opus格式的每一包数据都需要额外加ogg封装(RFC 7845

sample_rate

int

语音识别的采样率,支持范围:

  • 8000

  • 16000

  • 24000

  • 48000

默认为16000

vocabulary_id

string

热词id,设置该参数时会覆盖管控台热词配置。当管控台提供的热词不能满足客户需求时,可以考虑用Open API程序化管理热词,参见热词API文档

parameters.downstream的参数说明如下:

一级参数

类型

是否必选

说明

voice

string

合成语音的音色,支持范围取决于用户在管控台选择的语音合成模型

sample_rate

int

合成语音的采样率,支持范围:

  • 8000

  • 16000

  • 24000

  • 48000

默认为24000。

通义千问-TTS、通义千问3-TTS模型仅支持24000。

audio_format

string

音频格式,支持pcm,opus,mp3,raw-opus,默认为pcm。

通义千问-TTS、通义千问3-TTS模型仅支持pcm。

注意:opus 和 raw-opus的区别是opus格式的每一包数据都有额外ogg封装(RFC 7845

frame_size

int

合成音频的帧大小,取值范围:

  • 10

  • 20

  • 40

  • 60

  • 100

  • 120

默认值为60,单位ms

只在合成音频格式为opusraw-opus时生效

volume

int

合成音频的音量,取值范围0-100,默认50

speech_rate

int

合成音频的语速,取值范围50-200,表示默认语速的50%-200%,默认100

pitch_rate

int

合成音频的声调,取值范围50-200,默认100

bit_rate

int

合成音频的比特率,取值范围:6~510kbps,默认值为32,单位kbps,只在合成音频格式为opusraw-opus时生效

intermediate_text

string

控制返回给用户哪些中间文本:

  • transcript:返回用户语音识别结果

  • dialog:返回对话系统回答中间结果

可以设置多种,以逗号分隔,默认为transcript

transmit_rate_limit

int

下发音频发送速率限制,单位:字节每秒

parameters.client_info的参数说明如下:

一级参数

二级参数

类型

是否必选

说明

user_id

string

终端用户ID,客户根据自己业务规则生成,用来针对不同终端用户实现定制化功能。最大长度40个字符。

device.uuid

uuid

string

客户端全局唯一的ID,需要用户自己生成,传入SDK。最大长度40个字符。

network

ip

string

调用方公网IP

location

latitude

string

调用方纬度信息,在需要客户端精确位置的业务场景提交

longitude

string

调用方经度信息,在需要客户端精确位置的业务场景提交

city_name

string

调用方所在城市,指明客户端粗略位置

parameters.biz_params的参数说明如下:

一级参数

类型

是否必选

说明

user_defined_params

json object

需要透传给agent的参数,各类agent传递的参数参考调用官方Agent文档说明

user_prompt_params

json object

用于设置用户自定义prompt变量,由用户自定义设置json中的keyvalue。管控台上配置自定义prompt变量的方法参考应用配置-提示词

user_query_params

json object

用于设置用户自定义对话变量,由用户自定义设置json中的keyvalue。管控台上配置自定义对话变量的方法参考应用配置-对话变量

客户端使用的三种模式对比:

对比项

push2talk

tap2talk

duplex

类型

客户端控制模式

点击模式

双工模式

音频上传方式

按需

持续

持续

VAD检测方

客户端

服务端

服务端

打断方式

RequestToSpeak消息打断

RequestToSpeak消息打断

语音打断

使用场景

由用户控制开始/结束客户端语音发送和识别,适用于按键说话,松开停止说话的场景。

客户端需持续上传音频,服务端自动检测语音活动的场景。但不支持用户语音打断大模型输出,只能发送RequestToSpeak打断消息。

客户端需持续上传音频,服务端自动检测语音活动的场景。用户随时可以说话打断大模型输出。

示例如下:

{
    "header": {
        "action":"run-task",
        "task_id": "9B32878********************3D053",
        "streaming":"duplex"
    },
    "payload": {
        "task_group":"aigc",
        "task":"multimodal-generation",
        "function":"generation",
        "model":"multimodal-dialog",
        "input":{
          "directive": "Start",
          "workspace_id": "llm-***********",
          "app_id": "****************"
        },
        "parameters":{
          "upstream":{
            "type": "AudioOnly",
            "mode": "duplex"
          },
          "downstream":{
            "voice": "longxiaochun_v2",
            "sample_rate": 24000
          },
          "client_info":{
            "user_id": "bin********207",
            "device":{
              "uuid": "432k*********k449"
            },
            "network":{
              "ip": "10.0.0.9"
            },
            "location":{
              "city_name": "北京市"
            }
          },
          "biz_params":{
            "user_defined_params": {
                "agent_id_xxxxx": {
                    "name": "value"
                }
            },
            "user_prompt_params": {
                "name": "value"
            },
            "user_query_params": {
                "name": "value"
            }
          }
        }
    }
}
IConversationCallback (回调接口)
    /**
     * 对话启动结果,鉴权、客户端加入通道成功后,会回调该消息
     */
    fun onStartResult(isSuccess: Boolean, errorInfo: TYError?)

    /**
     * 主动打断的回调,包括手动打断和语音打断
     */
    fun onInterruptResult(isSuccess: Boolean, errorInfo: TYError?)

    /**
     * 对话准备完成,多端(客户端/VoiceChat/视频理解)均加入通道后,会回调该消息,此时才能调用业务接口
     */
    fun onReadyToSpeech()

    /**
     * 状态切换回调
     * 包含DIALOG_IDLE,DIALOG_LISTENING,DIALOG_RESPONDING,DIALOG_THINKING
     */
    fun onConvStateChangedCallback(state: DialogState)

    /**
     * 音量强度回调
     * @param audioType 参考 {@link Constant.TYVolumeSourceType}
     * @param audioLevel 0-100
     */
    fun onConvSoundLevelCallback(audioLevel: Float, audioType: Constant.TYVolumeSourceType)

    /**
     * 超出用户有效输入超时时间的超时时间,收到此事件,用户需要重新启动或者结束对话
     * @param timeout 超时时间
     */
    fun onSpeechTimeout(timeout: Long)

    /**
     * 回路音频,用于客户端AEC回声消除
     * @param bytes 音频数据
     */
    fun onPlaybackAudioData(bytes: ByteArray)

    /**
     * 对话过程中的异常信息
     * @param errorInfo 异常信息
     */
    fun onErrorReceived(errorInfo: TYError)

    /**
     * 对话过程中的事件信息
     * @param errorInfo 事件信息
     */
    fun onConvEventCallback(var1: ConvEvent?)

    /**
     * 运行过程中回调关键日志信息给上层
     * @param level 日志级别,参考Android.Log
     * @param type 日志类型
     * @param debugInfo 日志信息
     */
    fun onDebugInfoTrack(level: Int, type: Constant.TYDebugInfoType, debugInfo: String)

onConvEventCallback AI对话 Response详情
  • EVENT_HUMAN_SPEAKING_DETAIL

    语音识别内容

    SpeechContent - response

    一级参数

    二级参数

    三级参数

    类型

    是否必选

    说明

    output

    event

    string

    事件名称:SpeechContent

    dialog_id

    string

    对话id

    text

    string

    用户语音识别出的文本,流式全量输出

    finished

    bool

    输出是否结束

    {
        "header": {
            "request_id": "9B32878******************3D053",
            "service_id": "368208df",
            "status_code": 200,
            "status_name": "Success",
            "status_message": "Success.",
            "attributes":{
              "user_id":"1234557879x"
            }
        },
        "payload": {
            "output":{
              "event": "SpeechContent",
              "dialog_id": "b39398c9dd8147********35cdea81f7",
              "text": "一二三",
              "finished": false
            },
            "usage":{
              "invoke":10,
              "model_x":10
            }
        }
    }
  • EVENT_RESPONDING_DETAIL

    大模型的返回文本

    output

    finished

    bool

    输出是否结束

    dialog_id

    string

    对话id

    event

    string

    消息类型

    text

    string

    LLM大模型返回的文本结果

    spoken

    string

    LLM大模型返回的播放内容的文本,可能跟 text 字段有所不同。

    extra_info

    object

    其他扩展信息,目前支持:

    commands: 命令字符串

    agent_info: 智能体信息

    tool_calls: 插件返回的信息

    dialog_debug: 对话debug信息

    timestamps: 链路中各节点时间戳

    示例:

    {
        "header": {
            "event":"result-generated",
            "task_id": "9B32878******************3D053"
        },
        "payload": {
            "output":{
              "event": "RequestAccepted",
              "dialog_id": "b39398c9dd8147********35cdea81f7",
              "text": "您输入了数字序列“12345”。如果您有关于这些数字的问题或者需要我用它们来完成某项任务,请告诉我更多的细节,我会尽力帮助您。",
              "spoken": "您输入了数字序列“12345”。如果您有关于这些数字的问题或者需要我用它们来完成某项任务,请告诉我更多的细节,我会尽力帮助您。",
              "finished": true,
            "extra_info": {
              "commands": "[{\"name\":\"VOLUME_SET\",\"params\":[{\"name\":\"series\",\"normValue\":\"70\",\"value\":\"70\"}]}]",
              "tool_result": [{
                "id": "",
                "type": "function",
                "function": {
                  "name": "function_name",
                  "arguments": "{\"id\": \"123\", \"name\": \"test\"}",
                  "outputs": "函数调用结果",
                  "status": {
                    "code": 200,
                    "message": "Success."
                  }
                }
              }]
            }
            },
            "usage":{
              "invoke":10,
              "model_x":10
            }
        }
    }

异常处理

onErrorReceived - response

通用错误码

如遇报错问题,请参见多模态交互套件-错误码进行排查。

若问题仍未解决,请联系技术支持,反馈遇到的问题,并提供完整的request_iddialog_id,以便进一步排查问题。

RTC连接错误码

错误码

错误名称

说明

1001

ERROR_CODE_AUTH_FAILED

RTC鉴权错误

1002

ERROR_CODE_JOIN_CHANNEL_FAILED

RTC加入channel出错

1003

ERROR_CODE_NETWORK_DISCONNECT

RTC网络断连

1004

ERROR_CODE_CHANNEL_ERROR

RTC连接错误

调用时序

全双工交互

image

半双工交互

image

更多SDK接口使用说明

双工交互

移动端Android SDK支持Duplex 双工交互模式。 在双工交互模式下,SDK支持在播放语音合成回复的同时,输入录音数据。当用户在此时说话时,服务会自动打断当前播报数据返回 (客户端播放器缓存需要应用层处理),并开始新的回复。

双工交互需要实现回声消除(AEC,Acoustic Echo Cancellation),Android SDK内置了回声消除算法。当您需要使用双工交互时,仍需要您进行必要的配置。

  • 输入麦克风录音音频

请将实时录音获取的音频数据通过如下接口传入SDK。

multiModalDialog.sendAudioData(data);
  • 输入参考通道音频

请将实时播放的音频数据通过如下接口传入SDK。注意传入数据需要保证与当前播放数据一致。

multiModalDialog.sendRefData(data);

VQA交互

VQA 是在对话过程中通过发送图片实现图片+语音的多模交互的功能。

核心过程是语音或者文本请求拍照意图触发"visual_qa"拍照指令。

当客户端通过回调函数onConvEventCallback收到拍照指令后, 发送图片链接或者base64数据(支持小于180KB的图片)。

  • 处理"visual_qa" command和上传拍照。

private void executeCmd(String cmd,String dialogId,String taskId){
  String cmdName = null;
  String cmdParamValue = null;
  try {
    cmdName = new JSONArray(cmd).getJSONObject(0).getString("name");
  }catch (Exception ex) {
    ex.printStackTrace();
  }
  switch (cmdName){
     case "visual_qa":
       JSONObject extraObject = new JSONObject();
       extraObject.put("images", imagesArray);
       multimodalConversation.requestToRespond(type, text, extraObject.toString());
       break:
  ......
}

//上传拍照
public static JSONArray getMockOSSImage() {
    JSONObject imageObject = new JSONObject();
    JSONArray images = new JSONArray();
    try{
      if (vqaUseUrl){
        imageObject.put("type", "url");
        imageObject.put("value", "https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/7043267371/p909896.png");
      }else {
        imageObject.put("type", "base64");
        imageObject.put("value", getLocalImageBase64());
      }
      images.put(imageObject);

    }catch (Exception e){
      e.printStackTrace();
    }
    return images;
  }

通过 RTC 链路请求LiveAI

LiveAI (视频通话)是百炼多模交互提供的官方Agent。通过Android 全功能版本SDK, 您可以在应用中实现视频通话的功能。 本 SDK 内置了 RTC 协议,实现音视频双工的实时交互。

  • LiveAI调用时序

截屏2025-06-20 11

  • 关键代码示例

完整代码请参考 "前提条件" 章节下载的 Android Demo。

//1. 设置交互类型为AudioAndVideo
MultiModalRequestParam.UpStream.builder().mode("duplex").type("AudioAndVideo").build();

//2. 在建联后发送voicechat_video_channel 请求
private void startVideoMode() {
    if (isVideoMode) return;

    try {
        MultiModalRequestParam updateParams = MultiModalRequestParam.builder().build();
        JSONObject videoObj = new JSONObject();
        videoObj.put("action", "connect");
        videoObj.put("type", "voicechat_video_channel");

        List<JSONObject> videos = new ArrayList<>();
        videos.add(videoObj);

        updateParams.setBizParams(MultiModalRequestParam.BizParams.builder()
                .videos(videos).build());

        multiModalDialog.requestToRespond("prompt", "", updateParams.getParametersAsJson());
        multiModalDialog.setVideoContainer(videoContainer, uiHandler);

        isVideoMode = true;
        runOnUiThread(() -> videoContainer.setVisibility(View.VISIBLE));

    } catch (JSONException e) {
        Log.e(TAG, "启动视频模式失败", e);
    }
}

//3. 开始音视频交互。处理交互流程。注意 demo 中Constant.ChainMode.RTC 类型的处理。
private void handleOutputStarted() {
    if (!isRtcUseInternalAudio()) {
        audioPlayer.pause(true);
        audioPlayer.play();
    }
    if (authParams.getChainMode() == Constant.ChainMode.RTC) {
        //RTC 模式下,tts 合成数据速度为正常比例
        multiModalDialog.sendResponseStarted();
    }
}

private void handleOutputCompleted() {
    Log.d(TAG, "输出完成");
    if (authParams.getChainMode() != Constant.ChainMode.RTC) {
        multiModalDialog.sendResponseEnded();
        audioPlayer.isFinishSend(true);
    }
}

通过 Websocket 链路请求LiveAI

LiveAI (视频通话)是百炼多模交互提供的官方Agent。通过Android 全功能版本SDK, 您也可以在Websocket链路中通过自行录制视频帧的方式来调用视频通话功能。

注意:通过 Websocket 调用 LiveAI发送图片只支持base64编码,每张图片的大小在180K以下。

  • LiveAI调用时序

截屏2025-06-20 11

  • 关键代码示例

请注意参照如下的调用流程实现 通过Websocket 协议调用 LiveAI。

//1. 设置交互类型为AudioAndVideo
MultiModalRequestParam.UpStream.builder().mode("duplex").type("AudioAndVideo").build();

//2. 在建联后发送voicechat_video_channel 请求
private void startVideoMode() {
    if (isVideoMode) return;

    try {
        MultiModalRequestParam updateParams = MultiModalRequestParam.builder().build();
        JSONObject videoObj = new JSONObject();
        videoObj.put("action", "connect");
        videoObj.put("type", "voicechat_video_channel");

        List<JSONObject> videos = new ArrayList<>();
        videos.add(videoObj);

        updateParams.setBizParams(MultiModalRequestParam.BizParams.builder()
                .videos(videos).build());

        multiModalDialog.requestToRespond("prompt", "", updateParams.getParametersAsJson());
        multiModalDialog.setVideoContainer(videoContainer, uiHandler);

        isVideoMode = true;
        runOnUiThread(() -> videoContainer.setVisibility(View.VISIBLE));

    } catch (JSONException e) {
        Log.e(TAG, "启动视频模式失败", e);
    }
}

//3. 每 500ms 提交一张视频帧照片数据,注意图片尺寸小于 180KB。
/**
 * DEMO 流程未调用。演示在 websocket 链路中实现 liveAI
 * 启动视频帧流,每 500ms 发送一次图片帧
 */
private void startVideoFrameStreaming() {
    Thread videoStreamingThread = new Thread(() -> {
        try {
            while ( !Thread.currentThread().isInterrupted()) {
                Thread.sleep(500);

                JSONObject extraObject = new JSONObject();
                extraObject.put("images", getMockOSSImage());

                multiModalDialog.updateInfo(extraObject);
                }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    });

    videoStreamingThread.setDaemon(true);
    videoStreamingThread.setName("LiveAI-VideoStreaming");
    videoStreamingThread.start();

}

/**
 * build images list request
 * */
private static JSONArray getMockOSSImage() {
    JSONObject imageObject = new JSONObject();
    JSONArray images = new JSONArray();
    try{

        imageObject.put("type", "base64");
        imageObject.put("value", getLocalImageBase64());

        images.put(imageObject);

    }catch (Exception e){
        e.printStackTrace();
    }
    return images;
}

//read local image to base64
private static String getLocalImageBase64(){
    return "";
}

文本合成TTS

SDK支持通过文本直接请求服务端合成音频。

您需要在客户端处于Listening状态下发送requestToRespond请求。

若当前状态非Listening,需要先调用Interrupt 接口打断当前播报。

conversation.requestToRespond("transcript","幸福是一种技能,是你摒弃了外在多余欲望后的内心平和。",null);

自定义提示词变量和传值

  • 在管控台项目【提示词】配置自定义变量。

如下图示例,定义了一个user_name字段代表用户昵称。并将变量user_name以占位符形式${user_name} 插入到Prompt 中。

image.png

  • 在代码中设置变量。

如下示例,设置"user_name" = "大米"

//在请求参数构建中传入biz_params.user_prompt_params
HashMap<String, String> userPromptParams = new HashMap<>();
userPromptParams.put("user_name", "大米");
        MultiModalRequestParam.BizParams bizParams = MultiModalRequestParam.BizParams
                .builder()
                .userPromptParams(userPromptParams)
                .build();
  • 请求回复

image.png

ASR结果即时纠错

在对话过程中,ASR 识别结果有可能出现错误或者非预期的结果。 除了配置热词之外,您也可以通过即时纠错功能接口上传词表进行实时干预。

  • 参数说明:

通过配置UpStreamAsrPostProcessing 参数来配置纠错词表。

参数

一级参数

二级参数

类型

说明

AsrPostProcessing

Object

ASR 纠错词表

ReplaceWord[]

List

词表列表,每个ReplaceWord 对应一组词的替换规则

source

String

需要被替换的文本

target

String

替换目标文本

match_mode

String

匹配模式,默认为exact:

exact:整句精确匹配,只有文本与source完全相同才匹配成功

partial:部分匹配,文本中部分字符与source相同即匹配成功

//构建AsrPostProcessing对象
MultiModalRequestParam.UpStream.ReplaceWord replaceWord = new MultiModalRequestParam.UpStream.ReplaceWord();
    replaceWord.setTarget("一加一");
    replaceWord.setSource("1加1");
    replaceWord.setMatchMode("partial");
// 在创建对话请求时将asrPostProcessing 传入UpStream.AsrPostProcessing
.upStream(MultiModalRequestParam.UpStream.builder()
.asrPostProcessing(Collections.singletonList(replaceWord))
.build())