Web SDK 2.0 接入指南
一、集成指南
#1. 兼容性说明
目前仅支持 XRTC 协议,兼容性请参照 xrtc web sdk 兼容性 https://voipconference.xfyun.cn/book/#/web/README?id=%e6%94%af%e6%8c%81%e7%9a%84%e5%b9%b3%e5%8f%b0
#2. 引入 SDK 库
①、复制 vms-web-sdk-2.0.0 文件夹到项目的 JS 第三方库(如 src/libs)目录下
②、因虚拟人相关服务不支持跨域,故本地开发和上线部署时,都需要配置代理,本地代理具体如下:
ReactJS版本:
'/vmss': {
target: 'http://vms.cn-huadong-1.xf-yun.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/vmss/, '')
}
VueJS版本:
'/vmss': {
target: 'http://vms.cn-huadong-1.xf-yun.com',
changeOrigin: true,
pathRewrite: {
'^/vmss':''
}
}
部署上线 nginx 配置代理可参照如下:
location ^~/vmss/ {
proxy_pass http://vms.cn-huadong-1.xf-yun.com/;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
}
其他方式代理,本意如上所示,形式不限,根据技术方案做具体调整即可_
③、在需要的页面引入 sdk js 文件:
//ES Module 方式引入
import VMS from '@/libs/vms-web-sdk/vms-web-sdk-2.0.0.esm.min';
//CommonJS 方式引入
const VMS = require('./libs/vms-web-sdk/vms-web-sdk-2.0.0.cjs.min');
//UMD 方式引入
const VMS = require('@/libs/vms-web-sdk/vms-web-sdk-2.0.0.min')
<script src='./libs/vms-web-sdk/vms-web-sdk-2.0.0.min'></script>
#二、接口使用及调用流程
#1. 启动
启动虚拟人服务
#1)接口
/**
* 启动虚拟人服务
* @param {{
* appId: string,
* apiKey: string,
* apiSecret: string,
* width: number, //虚拟人分辨率:宽度[1920 1280 720]
* height: number, //虚拟人分辨率:高度 [1080 720 405]
* avatarId: string, //形象ID
* streamDomId: string//虚拟人渲染Dom ID
* resId:string //上传的资源返回的res_id,用于设置背景
* isSsl:boolean //是否启用ssl(https)
* moveH: number //水平位移
* moveV: number //纵向位移
* scale: number //缩放
* maskRegion:string //裁切,如:'[0,154,1080,1472]'
* interactiveScene:string //交互场景
* templateId:string //模板id
* transparent:boolean //透明通道
* }} vmsConfig 虚拟人服务配置
*/
start(vmsConfig) {}
如上代码所示,SDK 初始化参数中vmsConfig
必填,其中appId、apiKey、apiSecret
和avatarId、streamDomId
为必填项。
如需设置背景或者开启后处理,请先上传资源,请参考 “7.上传个性化资源” 完成上传,再将得到的 res_id 传入 start 方法
#2)参数
参数 | 类型 | 必填 | 说明 | 默认值 |
---|---|---|---|---|
appID | String | 是 | 应用 ID | |
apiKey | String | 是 | 引擎托管平台创建应用后,生成的唯一应用标识 | |
apiSecret | String | 是 | 引擎托管平台创建应用后,生成的唯一应用秘钥 | |
streamDomId | String | 是 | 虚拟人视频流要渲染的 Dom Id | |
avatarId | String | 是 | 形象 ID | |
width | number | 否 | 宽度,可取 1920、1280、720 | 1920 |
height | number | 否 | 高度,可取 1080、720、405 | 1080 |
moveH | number | 否 | 水平位移 | |
moveV | number | 否 | 纵向位移 | |
scale | number | 否 | 缩放 | |
maskRegion | string | 否 | 裁切,如:'[0,154,1080,1472]' | |
resId | string | 否 | 背景资源 id,上传图片至个性化系统返回得到 | |
isSsl | boolean | 否 | 是否启用 ssl(https,wss) | 否 |
interactiveScene | string | 否 | 交互场景 | |
templateId | string | 否 | 后处理模板id | |
transparent | boolean | 否 | 是否开启透明通道 | 否 |
#3)调用示例
VMS.start({
appId: '',
apiKey: '',
apiSecret: '',
width: 1280, //宽度,可取 1920、1280、720
height: 720, // 高度,可取1080、720、405
avatarId: '118801001', //形象ID
streamDomId: 'remote_stream' //虚拟人视频流要渲染的Dom Id
})
.then(() => {
console.log('启动虚拟人服务成功'); //成功回调
})
.catch(() => {
console.log('启动虚拟人服务失败'); //失败回调
});
#2. 结束
结束虚拟人服务
#1)接口
/**
* 结束虚拟人服务
*/
stop() {}
无必填参数
#2)调用示例
VMS.stop()
.then(() => {
console.log('结束虚拟人服务成功'); //成功回调
})
.catch(() => {
console.log('结束虚拟人服务失败'); //失败回调
});
#3. 音频驱动
输入音频数据,驱动虚拟人,音频驱动需先进行初始化,在间隔合适的时间(默认 40ms)流式传入音频数据
#3.1 初始化音频驱动
#1)接口
/**
* 音频驱动初始化
* @param {{frameSize:number,sendInterval:number}} audioDriverConfig 音频驱动配置,默认1280大小,40ms间隔,打断模式
*/
audioDriverInit(audioDriverConfig,wsCloseCallback) {}
#2)参数
{
frameSize:1280,
sendInterval:40
}
function(){}
参数 | 类型 | 必填 | 说明 | 默认值 |
---|---|---|---|---|
frameSize | number | 否 | 每帧数据大小 | 1280 |
sendInterval | number | 否 | 数据发送间隔 | 40 |
#3)调用示例
VMS.audioDriverInit({
frameSize: 1280,
sendInterval: 40
})
.then(() => {
console.log('音频驱动初始化成功'); //成功回调
})
.catch(() => {
console.log('音频驱动初始化失败'); //失败回调
});
#3.2 发送音频数据
#1)接口
/**
* 音频驱动
* @param {IAudioDriverParam} param 音频数据:16K 16bit 单声道
*/
audioDriverSendData(param) {}
#2)参数
{
"parameter": {
"vms_dispatch": {
"realtime_status": {
"vmr_status": true,
"vmr_action_status": true //动作信息
}
}
},
"payload": {
"audio": {
// 驱动音频
"encoding": "raw",
"sample_rate": 16000,
"audio": [],
},
"ctrl_t": {
// 控制指令
"encoding": "utf8",
"compress": "raw",
"format": "json",
"text": ""
},
"ctrl_postproc": {
// 控制指令
"encoding": "utf8",
"compress": "raw",
"format": "json",
"text": ""
}
}
}
① parameter,非必填
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
vms_dispatch | Object | 否 | 服务别名 | ||
realtime_status | Object | 否 | 实时返回状态数据 | ||
vmr_status | number | 0,1 | 否 | 渲染引擎文本实时响应状态 0 关闭 1 打开 | 0 |
vmr_action_status | number | 0,1 | 否 | 渲染引擎动作实时响应状态 0 关闭 1 打开 | 0 |
② payload,必填
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
audio | Object | 是 | 音频数据 |
ctrl_t | Object | 否 | 动作控制段 |
ctrl_postproc | Object | 否 | 后处理控制段 |
audio
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | raw,lame, opus-wb, speex-wb | 否 | 音频编码 | raw |
sample_rate | number | 16000 | 否 | 采样率 | 16000 |
audio | Array | 最小尺寸:1B, 最大尺寸:10485760B | 是 | 音频数据 |
ctrl_t
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 文本编码 | utf8 |
compress | string | raw | 否 | 文本压缩格式 | raw |
format | string | json | 否 | 压缩格式 | json |
text | string | 最小尺寸:0B, 最大尺寸:1048576B | 是 | 驱动指令,base64 字符串,如:Base64.encode({avatar:[{ type: 'action', value: 'A_LH_introduced_O', wb: 3, we: 5 }]}) |
具体动作指令参数,请参照虚拟人服务接口文档 https://aidocs.xfyun.cn/docs/vms/实时交互服务接口文档.html
ctrl_postproc
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 音频编码 | utf8 |
compress | string | raw | 否 | 采样率 | raw |
format | string | json | 否 | 采样率 | json |
text | string | 最小尺寸:0B, 最大尺寸:1048576B | 是 | 后处理控制指令 |
#3)调用示例
VMS.audioDriverSendData({
parameter: {
vms_dispatch: {
realtime_status: {
vmr_status: true,
vmr_action_status: true //动作信息
}
}
},
payload: {
audio: {
encoding: 'raw',
sample_rate: 16000,
audio: []
},
ctrl_t: {
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_postproc: {
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
}
}
});
#4. 文本驱动
输入文本数据,驱动虚拟人
#1)接口
/**
* 文本驱动
* @param {ITextDriverParam} param 动作控制参数
*/
textDriver(param) {}
#2)参数
{
parameter: {
tts: {
// 合成参数
vcn: '', // 发音人
speed: 50, // 语速:[0,100],默认50
pitch: 50, // 语调:[0,100],默认50
volume: 50, // 音量:[0,100],默认50
rhy:3
}
},
payload: {
text: {
// 驱动音频
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_t: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_postproc: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
}
}
}
① parameter,必传:
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
tts | Object | 是 | 合成控制段参数 |
tts
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
vcn | string | x4_xiaoxuan x4_panting x4_yezi x4_xiaoguo x4_yifei x4_mingge x4_chaoge | 是 | 合成发言人 | |
speed | number | 最小值:0, 最大值:100 | 否 | 语速:50 正常语速,0 对应默认语速的 1/2,100 对应默认语速的 2 倍 | 50 |
volume | number | 最小值:0, 最大值:100 | 否 | 音量:50 正常音量,0 是静音,1 对应默认音量 1/2,100 对应默认音量的 2 倍 | 50 |
pitch | number | 最小值:0, 最大值:100 | 否 | 语调:50 正常语调,0 对应默认语速的 1/2,100 对应默认语速的 2 倍 | 50 |
rhy | number | 可选0,1,3 | 否 | 控制是否返回拼音标注。0: 不返回拼音,1: 返回拼音(支持的引擎: xtts1.0-cpu, xtts1.0-gpu, xtts2.0-gpu, xtts2-gpu中是每句话一次性返回)拼音标注的时间xtts2.0要乘以5ms | 1 |
② payload,必填
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
text | Object | 是 | 文本数据描述数据 |
ctrl_w | Object | 否 | 动作控制段 |
ctrl_postproc | Object | 否 | 后处理控制段 |
text
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 文本编码 | utf8 |
compress | string | raw | 否 | 文本压缩格式 | raw |
format | string | json | 否 | 文本格式 | json |
text | string | 最小尺寸:0B, 最大尺寸:65536B | 是 | 合成的文本数据,文本大小:0-64k |
ctrl_w
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 文本编码 | utf8 |
compress | string | raw | 否 | 文本压缩格式 | raw |
format | string | json | 否 | 文本格式 | json |
text | string | 最小尺寸:0B, 最大尺寸:1048576B | 是 | 驱动指令,base64 字符串,如:Base64.encode({avatar:[{ type: 'action', value: 'A_LH_introduced_O', wb: 3, we: 5 }]}) |
具体动作指令参数,请参照虚拟人服务接口文档 https://aidocs.xfyun.cn/docs/vms/实时交互服务接口文档.html
ctrl_postproc
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 文本编码 | utf8 |
compress | string | raw | 否 | 文本压缩格式 | raw |
format | string | json | 否 | 文本格式 | json |
text | string | 最小尺寸:0B, 最大尺寸:1048576B | 是 | 后处理控制指令 |
#3)调用示例
VMS.textDriver({
parameter: {
tts: {
// 合成参数
vcn: '', // 发音人
speed: 50, // 语速:[0,100],默认50
pitch: 50, // 语调:[0,100],默认50
volume: 50, // 音量:[0,100],默认50
rhy:3
}
},
payload: {
text: {
// 驱动音频
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_t: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_postproc: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
}
}
})
.then(res => {})
.catch(e => {});
#5. 流式文本驱动
适用于大模型场景下,流式交互,输入文本数据,驱动虚拟人
####5.1 文本驱动初始化
#1)接口
/**
* 文本驱动初始化
* @param realtimeShowCallback 实时状态回调,用于实时返回各种实时处理状态
* @param wsCloseCallback ws关闭回调
*/
textDriverNitInit(realtimeShowCallback,wsCloseCallback) {}
#2)参数
realtimeShowCallback:function(){}
wsCloseCallback:function(){}
#3)调用示例
VMS.textDriverNitInit((res) => {
console.log('流式返回的实时数据:', res.payload ? decode(res.payload.realtime_status.text) : res.payload);
},(res)=>{
console.log('流式文本驱动ws链接关闭');
}).then(res => {
console.log('流式文本驱动建立连接成功啦');
})
.catch(e => {
console.log('流式文本驱动建立连接失败');
});
####5.2 发送数据
#1)接口
/**
* 发送文本驱动数据
* @param {ITextDriverParam} param 动作控制参数
*/
sendTextDriverData(param) {}
#2)参数
{
parameter: {
tts: {
// 合成参数
vcn: '', // 发音人
speed: 50, // 语速:[0,100],默认50
pitch: 50, // 语调:[0,100],默认50
volume: 50, // 音量:[0,100],默认50
rhy:3
},
vms_dispatch: {
realtime_status: {
tts_status:1,
vmr_status:1,
vmr_action_status:1
},
interactive_mode:1
},
},
payload: {
text: {
// 驱动音频
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_t: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_postproc: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
}
}
}
① parameter,必传:
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
tts | Object | 是 | 合成控制段参数 |
vms_dispatch | Object | 否 | 流式控制参数 |
tts
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
vcn | string | x4_xiaoxuan x4_panting x4_yezi x4_xiaoguo x4_yifei x4_mingge x4_chaoge | 是 | 合成发言人 | |
speed | number | 最小值:0, 最大值:100 | 否 | 语速:50 正常语速,0 对应默认语速的 1/2,100 对应默认语速的 2 倍 | 50 |
volume | number | 最小值:0, 最大值:100 | 否 | 音量:50 正常音量,0 是静音,1 对应默认音量 1/2,100 对应默认音量的 2 倍 | 50 |
pitch | number | 最小值:0, 最大值:100 | 否 | 语调:50 正常语调,0 对应默认语速的 1/2,100 对应默认语速的 2 倍 | 50 |
rhy | number | 可选0,1,3 | 否 | 控制是否返回拼音标注。0: 不返回拼音,1: 返回拼音(支持的引擎: xtts1.0-cpu, xtts1.0-gpu, xtts2.0-gpu, xtts2-gpu中是每句话一次性返回)拼音标注的时间xtts2.0要乘以5ms | 1 |
vms_dispatch
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
realtime_status | Object | 否 | 实时返回状态数据 | ||
tts_status | number | 0,1 | 否 | 文本合成状态 0 关闭 1 打开 | 0 |
vmr_status | number | 0,1 | 否 | 渲染引擎文本实时响应状态 0 关闭 1 打开 | 0 |
vmr_action_status | number | 0,1 | 否 | 渲染引擎动作实时响应状态 0 关闭 1 打开 | 0 |
interactive_mode | number | 0,1 | 否 | 是否打断模式 1 打断 0 追加 | 1 |
② payload,必填
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
text | Object | 是 | 文本数据描述数据 |
ctrl_w | Object | 否 | 动作控制段 |
ctrl_postproc | Object | 否 | 后处理控制段 |
text
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 文本编码 | utf8 |
compress | string | raw | 否 | 文本压缩格式 | raw |
format | string | json | 否 | 文本格式 | json |
text | string | 最小尺寸:0B, 最大尺寸:65536B | 是 | 合成的文本数据,文本大小:0-64k |
ctrl_w
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 文本编码 | utf8 |
compress | string | raw | 否 | 文本压缩格式 | raw |
format | string | json | 否 | 文本格式 | json |
text | string | 最小尺寸:0B, 最大尺寸:1048576B | 是 | 驱动指令,base64 字符串,如:Base64.encode({avatar:[{ type: 'action', value: 'A_LH_introduced_O', wb: 3, we: 5 }]}) |
具体动作指令参数,请参照虚拟人服务接口文档 https://aidocs.xfyun.cn/docs/vms/实时交互服务接口文档.html
ctrl_postproc
参数 | 类型 | 取值范围 | 必填 | 说明 | 默认值 |
---|---|---|---|---|---|
encoding | string | utf8 | 否 | 文本编码 | utf8 |
compress | string | raw | 否 | 文本压缩格式 | raw |
format | string | json | 否 | 文本格式 | json |
text | string | 最小尺寸:0B, 最大尺寸:1048576B | 是 | 后处理控制指令 |
#3)调用示例
VMS.sendTextDriverData({
parameter: {
tts: {
// 合成参数
vcn: '', // 发音人
speed: 50, // 语速:[0,100],默认50
pitch: 50, // 语调:[0,100],默认50
volume: 50, // 音量:[0,100],默认50
rhy:3
},
vms_dispatch: {
realtime_status: {
tts_status: 1,
vmr_status: 1,
vmr_action_status: 1
},
interactive_mode:1
}
},
payload: {
text: {
// 驱动音频
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_t: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
},
ctrl_postproc: {
// 控制指令
encoding: 'utf8',
compress: 'raw',
format: 'json',
text: ''
}
}
})
.then(res => {})
.catch(e => {});
#6. 打断/重置接口
中断驱动,如果是流式驱动则会断开ws连接
#1)接口
/**
*中断流式驱动
*/
pauseTextDriverNit() {}
#2)参数
无
#3)调用示例
VMS.pauseTextDriverNit();
_注意:如需使用 uploadResourceData 需配置代理 _ 本地开发代理配置 如下:
'/individuation': {
target: 'http://evo-hu.xf-yun.com',
changeOrigin: true
},
部署上线 nginx 配置可参考如下:
Location ^~/individuation/ {
proxy_pass http://evo-hu.xf-yun.com;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
}
#7. 上传个性化资源
上传个性化资源,如背景或者画中画 图片、视频以及后处理模板
#1)接口
/**
*
* @param {{
* appId:string
* apiKey:string
* appSecret:string
* resourceBase64Str:string
* type:string
* }} vmsConfig
* @param {string} resId 指定资源resId
* @returns {Promise}
*/
uploadResourceData(vmsConfig, resId) {}
如上代码所示,参数vmsConfig
为必填项。
#2)参数
① 鉴权参数 vmsConfig,必传:
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
appId | String | 是 | 应用 id |
apiKey | String | 是 | apiKey |
appSecret | String | 是 | appSecret |
resourceBase64Str | String | 是 | 资源 base64 字符串 |
type | String | 否 | 资源描述信息,可选:,默认图片:'background_data' |
② 个性化参数 resId,非必传 支持自定义,如果不传,服务返回一个生成的 res_id
#3)调用示例
const uploadTemplateChange = file => {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
let result: any = reader.result;
let base64Str = result.split(';base64,')[1];
VMS.uploadResourceData(
{
appId: '',
apiKey: '',
apiSecret: '',
resourceBase64Str: base64Str,
type:'background_data'
},
'yourResId'
)
.then(data => {})
.catch(() => {});
};
};
_注意:如需使用 uploadResourceData 需配置代理 _ 本地开发代理配置 如下:
'/individuation': {
target: 'http://evo-hu.xf-yun.com',
changeOrigin: true
},
部署上线 nginx 配置可参考如下:
Location ^~/individuation/ {
proxy_pass http://evo-hu.xf-yun.com;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
}
#三、错误码
错误码 | 描述 |
---|---|
29001 | 加入房间失败 |
29002 | 播放视频流失败 |
29003 | 订阅远端流失败 |
29004 | 启动虚拟人服务失败,具体失败原因可查看错误返回信息 |
29005 | 上传资源失败 |
29006 | 停止虚拟人服务失败 |
29007 | 浏览器不支持WebSocket |
29008 | WebSocket连接异常 |
29010 | 文本驱动文本不可为空 |
29011 | 非流式文本驱动异常 |
0x4043 | 此项错误比较特殊:浏览器安全限制,需用户与页面交互才可启动播放 |
#四、移动端兼容性
此版本目前仅完整支持 pc web,不支持移动端,安卓、IOS请请使用对应的SDK