磐曦2D&3D数字人运行时SDK

更新时间:2025-03-26 09:41:35

运行时sdk主要包含互动C端业务逻辑,整体交互如下:

image.png

一、服务端对接

依赖

<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>intelligentcreation20240313</artifactId>
  <version>2.11.0</version>
</dependency>

api:SendSdkMessage

{
  "moduleName":"",  // 透传sdk参数
  "operationName":"", // 示例:getProject,透传sdk参数
  "data":"",  // sdk传过来的数据,透传给阿里云服务即可
  "userId":"" // 当需要根据c端用户做具体权限校验时用到
}
{
  "requestId":"",
  "data":"", // 数据返回透传回sdk即可
  "success":true,
  "errorMessage":"",
  "errorCode":""
}

代码示例

@RestController
@RequestMapping("/testApi")
public class TestApi {

    public TestApi() throws Exception {}

    String url = "intelligentcreation.cn-zhangjiakou.aliyuncs.com";

    /**
     * 初始化配置
     */
    Config config = new Config().setAccessKeyId("xxx")
            .setAccessKeySecret("xxx")
            .setEndpoint(url);

    /**
     * 创建客户端
      */
    Client client = new Client(config);

    @PostMapping("/send")
    public String send(@RequestBody SendParam param) throws Exception {
        Gson gson = new Gson();
        System.out.println(param.getMessage());
        //String message = "{\"moduleName\":\"avatar\",\"operationName\":\"getProject\",\"data\":\"834372344431362048\",\"userId\":\"123456\"}";

        Map<String, Object> map = gson.fromJson(param.getMessage(), new TypeToken<Map<String, Object>>() {}.getType());

        SendSdkMessageRequest request = SendSdkMessageRequest.build(map);
        // 请求接口
        SendSdkMessageResponse response = client.sendSdkMessage(request);
        if (response.getStatusCode().equals(200)) {
            System.out.println("sendSdkMessage 请求成功");
            System.out.println(gson.toJson(response));
            System.out.println(gson.toJson(response.getHeaders()));
            System.out.println(gson.toJson(response.getBody()));
            Gson gson2 = new Gson();
            return gson2.toJson(response.getBody());
        } else {
            return response.getBody().toString();
        }
    }
}

二、前端对接

1. 安装

安装前置依赖

npm i @alifd/next @b-design/fusion moment react react-dom --save

html 模板中引入组件库 css 依赖

<link href="//gw.alipayobjects.com/os/lib/alifd/next/1.25.45/dist/next-noreset.var.css" rel="stylesheet" />
<link href="//gw.alipayobjects.com/os/lib/b-design/fusion/3.0.3/dist/index.css" rel="stylesheet" />

请使用 npm 包管理工具安装 SDK。

npm install @alicloud-panxi/dhuman-sdk --save

2. 快速接入

1. 引入 SDK

在 JavaScript 或 TypeScript 文件中使用 SDK:

import AIGCPreviewRuntimeSDK from '@alicloud-panxi/dhuman-sdk';

// 创建容器 DOM 元素
const container = document.getElementById('sdk-container') as HTMLElement;

// 配置 SDK 参数
const sdkOptions: SDKOptions = {
  // 服务端对接后,服务端会透出一个 api 接口,这个接口地址就是 apiPath
  apiPath: 'https://xxx.com/path/to/server',
  // 要渲染的容器dom节点
  container: container,
  // 项目 id
  projectId: 'your-project-id',
  // 场景类型
  type: '2d',
};

// 初始化并渲染 SDK 实例
const sdkInstance = new AIGCPreviewRuntimeSDK(sdkOptions);

// 当不再需要时,可以调用 destroy 方法来销毁 SDK
sdkInstance.destroy();

除了上述必要参数,SDK 支持更灵活的配置,全量示例如下:

import AIGCPreviewRuntimeSDK from '@alicloud-panxi/dhuman-sdk';

// 创建容器 DOM 元素
const container = document.getElementById('sdk-container') as HTMLElement;

// 配置 SDK 参数
const sdkOptions: SDKOptions = {
  // 服务端对接后,服务端会透出一个 api 接口,这个接口地址就是 apiPath
  apiPath: 'https://xxx.com/path/to/server',
  // 要渲染的容器dom节点
  container: container,
  // 项目 id
  projectId: 'your-project-id',
  // 场景类型
  type: '2d',
  // 自定义参数 - 按需
  options: {
    topPane: {
      isHideTitle: false,
      isHideCloseButton: false,
      isHideCountDown: true,
      ComponentView: {
        CustomInteractSwitch: MyCustomInteractSwitch,
      },
    },
    chatPane: {
      useTextOnly: true,
      useAudioOnly: false,
      ComponentView: {
        CustomChatInput: MyCustomChatInput,
        CustomAudioInput: MyCustomAudioInput,
        CustomMessageList: MyCustomMessageList,
      },
    },
    hooks: {
      chat: {
        useCustomModelWithCompleteInput: async (question) => {
          console.log('Processing question:', question);
          // 在自定义服务中处理问题
          const responseText = await externalService(question);

          return {
            TotalResponse: {
              content: responseText,
              messageId: 'unique-id',
              finish: true,
            },
            processAudioStream: (callback) => {
              // 如果需要处理音频数据块,可以在这里实现逻辑。
              const audioChunks = mockAudioChunks(responseText);
              audioChunks.forEach((chunk, index) => {
                const isEnd = index === audioChunks.length - 1;
                callback(chunk, isEnd);
              });
            },
          };
        },
      },
      audio: {
        useCustomModelWithCompleteInput: async (question) => {
          console.log('Processing audio question:', question);
          const responseText = await externalService(question);

          return {
            TotalResponse: {
              content: responseText,
              messageId: 'unique-id',
              finish: true,
            },
            processAudioStream: (callback) => {
              const audioChunks = createAudioChunks(responseText);
              audioChunks.forEach((chunk, index) => {
                const isEnd = index === audioChunks.length - 1;
                callback(chunk, isEnd);
              });
            },
          };
        },
        useCustomModelWithStreamASRInput: async (asrResult) => {
          console.log('ASR result:', asrResult);
          const processedText = await externalService(asrResult);

          const messageId = 'streaming-text-response-id';
          return {
            processTextStream: (callback) => {
              const textChunks = [
                { content: '这是第一部分', messageId, finish: false },
                { content: '继续第二部分', messageId, finish: false },
                { content: '最后的结尾', messageId, finish: true },
              ];
              textChunks.forEach((chunk, index) => {
                const isEnd = chunk.finish;
                callback(chunk, isEnd);
              });
            },
          };
        },
      },
      asr: {
        useAudioData: async ({ audio, taskStatus, taskId }) => {
          if (taskStatus === 'taskStart') {
            console.log('Task started');
            return {
              processASRStream: (callback) => {
                callback(
                  {
                    header: { name: 'TranscriptionStarted', task_id: taskId.current },
                    payload: {},
                  },
                  false
                );
              },
            };
          }
          if (taskStatus === 'taskEnd') {
            console.log('Task ended');
            return {
              processASRStream: (callback) => {
                callback(
                  {
                    header: { name: 'TranscriptionCompleted', task_id: taskId.current },
                    payload: {},
                  },
                  true
                );
              },
            };
          }

          // 默认返回
          return {
            processASRStream: (callback) => {
              callback(
                {
                  header: { name: 'TranscriptionResultChanged', task_id: taskId.current },
                  payload: { result: '动态的识别结果' },
                },
                false
              );
            },
          };
        },
      },
    },
  },
  onJoinChannel: ({ success }) => {
    console.log('Join channel success:', success);
  },
  onError: (error) => {
    console.error('Error occurred:', error);
  },
  onStart: () => {
    console.log('SDK started');
  },
  onEnd: () => {
    console.log('SDK ended');
  },
};

// 初始化并渲染 SDK 实例
const sdkInstance = new AIGCPreviewRuntimeSDK(sdkOptions);

// 当不再需要时,可以调用 destroy 方法来销毁 SDK
sdkInstance.destroy();

2. 参数说明

参数名

描述

类型

是否必填

默认值

apiPath

后台服务端 API 接口地址

string

-

apiPathOptions

apiPath 接口请求的配置(如 timeout,headers,method,withCredentials, customRequestData 等)

Record<string, any>

-

container

要渲染的容器 DOM 节点

HTMLElement

-

projectId

项目标识 ID

string

-

type

渲染的类型,可选值有 '2d', 'hyperrealism', 等

string

'2d'

options

UI 自定义配置和处理钩子,详见下文

object

-

onJoinChannel

加入频道成功后的回调函数,返回一个对象包含 success 状态

function

-

onError

出错时的回调函数

function

-

onStart

SDK 启动成功后的回调函数

function

-

onEnd

SDK 结束时的回调函数

function

-

3. 方法说明

参数名

描述

类型

是否必填

默认值

destroy

销毁当前实例

function

-

speak

(仅 3D)主动播报一段语音,speak(text, { onStart,onEnd })

function

-

stopSpeak

(仅 3D)停止播报当前语音

function

-

createSpeakStream

(仅 3D)播放文本流 x=createSpeakStream({ onStart,onEnd });x.next('text');x.last('text')

function

-

4. Options 配置

options 对象允许自定义 SDK 的 UI 组件和功能钩子,支持以下自定义配置:

  • TopPaneConfig: 定制顶部面板的外观和功能。

参数名

描述

类型

是否必填

默认值

isHideTitle

是否隐藏标题

boolean

false

isHideCloseButton

是否隐藏关闭按钮

boolean

false

isHideCountDown

是否隐藏倒计时

boolean

false

ComponentView

自定义顶部面板的组件,比如 CustomInteractSwitch(交互切换按钮)。

react/vue component

-

  • ChatPaneConfig: 定制聊天面板的外观和功能。

参数名

描述

类型

是否必填

默认值

useTextOnly

仅使用文字输入

boolean

false

useAudioOnly

仅使用音频输入

boolean

false

ComponentView

自定义聊天组件,例如 CustomChatInput(聊天输入框)、CustomAudioInput(音频输入框)、CustomMessageList(消息列表)

boolean

false

  • Hooks: 用于自定义交互逻辑。

chat

- **`useCustomModelWithCompleteInput`**

  - **类型**: `(question: string) => Promise<CustomModelResponse>`
  - **描述**: 文字输入场景使用,用户可以通过 hook 入参获取用户当前输入的对话内容,用户侧自由调用服务,按照 `CustomModelResponse` 定义返回处理结果,交由前端 SDK 进行渲染。
  - **示例**:

- **`getUserInput`**

  - **类型**: `(question: string) => void`
  - **描述**: 文字输入场景使用,用户可以通过 hook 入参获取用户当前输入的对话内容。
  - **示例**:

    ```typescript
    hooks: {
      chat: {
        getUserInput: async (question) => {
          console.log('Processing question:', question);
        };
      }
    }
    ```

audio

  • useCustomModelWithCompleteInput

    • 类型: (question: string) => Promise<CustomModelResponse>

    • 描述: 语音输入场景使用,用户可以通过 hook 入参获取用户语音输入完整的 ASR 识别结果,用户侧自由调用服务,按照 CustomModelResponse 定义返回处理结果,交由前端 SDK 进行渲染。

    • 示例:

hooks: {
  audio: {
    useCustomModelWithCompleteInput: async (question) => {
      console.log('Processing audio question:', question);
      const responseText = await externalService(question);

      return {
        TotalResponse: {
          content: responseText,
          messageId: 'audio-message-id',
          finish: true
        },
        processAudioStream: (callback) => {
          const audioChunks = createAudioChunks(responseText);
          audioChunks.forEach((chunk, index) => {
            const isEnd = index === audioChunks.length - 1;
            callback(chunk, isEnd);
          });
        },
      };
    },
  }
}
  • useCustomModelWithStreamASRInput

    • 类型: (asrResult: string) => Promise<CustomModelResponse>

    • 描述: 语音输入场景使用,用户可以通过 hook 入参获取用户语音输入流式的 ASR 识别结果,用户侧自由调用服务,按照 CustomModelResponse 定义返回处理结果,交由前端 SDK 进行渲染。

    • 示例:

hooks: {
  audio: {
    useCustomModelWithStreamASRInput: async (asrResult) => {
      console.log('ASR result:', asrResult);
      const processedText = await externalService(asrResult);

      return {
        processTextStream: (callback) => {
          const textChunks = [
            { content: '流式文本部分1', messageId: 'stream-id', finish: false },
            { content: '流式文本部分2', messageId: 'stream-id', finish: true },
          ];
          textChunks.forEach((chunk) => {
            callback(chunk, chunk.finish);
          });
        },
      };
    };
  }
}
  • getASRResultInStream

    • 类型: (asrResult: string) => void

    • 描述: 语音输入场景使用,用户可以通过 hook 入参获取用户语音输入流式的 ASR 识别结果。

  • getASRResultInTotal

    • 类型: (asrResult: string) => void

    • 描述: 语音输入场景使用,用户可以通过 hook 入参获取用户语音输入完整的 ASR 识别结果。

asr

  • useAudioData

    • 类型: ({ audio, taskStatus, taskId }) => Promise<CustomASRModelResponse>

    • 描述: 用户自定义 ASR 服务使用,用户可以通过 hook 入参获取用户输入语音的二进制数据、当前语音识别任务的状态('taskStart':任务开始,'taskRecording':任务进行中,'taskEnd':任务结束)、任务 ID(当前语音识别任务的标识,一段语音识别为一个任务),用户侧自由调用服务,按照 CustomASRModelResponse 定义返回处理结果,交由前端 SDK 进行渲染。

    • 示例:

hooks: {
  asr: {
    useAudioData: async ({ audio, taskStatus, taskId }) => {
      if (taskStatus === 'taskStart') {
        console.log('任务开始');
        return {
          processASRStream: (callback) => {
            callback(
              {
                header: { name: 'TranscriptionStarted', task_id: taskId.current },
                payload: {},
              },
              false
            );
          },
        };
      }

      if (taskStatus === 'taskEnd') {
        console.log('任务结束');
        return {
          processASRStream: (callback) => {
            callback(
              {
                header: { name: 'TranscriptionCompleted', task_id: taskId.current },
                payload: {},
              },
              true
            );
          },
        };
      }

      // 处理中状态
      return {
        processASRStream: (callback) => {
          callback(
            {
              header: { name: 'TranscriptionResultChanged', task_id: taskId.current },
              payload: { result: '流动态识别结果' },
            },
            false
          );
        };
      };
    };
  }
}

CustomModelResponse

  • 类型: 自定义大模型 hooks 返回类型

  • 描述: 包含大模型的完整文字回复、流式音频回复和流式文字回复

interface IModelMessage {
  content: string; // 大模型完整回复
  messageId: string; // uuid
  finish: boolean; // 全量返回的时候直接传 true
  relatedImages?: string[]; // 相关图片资源
  relatedVideos?: string[]; // 相关视频资源
}

interface CustomModelResponse {
  TotalResponse?: IModelMessage;
  processAudioStream?: (callback: (audioChunk: ArrayBuffer, isEnd: boolean) => void) => void;
  processTextStream?: (callback: (textChunk: IModelMessage, isEnd: boolean) => void) => void;
}

CustomASRModelResponse

  • 类型: 自定义 ASR hooks 返回类型

  • 描述: 包含 ASR 完整识别结果和流式识别结果。持续收音交互模式只支持 processASRStream,不支持 totalASRResult

interface IASRMessage {
  header: {
    name: 'TranscriptionStarted' | 'SentenceBegin' | 'TranscriptionResultChanged' | 'SentenceEnd' | 'TranscriptionCompleted';
    task_id: string;
  };
  payload: {
    result?: string;
  };
}

interface CustomASRModelResponse {
  totalASRResult?: string; // 完整返回识别结果
  processASRStream?: (callback: (asrChunk: IASRMessage, isEnd: boolean) => void) => void; // 流式返回识别结果
}

5. 版本更新

对于最新的版本更改日志,请参阅 changelog.md 文件。


通过 AIGC Preview Runtime SDK,您可以灵活定制 avatars 的预览会话并集成到现有系统中。请根据具体需求调整 options 设置,以实现符合您期望的 UI 和功能。通过 hooks,您可以在 SDK 执行关键逻辑时插入自定义处理,应用扩展和业务集成更加灵活与高效。

三、常见问题

1、界面上报:预览已停止

  • 数字人有线路的概念,预览与发布使用的是不同的线路,参见【3参数说明】的type字段。

  • 如果仅发布,需要给type传参prod;如果不传type

  • 本页导读 (0)
  • 一、服务端对接
  • 依赖
  • api:SendSdkMessage
  • 代码示例
  • 二、前端对接
  • 1. 安装
  • 2. 快速接入
  • 1. 引入 SDK
  • 2. 参数说明
  • 3. 方法说明
  • 4. Options 配置
  • 5. 版本更新
  • 三、常见问题
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等