@nextcas/sdk
v1.2.3
Published
nextcas 虚拟人webgl sdk
Downloads
155
Readme
《JS/小程序》虚拟人开发文档
简介
NextHuman对外提供的WebGL版SDK名为NextCAS(全称为NextHuman connect Agents And Systems.),旨在为企业提供“低价格”、“近乎零成本开发”、“高质量数字人”、“快速部署落地”的轻量级数字人解决方案。
开源
考虑到数字人的许多业务场景有高度相似性,所以我们会开放许多特定场景的WebGL Demo到Github仓库,帮助大家快速构建自己的数字人应用,当然也欢迎外部的开发者朋友向我们提交一些有趣的Demo,代码开放仓库在Github
计费
快速开始
注意:《文旅元宇宙开发者或企业》请单独联系我们,需使用另外的WebGL SDK来实现玩家或NPC系统 录音功能可使用@nextcas/voice
调试
在JS/WebGL的开发过程中,目前虚拟人底层库是不支持“断点调试”,所以大家可以通过console.log的形式进行日志调试,关闭断点调试如下:
安装
通过 npm 安装
npm i @nextcas/sdk@latest -s
然后在应用中,可以通过以下内容引用 SDK
import NextCas from "@nextcas/sdk";
鉴权
使用应用管理中应用的accessKey和accessSecret生成SDK初始化时的鉴权令牌(JWT 风格的Token),注意每次SDK重新初始化或/刷新页面,请重新生成Token(避免被盗用和滥用),参考如下代码(JAVA)
public String createAccessToken(String accessKey,String accessSecret){
SecretKey secretKey = Keys.hmacShaKeyFor(accessSecret.getBytes(StandardCharsets.UTF_8));
JwtBuilder builder = Jwts.builder();
builder.claim("role","role.visit");
builder.claim("timestamp",System.currentTimeMillis());//务必传系统当前时间,会用于系统时间钟校验
builder.setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000));//建议设置为24小时以内的有效期
return accessKey + "@" + builder.signWith(secretKey).compact();
}
初始化
const container = document.getElementById("nextcas")!;
const nextCas = new NextCas(container, {
token: token,
actorId: actorId,
templateName: "base",
avatarId: string,
});
初始化时确保已为
container
元素设置宽高,渲染区域铺满container,默认开启响应式
参数简介
| 参数名称 | 类型 | 描述 | | ------------ | ------------------ | --------------------------------------------------------------------------------------------------------------------- | | avatarId | string | 形象ID,比如通用女模:avatar_257 | | token | string | 参考“鉴权” | | actorId | string | 智能体管理模块中的智能体Id,通用/自建actorId皆可以调用,比如“甜美小源” | | templateName | string | 目前的可用模版有:'introduce'(功能演示)、'base'(基础) | | visitId | string(可选) | | | render | RenderOption(可选) | 渲染设置 |
RenderOption
| 参数名称 | 类型 | 描述 | | -------------- | ------------- | ---------------------------------------------- | | textureQuality | number(可选) | 设置纹理渲染精度,减少gpu显存消耗,取值范围0-1 | | lookAt | boolean(可选) | 是否开启眼神注视,默认值:true | | hairPhysics | boolean(可选) | 是否开启物理模拟,默认值:true |
SDK方法
setAvatar(avatarId:string)
说明 :切换角色
nextCas.setAvatar("avatar_1078");
setActor(actorId:string)
说明 :切换智能体
nextCas.setActor("actor_100230");
addBundle(bundleId:string)
说明 :切换装扮
nextCas.addBundle(bundleId); //bundleId: string [道具](daoju.md)Id 目前支持分类 头发 鞋子 套装
addSceneBundle(bundleId:string)
说明 :切换场景
nextCas.addSceneBundle(bundleId); //bundleId: string [道具](daoju.md)Id
getBundles()
说明 :获取当前装扮
const currentBundles = await nextCas.getBundles();
setBackground(color:string)
说明 :设置环境背景
color 支持 css 颜色
nextCas.setBackground("red");
speak()
主动触发虚拟人演讲
- 类型
speak(
text: string,
options?: {
reqId?: string
onEnd?: () => void
onStart?: () => void
},
):void
- 详细信息
第一个参数为需要说话的文本 第二个参数为可选参数 reqId:自定义reqId onEnd:当说话结束时触发 onStart:当说话开始时触发
- 示例
nextCas.speak("你好,我是来自潘多拉星球的nexthuman", {
onEnd: () => {
console.log("onEnd");
},
onStart: () => {
console.log("onStart");
},
});
speakByAudio()
- 类型
speakByAudio(
audioData: ArrayBuffer | string,
options?: {
reqId?:string
onEnd?: () => void
onStart?: () => void
},
):()=>void;
详细信息 第一个参数是音频数据,(ArraybuFfer 和 base64 字符串)16k16bit 单通道 wav 第二个参数是可选参数,可以指定 onEnd, onStart 回调函数
示例
<div class="mt-8">
指定音频
<input type="file" name="audioFile" accept="*" @change="onAudioChange" />
</div>
async function onAudioChange(event) {
const file = event.target.files[0] as File;
const arrayBuffer = await file.arrayBuffer();
cas?.value?.speakByAudio(arrayBuffer, {
onEnd: () => {
console.log("结束");
},
onStart: () => {
console.log("开始");
},
});
}
createSpeackStream(reqId?:string)
说明 :创建流式的虚拟人演讲
文本流的最后一段需要调用last,否则虚拟人会一直等待最后一段文本流,或者在下一段演讲时打断
const stream = nextCas.createSpeackStream();
stream.onStart = () => {
console.log("开始播报")
}
stream.onEnd = () => {
console.log("播报结束")
}
stream.next("NextHuman是一个消费级超写实数字人直播引擎,使用户一键实现自由搭配")
setTimeout(() => {
stream.next("能够提供精致的妆容效果,满足用户的随心所欲变更妆容;提供丰富的私人衣柜");
// last 可以不传参
// stream.next("换装;独创的AI算法,实现对超写实微表情的完美复原。")
// stream.last()
stream.last("换装;独创的AI算法,实现对超写实微表情的完美复原。")
}, 3000);
createSpeakAudioStream()
创建语音数据驱动流式的虚拟人演讲
- 类型
createSpeakAudioStream(reqId?string):SpeakStream
// data 数据为ArraybuFfer 或者 base64 16k16bit 单通道 wav
SpeakStream{
onEnd?:()=>void,
onStart?:()=>void
next:(audio:ArrayBuffer|string)=>void,
last:(audio:ArrayBuffer|string)=>void
}
详细信息 语音流的最后一段需要调用 last,否则虚拟人会一直等待最后一段文本流,或者在下一段演讲时打断。
代码示例
const stream = nextCas.createSpeakAudioStream();
stream.onEnd = () => {
console.log("演讲开始");
};
stream.onEnd = () => {
console.log("演讲结束");
};
stream.next(data);
setTimeout(() => {
stream.next(
data
);
stream.last(data);
}, 3000);
playDrama(dramaId:string)
说明 :播放剧本
nextCas.playDrama(dramaId);
ask(text:string,askOption:AskOption)
说明 :AI 问答
AskOption:{
userName:string, // 用户名
userInfo:string // 用户信息
}
const askId = await nextCas.ask("你是谁啊");
nextCas.on("reply", (data) => {
if (data.id === askId) {
console.log("这是同一段对话内容");
}
});
mute()
说明 :静音
nextCas.mute();
unmute()
说明 :取消静音
nextCas.unmute();
stopAct()
说明 :主动停止当前演讲
nextCas.speack("你好,我是来自潘多拉星球的nexthuman");
setTimeout(() => {
nextCas.stopAct();
}, 3000);
changeCamera(position?:{x:number,y:number,z:number},lookAt?:{x:number,y:number,z:number},duration?:number)
说明 :改变相机位置
参数 Position:相机位置,lookAt:camera朝向,duration?:动画执行时长 (ms)
nextCas.changeCamera({ x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: 0 }, 500);
addHdrScene(hdrSrc:string)
说明 :设置 HDR 场景
nextCas.addHdrScene("https://cdn.xxxx.com/scene.hdr");
removeHdrScene()
说明 :移除 hdr 场景
nextCas.removeHdrScene();
setLookAt(open:boolean)
说明 :设置是否开启视角跟随
nextCas.setLookAt(true|false);
setHairPhysics(open:boolean)
说明 :设置是否开启头发物理模拟
nextCas.setHairPhysics(true|false);
updateToken(token:string)
说明 :更新 token
nextCas.on("refresh_token", () => {
const token = ...
nextCas.updateToken(token)
});
save(masterToken:string,name?:string)
说明: 使用 addBundle
更改数字人装扮后,可保存使其为默认装扮
const masterToken = "";
nextCas.save(masterToken, "新角色名称");
saveas(masterToken:string,name?:string)
说明 :使用 addBundle
更改数字人装扮后,可另存为一个新的角色,返回值为新的avatarId
const masterToken = "";
const newAvatar = await nextCas.saveas(masterToken, "新角色名称");
destroy()
说明 :销毁当前cas实例
nextCas.destroy()
nextCas = null
事件
| 事件名称 | 事件参数 | 描述 |
| -------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| ready | null
| 初始化完成 |
| reply | [data:{content:string,last:boolean},id:string]
| id 对应 ask 接口的返回值,可用于判断回答内容是否属于同一个问题,content 为回答具体内容 |
| initProgress | number
| 初始化时的资源网络加载进度,由于第一次渲染时间较长(基于客户端机器性能),当资源加载完成后,会有几秒的延迟再触发 ready 事件 (等同于avatarProgress) |
| refresh_token | null
| token 过期,需要重新获取 token |
| avatarProgress | number
| avatar的加载进度 |
| actorStart | null
| 演讲或剧本播放开始 |
| actorEnd | null
| 演讲或剧本播放结束 |
| error | {key:string,message:string}
| 见下方错误码表格 |
常见问题
1. 为什么调用speack和ask接口,虚拟人没有响应?
说明 : 由于浏览器自动播放策略的限制,在触发虚拟人说话前,需要确保用户有过交互行为(click,touch,keydown)。
2. 使用introduce
模板,为什么录音功能没有响应
说明 :
当前sdk(0.x版本)基于iframe实现,自定义部署时,由于浏览器跨域限制,无法使用浏览器的录音api,需要用户使用base
模板自定义实现
可以使用1.0以上版本
错误码
| 错误码 | 说明 | | ---------------------- | ------------------------ | | CMN_INVALID_PARAM | 无效的请求参数 | | CMN_EXCEED_CONCURRENCY | XX类别的请求并发超过限制 | | CMN_EXCEED_QAUTO | XX类别请求用量超过限制 | | CMN_NO_PERMISSION | 无权限的访问 | | CMN_NO_AUTHED | 无效的鉴权 | | X2FACE_GEN_FAILED | 表情生成失败 | | X2FACE_EXCEED_QAUTO | 表情生成超过用量限制 | | TTS_EXCEED_QAUTO | TTS超过用量限制 | | TTS_GEN_FAILED | TTS生成异常 | | TTS_INVALID_VOICEID | 无效的发音人设置 | | ASR_EXCEED_QAUTO | ASR用量超过限制 |