npm包版本
云端渲染SDK接入文档
1.接入方法
1.1 安装依赖包
npm i @bddh/starling-realtime-client
或yarn add @bddh/starling-realtime-client
1.2 代码中使用
1 import RealTimeHuman from'@bddh/starling-realtime-client';
2
3 const humanInstance = new RealTimeHuman({
4 token: '填写应用对应的token'
5 wrapperId: '挂载节点id',
6 connectParams: {
7 resolutionHeight: 1920,
8 resolutionWidth: 1080,
9 },
10 renderParams: {
11 autoChromaKey: false
12 },
13 onDigitalHumanCallback: data => console.log(data)
14 })
15 humanInstanceRef.createServer(); // 启动服务
2.使用Demo
2.1 demo说明
此demo分别使用react,vue两种框架。针对如何发送文本消息、音频消息驱动数字人,如何打断、静音、暂停数字人,如何监听消息的回调等问题,进行了代码实现。
2.2 demo下载
React版本,下载地址 https://meta-human-editor-prd.bj.bcebos.com/realtime-human-npm/digital-human-sdk-test-react-0210.zip
Vue版本,下载地址 https://meta-human-editor-prd.bj.bcebos.com/realtime-human-npm/digital-human-sdk-test-vue-0210.zip
截止至 2026.2.12,SDK包最新版本为 2.0.9。
2.3 demo运行和修改
- 解压后,进入目录:React版本目录名称:digital-human-sdk-test-react、Vue 版本目录名称:digital-human-sdk-test-vue
- 判断环境是否有 node(22 版本以上)和 yarn,如没有则进行 node, yarn 的安装: brew install node; npm install --global yarn (其他安装方式请自行搜索)
- 命令行执行 yarn,安装所需依赖包
- React版本命令行执行 npm run start,启动项目; vue版命令行执行 npm run dev,启动项目
- 将控制台输出的ip地址,复制到浏览器地址栏进行项目预览
- 在平台购买云渲染交互组件平台操作指南,新建应用关联组件,获取应用的appId和appkey,通过鉴权参数生成接口 生成token。替换 demo 文件中 token 参数,文件位置:React 版本是 src/Demo.tsx、Vue 版本是 /src/components/Demo.vue
- 在公共形象库中查找组件对应的人像类型的人像 id,替换 demo 文件中 figureId,文件位置:React 版本是 src/Demo.tsx、Vue 版本是 /src/components/Demo.vue
- 保存文件刷新页面,点击connect按钮可以看到数字人成功加载出来,可以点击播报按钮驱动数字人播报
3.sdk初始化参数
| 参数 | 类型 | 必填 | 默认 | 备注 |
|---|---|---|---|---|
| wrapperId | string | 是 | - | 数字人渲染挂载节点id |
| token | string | 是 | - | 应用管理对应的token |
| connectParams | object | 否 | - | 连接数字人所需参数配置 |
| renderParams | object | 否 | - | 数字人渲染所需的参数配置 |
| onDigitalHumanCallback | function | 是 | - | 数字人状态初监听函数,状态消息见4.状态消息 |
3.1 connectParams
| 参数 | 类型 | 默认 | 备注 |
|---|---|---|---|
| figureId | string | - | 查找文档公共形象库,填写对应figureId |
| resolutionWidth | string | 使用场景配置数据 | 视频分辨率宽,只能是偶数,分辨率最大不超过 1080x1920、1920x1080 |
| resolutionHeight | string | 使用场景配置数据 | 视频分辨率高,只能是偶数,分辨率最大不超过 1080x1920、1920x1080 |
| backgroundImageUrl | string | 场景设置的数值 | 设置数字人video背景图片,不支持直接配置颜色 ,autoChromaKey为 true 时不生效 |
| ttsPer | string | 人设设置的数值 | 音色id,要注意参数需要在平台存在,参考:公共音色库 |
| ttsPitch | number | 人设设置的数值 | 音调,5是正常值,0-15的取值范围,越大声音越尖,默认值5 (字面量需要是整数) |
| ttsSpeed | number | 人设设置的数值 | 语速,5是正常值,0-15的取值范围。越大语速越快,默认值5 (字面量需要是整数) |
| ttsVolume | number | 人设设置的数值 | 音量,5是正常值,0-15的取值范围,越大音量越大,默认值5 (字面量需要是整数) |
| inactiveDisconnectSec | int | 场景设置的数值 | 长时间无交互(交互指发送 text render 让数字人播报)的断连提醒,单位秒,0 表示不开启。达到阈值时,服务端会发送 TIMEOUT_EXIT 提醒消息,父页面在收到该消息时需销毁子页面,避免数字人渲染资源浪费,目前数字人后端服务不会主动断开。 |
| preAlertSec | int | 场景设置的数值 | 在开启长时间无交互断连提醒,且即将到达断连阈值时,后端会先发送一条 DISCONNECT_ALERT 预提醒消息,父页面收到消息可以弹窗提醒用户。该参数用于设置断连前多少秒发送该提醒,比如无交互超时参数 inactiveDisconnectSec 设置为 180(3 分钟),提醒参数 preAlertSec 设置为 10 (秒),则在用户最后一次交互后的 2 分 50 秒时会收到后端发送的 DISCONNECT_ALERT 提醒消息,在 3 分钟时收到 TIMEOUT_EXIT 断连消息。 |
| cameraId | int | - | 数字人预设机位 ID,控制数字人的位置和大小,建议使用和视频分辨率比例一致的机位:高精 2D 人像:0 (横屏半身)、1(竖屏半身)详细枚举参考3D数字人、2D数字人 |
| pickAudioMode | 'pressButton'或者'free' | - | 拾音模式,'pressButton'代表按键拾音,'free'代表持续拾音。补充:拾音功能目前只支持中英文、上海话、闽南语,四川、陕西、粤语的识别。 |
| pullAudioFromRtc | boolean | - | 拾音模式pickAudioMode为'pressButton'时需要填false,pickAudioMode为'free'时填true |
| asrDdc | boolean | true | 拾音是否开启语义顺滑。开启语义顺滑则会通过删除或修改ASR结果中的不流畅部分,如停顿词、语气词、语义重复词等,使得文本更加易于阅读和理解。 |
| asrPunc | boolean | true | 拾音是否开启自动标点 |
| asrItn | boolean | true | 拾音是否开启文本规范化,例如,“一九七零年”->“1970年” |
| asrSensitiveWord | boolean | true | 拾音是否开启敏感词过滤。使用自带的敏感词库,开启时ASR识别的文本会将敏感词变为*。 |
| asrBoostingTable | string | - | 拾音热词配置,可通过添加热词,提高该词的识别效果。词汇之间使用英文逗号分隔,例如,'拾音,实验'。 |
| asrVadPauseTime | int | 800 | ASR的断句停顿时间,用于切分句子。当静音时间超过该值时,会将文本分为两个句子。取值范围:200~5000,超过此范围不生效。 |
| enableInterrupt | boolean | true | 是否允许在拾音的时候打断播报。 |
| x264BitRate | int | - | 视频码率,详细解释请参考下方 |
不同分辨率对应的码率建议值:
| 分辨率 | 码率 |
|---|---|
| 720p(1280×720) | 低画质 / 弱网兜底:700–1,000 kbps |
| 推荐(清晰人脸 + 自然表情):1,200–2,500 kbps | |
| 高质量(细节多/复杂背景):2,500–3,500 kbps | |
| 1080p(1920×1080) | 低画质 / 弱网兜底:1,200–2,000 kbps |
| 推荐:2,000–4,000 kbps | |
| 高质量:4,000–6,000 kbps |
3.2 renderParams
| 参数 | 类型 | 默认 | 备注 |
|---|---|---|---|
| autoChromaKey | Boolean | false | 开启自动抠绿,实现数字人透明背景 |
| chromaEffects | Object | - | 自定义抠绿参数,使用时需将autoChromaKey设置为false;{version: 2, 'chromaKey': {'screen': [43, 185, 2], 'similarity': 90, 'edgeShrink': 3, 'smoothness': 80, 'spill': 100, 'opacity': 1, 'contrast': 0, 'brightness': 0, 'gamma': 0}}screen 为背景的rgb取色 |
| closeLog | Boolean | false | sdk侧控制台日志 |
| fullStatus | Boolean | false | 默认为false, 设置为true后,onDigitalHumanCallback回调会返回status为DH_LIB_FULL_STATUS的全量状态消息 |
4.状态消息{status, content}
| status | content | 备注 |
|---|---|---|
| DH_LIB_INIT | - | SDK启动准备中, ws status: -1 |
| DH_LIB_WS_SUCCESS | object | connect / pre-connect ws res信息 |
| DH_LIB_OPEN | - | 对应remotevideoon状态,数字人已出现 |
| DH_LIB_CLOSE | - | 对应remotevideooff状态,ws = 2 / 3状态 |
| DH_LIB_STATUS | msg信息见4.1 | |
| DH_LIB_ERROR | error信息见4.2 | 包含connect报错 |
| DH_LIB_MESSAGE | 信息详见4.5 | 数字人播报状态消息或ASR消息 |
| ASR_ERROR | - | ASR相关错误 |
| DH_LIB_FULL_STATUS | {type: rtcState/wsState,content: { action, body, readyState}} | 当renderParams设置为true时,抛出该回调信息 |
4.1 msg数据信息
content: {type, msg}
| type | msg | 备注 |
|---|---|---|
| DISCONNECT_ALERT | - | 长时间无交互提示 |
| TIMEOUT_EXIT | - | 超时退出消息 |
| LOCAL_VIDEO_MUTED | - | 首次加载无交互导致的video静音 |
4.2 error数据信息
content: {type, msg}
| type | msg | 备注 |
|---|---|---|
| CONNECT_ERROR | {code} | 数字人建连消息 |
| LOCAL_VIDEO_ERROR | - | 首次加载无交互导致的video播报暂停,部分iphone表现为无数字人 |
| RTC_ERROR | - | rtc连接错误 |
type为 CONNECT_ERROR 的 msg.code
| 错误码 | 错误信息 | 说明 |
|---|---|---|
| 1001 | 服务器内部错误 | |
| 1002 | APP已失效 | |
| 1003 | APP token已过期 | |
| 1004 | 目前线上用户较多,请您稍后再试 | app 会话路数已经达到上限 |
| 1005 | 授权信息不存在 | figureId未授权不可用 |
| 1009 | App key非法 | |
| 1011 | 裁剪参数非法 | 仅2D数字人存在 |
| 1012 | 参数不能为空 | |
| 1014 | 分辨率/编码参数不合法 | |
| 1015 | 无效的媒体信息 | 例如:传递的RTMP参数无效 |
| 1202 | 正在连接或已连接 | |
| 1204 | 解析请求失败 | |
| 1206 | 读取json失败 | |
| 2001 | Fail to establish | 建立渲染任务失败 |
| 3001 | 目前线上用户较多,请您稍后再试 | 系统渲染资源不足导致 |
| 4001 | 请先初始化数字人实例 | |
| 4002 | webSocket连接中 | 预连接进行中 |
4.3 rtcState数据信息
type为 rtcState 的 content 的 格式 {action, body}
| action | body | 备注 |
|---|---|---|
| success | true | rtc房间登录成功 |
| error | error | rtc房间登录失败 |
| remotevideoloading | - | 远端视频流开始加载 |
| remoteVideoConnected | - | 成功获取远端视频流(不受视频暂停影响) |
| remotevideoon | - | 远端视频流加载完毕 |
4.4 wsState数据信息
type为 wsState 的 content.readyState
| readyState | 状态 | 备注 |
|---|---|---|
| -1 | UNINSTANTIATED | 默认值:无状态 |
| 0 | CONNECTING | ws 连接中 |
| 1 | OPEN | ws 开启成功 |
| 2 | CLOSING | ws 关闭中 |
| 3 | CLOSED | ws 关闭 |
4.5 DH_LIB_MESSAGE数据信息
status为 DH_LIB_MESSAGE 的 content 格式{action, body, code, requestId, message}
| action | body | message |
|---|---|---|
| DOWN_SUBTITLE | 值为json字符串,包含{type,completed,content}。可用于字幕显示。 | null |
| EMPTY_ASR_RESULT | 值为null。ASR未识别到有意义的内容。 | null |
| ASR_ERROR | 值为null。ASR发生错误 | 展示错误信息 |
action为 DOWN_SUBTITLE 的 body 内容如下:
| 字段 | 类型 | 说明 |
|---|---|---|
| type | string | QUERY代表当前消息是拾音后ASR的结果;REPLY代表当前消息是文本驱动的内容 |
| content | string | QUERY或REPLY的文本内容 |
| completed | boolean | 消息为QUERY时,按键拾音下true代表当前消息的content是完整内容,持续拾音下true代表当前消息的content是一个完整的分句。消息为REPLY时,true代表当前消息的content是文本驱动的完整内容。 |
action为 ASR_ERROR 的 code 与对应 message 的内容如下:
| code | message |
|---|---|
| 45000001 | 请求参数无效,请检查 |
| 45000002 | 无效音频过多 |
| 45000003 | ASR包解析失败 |
| 45000081 | ASR服务等包超时 |
| 45000151 | ASR服务音频格式不正确 |
| 55000031 | ASR服务器繁忙 |
| 550xxxxx | ASR服务内部处理错误 |
5.数字人驱动
5.1 textRender整段文本驱动方式
1 const onCallbackMsg = (data) => {
2 // 打印回调消息
3 console.log(data);
4 }
5
6 // 发送消息
7 humanInstance.textRender({
8 // requestId: '可传入自定义唯一字符串',
9 body: '你好,这是我的开场白自我介绍,我是数字人',
10 onCallbackMsg
11 });
requestId说明:可自定义构造requestId进行驱动数字人,驱动的回调消息会沿用自定义构造的requestId。
body说明:
| body的可选值 | 备注 |
|---|---|
| 你好,我是数字人 | 播报内容 |
<interrupt></interrupt> |
打断当前数字人播报 |
<speak><say-as type="telephone">110</say-as></speak> |
指定读法的高级播报内容,支持SSML使用说明 |
<speak>开始说话<silence time="5s"></silence>停止5s后继续说话</speak> |
支持播报中停顿 |
<speak interruptible="false">这段话不允许打断这段话不允许打断这段话不允许打断</speak> |
播报不受打断的内容,后续textRender会在上句播报完成后开始播报,但仍可被interrupt标签打断 |
onCallbackMsg说明:data: {action: string, body: object}
| action | 内容数据 | 备注 |
|---|---|---|
| RENDER_START | - | 数字人收到驱动后,驱动开始 |
| FINISHED | - | 数字人完成驱动指令,驱动完成 |
| RENDER_ERROR | - | 文本驱动错误 |
| DOWN_SUBTITLE | body | 播报内容的字幕消息 |
| RENDER_INTERRUPTED | - | 数字人驱动被打断 |
5.2 textStreamRender流式文本驱动方式
1 const onCallbackMsg = (data) => {
2 // 打印回调消息
3 console.log(data);
4 }
5
6 const commandId = '当前流式驱动的唯一ID'
7
8 humanInstance.textStreamRender({
9 body: JSON.stringify({
10 first: true,
11 last: false,
12 text: '你好,这是我的开场白自我介绍,我是数字人'
13 }),
14 requestId: commandId,
15 onCallbackMsg // 第一条有回调
16 });
17
18 humanInstance.textStreamRender({
19 body: JSON.stringify({
20 first: false,
21 last: false,
22 text: '你好,这是我的开场白自我介绍,我是数字人'
23 }),
24 requestId: commandId
25 }
26
27 humanInstance.textStreamRender({
28 body: JSON.stringify({
29 first: false,
30 last: false,
31 text: '你好,这是我的开场白自我介绍,我是数字人'
32 }),
33 requestId: commandId
34 };
35
36 setTimeout(() => {
37 humanInstance.textStreamRender({
38 body: JSON.stringify({
39 first: false,
40 last: true,
41 text: '你好,这是我的开场白自我介绍,我是数字人'
42 }),
43 requestId: commandId
44 };
45 }, 500);
| 字段 | 备注 |
|---|---|
| body | text: string, (播报内容,) first: boolean, (第一个流式数据设置first为true, 其余设置为false) last: boolean (最后一个流式数据设置last为true, 其余设置为false) |
| onCallbackMsg | 仅需在first为true时进行填写,数字人驱动回调,详见5.1 |
| requestId | 流式文本驱动每一条需要传入生成的随机id, 一轮流式文本驱动需使用同一个requestId |
5.3 sendMessage原始驱动方式( 主要透传消息)
1 import {v4 as uuidV4} from 'uuid';
2 // data 格式类型
3 const body = '<interrupt></interrupt>' // '文本', 指令
4
5 const onCallbackMsg = (data) => {
6 // 打印回调消息
7 console.log(data);
8 }
9
10 // 发送消息
11 humanInstance.sendMessage({
12 requestId: uuidv4(),
13 action: 'TEXT_RENDER',
14 body,
15 clientTs: new Date().getTime()
16 }, onCallbackMsg);
17
18 humanInstance.sendMessage()
requestId说明:可自定义构造requestId进行驱动数字人,驱动的回调消息会沿用自定义构造的requestId。
action说明:可选值:TEXT_RENDER 等
5.4 audioStreamRender流式音频驱动方式
1 const onCallbackMsg = (data) => {
2 // 打印回调消息
3 console.log(data);
4 }
5 const commandId = '当前流式音频驱动的唯一ID'
6 // 发送消息
7 humanInstance.audioStreamRender({
8 requestId: commandId,
9 body: JSON.stringify({
10 first: true,
11 last: false,
12 audio: '音频数据1'
13 }),
14 onCallbackMsg
15 });
16
17
18 humanInstance.audioStreamRender({
19 requestId: commandId,
20 body: JSON.stringify({
21 first: false,
22 last: false,
23 audio: '音频数据2'
24 })
25 });
26
27 humanInstance.audioStreamRender({
28 requestId: commandId,
29 body: JSON.stringify({
30 first: false,
31 last: true,
32 audio: '音频数据3'
33 })
34 });
| 字段名 | 备注 |
|---|---|
| body | audio: base64String(注: 将pcm音频数据转换为base64格式) first: boolean, (第一个流式数据设置first为true, 其余设置为false) last: boolean (最后一个流式数据设置last为true, 其余设置为false) |
| onCallbackMsg | 数字人驱动回调,详见5.1 |
| requestId | 流式音频驱动每一条需要传入生成的随机id, 同一轮流式驱动需使用同一个requestId |
tip1:仅支持pcm数据,pcm数据大小 限制48K。转为base64字符串后大小不超过64K。
tip2:音频属性仅支持"16k"、"16bit" 和 "单声道"
5.5 其他驱动方法
| 方法名 | 返回值类型 | 备注 |
|---|---|---|
| createServer | void | 启动对话服务 |
| muteHuman | void | 静音数字人 |
| unMuteHuman | Promise | 解除静音数字人 |
| playHuman | Promise | 对停止数字人拉流,进行启动 |
| pauseHuman | void | 停止数字人拉流 |
| destroy | Promise | 数字人销毁方法 |
| interrupt | Promise | 打断数字人 |
6.两种集成方式对比
6.1 iframe集成方式
技术规格:
- 基于iframe嵌入远程页面
优势:
- 插入iframe+url快速接入
- 和集成方代码形成隔离,形成单独的进程进行数字人的渲染工作,防范因js单线程设计可能造成的渲染卡顿问题。
- 平台统一管理升级,零维护成本
适用场景:
- 静态展示类页面(如数字人介绍页、展厅屏幕)
- 快速验证、PoC 演示
- 对渲染样式要求低、仅需固定播报内容的场景
6.2 npm包集成方式
技术规格:
- 以 npm 包形式集成,直接运行在集成方工程中
- 可与集成方共享依赖与上下文
优势:
- 跨端兼容性更好,移动端点击播放不受限制
- 可控性强:直接通过 SDK 实例控制数字人
适用场景:
- 高交互场景(语音对话、流式文本驱动)
- 需要与业务 UI 深度融合的场景(按钮、表单、动画)
