照片数字人交互SDK-H5版
1. SDK运行原理
1.1. 使用流程
1、形象定制:服务端调用数字人开放平台“形象定制-照片数字人”接口,上传人像照片获取形象包文件。形象定制参考照片数字人形象定制接口文档,已生成形象包需要通过SDK驱动使用,不可单独使用。
2、SDK调用:本文档为端渲染交互组件-照片数字人SDK文档,客户端或页面集成集成SDK加载形象包,本地驱动渲染数字人。支持音频和文本驱动。音频可以使用真人音频或自行接入的第三方TTS的音频。文本驱动SDK 内部会调用数字人开放平台 TTS 服务驱动数字人。
1.2 购买入口
2. 接入方法
2.1 安装依赖包
npm i @bddh/starling-dh-picture-client
或yarn add @bddh/starling-dh-picture-client
SDK 包不定期进行升级修复边缘 case(截止至 2024.10.18, 最新版本为1.0.29),如遇问题,请先更新sdk 包版本
2.2 代码中使用
import PictureHuman from '@bddh/starling-dh-picture-client';
const instance = new PictureHuman({
modelUrl: '形象 zip 包',
licenseUrl: 'license的 url',
licenseKey: 'license 的 key',
statusCallback: (status: object) => console.info(JSON.stringify(status)),
canvasId: '#canvas-pic' // 跟下文的 id一致,添加#
});
return (
<canvas id="canvas-pic"></canvas>
)
3.SDK 兼容性列表
支持主流浏览器,详细兼容见下表
端\浏览器 | Chrome | Edge | Safari | Opera | UC | 百度(手百) | Firefox | IE | |
---|---|---|---|---|---|---|---|---|---|
移动端-安卓 | 123+ | —— | —— | —— | 15.5+ | 13.52+ | —— | —— | 14.9+ |
移动端-iOS | 126 | —— | 13.3.1+ | —— | 16.6.0 | 13.60 | —— | —— | 15.2 |
PC端-Mac | 108+ | —— | 14.1.1+ | 111 | —— | —— | 116+ | 不兼容 | 5.0.4 |
PC端-Windows | 108+ | 126 | —— | 111 | —— | —— | 115+ | 不兼容 | 12.6 |
支持机型信息:
- 安卓:最低支持安卓10 CPU骁龙730G/骁龙855/联发科天玑900/天玑820(同等性能的芯片)及以上
- iOS : 最低支持iPhonexs 系统版本13.3以及以上。
包大小和相关时延
SDK大小 | 12.4M + CDN引擎资源包4.3MB |
---|---|
自定义人像包大小 | 6MB左右 |
音频驱动时延 | 100ms 左右 |
文本驱动时延 | 0.3s~1.5s(跟第一个标点前文字数量相关) |
4.demo 使用
4.1 demo说明
此demo分别使用react,vue两种框架。
针对如何发送消息驱动数字人, 发送流式音频驱动数字人,以及数字人的打断,状态的检测,给予了相应的实现
其中文本驱动的 token需要自行生产生成
4.2 demo下载
React版本,下载地址https://sdk-demo.bj.bcebos.com/picture-human-client-react-demo.zip
Vue版本,下载地址https://sdk-demo.bj.bcebos.com/picture-human-client-vue-demo.zip
4.3 demo运行
- 命令行执行yarn,安装所需依赖包 (根据提示使用对应的 node 版本)
- 命令行执行npm run dev,启动项目
- 将控制台输出的ip地址,复制到浏览器地址栏进行项目预览(目前cors只可使用 localhost:8080进行预览)
5. 初始化配置
参数 | 必填 | 类型 | 含义 |
---|---|---|---|
modelUrl | 是 | string | 模型包地址 |
licenseUrl | 是 | string | 模型鉴权文件地址 |
licenseKey | 是 | string | 模型鉴权 key |
statusCallback | 否 | function | 返回 5.1的状态信息 |
5.1 状态消息
type | value | 含义 |
---|---|---|
status | { code: 0, value: 'PENDING', progress: number} | 模型加载中, progress为加载进度,值为 0-100 |
status | { code: 0 value: 'SUCCESS', progress: 100} | 模型加载完成 |
code | -- | 鉴权相关状态码, 枚举见 5.2 表 |
5.2 初始化错误码
code | 含义 |
---|---|
1 | license未初始化 |
2 | license数据解密失败 |
3 | license数据格式错误 |
4 | license-key(api-key)校验错误 |
5 | 算法ID校验错误 |
6 | MD5校验错误 |
7 | 设备ID校验错误 |
8 | 域名校验错误 |
9 | 过期时间不正确 |
10 | 功能未授权 |
11 | 授权已过期 |
12 | 本地⽂件读取失败 |
13 | 远程数据拉取失败 |
14 | 本地时间校验错误 |
1001 | 构造函数的ready属性不是函数 |
1002 | 构造函数的config属性不是对象 |
1003 | 构造函数的licenseKey属性不是字符串 |
1004 | 构造函数的license属性不是字符串 |
1005 | 多级嵌套iframe不被⽀持 |
1101 | 初始化webgl的上下⽂失败 |
1201 | replaceVisualizeBody⽅法的参数不合法 |
1301 | init⽅法的参数不合法 |
1401 | 构造函数的config属性不合法 |
1501 | 创建虚拟路径失败 |
1502 | 创建虚拟⽂件失败 |
1503 | 创建鉴权虚拟⽂件失败 |
1601 | 初始化模型失败 |
2001 | 无用户交互,无法自动播放音频 |
6.驱动与回调
6.1 音频驱动
instance.audioRender({
audioBuffer: 'arrryBuffer 格式的数据',
first: true,
last: true,
sample: 16000,
interrupted: true
finishListener: err => console.info('播报完成', err)
});
参数 | 必填 | 类型 | 默认值 | 含义 |
---|---|---|---|---|
audioBuffer | 是 | ArrayBuffer | - | 播报音频(必须是 PCM无损音频编码格式, MP3属于有损压缩,其数据不可驱动**) |
sample | 是 | 16000 | - | 音频数据的采样率, 目前只支持16K |
first | 否 | boolean | true | 流式音频驱动:第一条音频数据传first= true 完整音频驱动:first=true或不传 |
last | 否 | boolean | true | 流式音频驱动:最后一条音频数据传last= true 完整音频驱动:last=true或不传 |
interrupted | 否 | boolean | false | 音频驱动是否打断正在播报的内容 false: 不打断当前播报内容 true: 停止当前播报内容,直接播报驱动音频 |
finishListener | 否 | (err?: Error) => void | - | 驱动结束回调, 报错失败会通过该回调返回Error 参见6.4驱动错误 Error |
6.2 文本驱动
instance.textRender({
msg: {
token: '填写 appKey, appId 生成的鉴权 token',
text: '使用文本驱动数字人的播报文本',
tts: {
per: 5116,
spd: 5,
pit: 5,
vol: 5
},
interrupted: true
},
finishListener: err => console.info('播报完成', err)
});
参数 | 必填 | 类型 | 含义 |
---|---|---|---|
text | 是 | string | 播报文本, 支持在线 SSML(语音合成标记语言);不可包含& < >特殊字符 |
token | 是 | string | 鉴权 token鉴权参数生成 |
finishListener | 否 | (err?: Error) => void | 驱动结束回调,报错失败会通过该回调返回Error 参见6.4驱动错误 Error |
tts | 是 | { per: number | string; spd: number; pit: number; vol: number } | per 发音人,取值参考公共音色库; spd 语速 5是正常值,0-15的取值范围。越大语速越快,默认值5 (字面量需要是整数) pit 语调 5是正常值,0-15的取值范围,越大声音越尖,默认值5 (字面量需要是整数) vol 音量 5是正常值,0-15的取值范围,越大音量越大,默认值5 (字面量需要是整数) |
interrupted | 否(默认 false) | boolean | 音频驱动是否打断正在播报的内容 false: 不打断当前播报内容,需配合last字段使用 true: 停止当前播报内容,直接播报驱动音频 |
last | 否(默认 true) | boolean | 流式文本驱动: 最后一条文本数据传last= true 其余文本数据传last=false 完整音频驱动:last=true或不传 |
6.3 指令驱动
方法 | 返回值 | 使用方法 | 含义 |
---|---|---|---|
isPlay | boolean | humanInstance.isPlay() | 判断数字人是否正在播报 |
play | promise | await humanInstance.play() | 开始播报 |
isPause | boolean | humanInstance.isPause() | 判断数字人是否正在暂停 |
pause | promise | await humanInstance.pause() | 播报暂停 |
isStop | boolean | humanInstance.isStop() | 判断数字人已经播报完成 |
stop | promise | await humanInstance.stop() | 终止播报 |
finish | void | humanInstance.finish | 销毁数字人 |
6.4 驱动错误 Error: {code, message}
code | 含义 |
---|---|
1702 | 音频驱动数据,audioBuffer异常 |
1701 | sample,采样率设置非法 |
2001 | 无用户交互,无法自动播放音频 |
TTS_1003 | 鉴权信息已过期 |
TTS_1004 | 超出并发上限,不可使用 tts |
TTS_1005 | 鉴权信息不存在 |
TTS_1007 | 过期时间格式非法 |
TTS_1008 | 鉴权信息非法 |
TTS_1009 | App key非法 |
TTS_1010 | App token非法 |
TTS_4001 | 文本驱动时,模型加载未完成 |
7. 常见问题
7.1 浏览器置于后台播报停止
因为使用WebAssembly技术,程序运行会在浏览器置于后台或者标签页失活后自动停止,属于正常表现;
如需切换回页面,进行重播,可以设置时间监听,重新发送文本或音频驱动指令
7.2 js 和 license跨域cors报错
获取到的 zip 包和 license有两种处理方式来解决 cors报错;
- 上传到 cdn,为 cdn 设置 cors白名单
- 保证zip, license资源域名同 sdk集成的业务同域名。
7.3 音频使用 ArrayBuffer数据进行驱动,但是效果不好
sdk 照片数字人接受的音频数据必须是 pcm无损音频编码格式,需检测数据是否进行了压缩编码
如来源是音频 url,检测 url 后缀是否是 pcm。如是 mp3,m4a, wav等格式则不支持