0 前言
最近朋友圈以及身边很多朋友都在研讨GPT开发,做了各种各样的小东西小Demo,AI东西用起来是真的香!在他们的影响下,我也继续捣鼓GPT Demo,期望更多的开发者参加一起多多沟通。 上一篇结合即时通 IM SDK捣鼓了一个Demo ChatGPT群聊机器人Demo ,也收到了一些还不错的反应,有伙伴用于客服场景解放了一部分人工重复作业提升了功率。趁着周末我捣鼓了一个ChatGPT虚拟人直播,结合了相同热门的元宇宙技能。
本文将经过详细开发流程来为大家举例如何快速完成一个虚拟人直播,可用于无人直播场景。ChatGPT虚拟人可抓取直播中粉丝弹幕和谈论并回复来进行用户互动,提升直播间的活跃与用户体会。
最终完成效果如下所示: GPT虚拟人直播
1 完成思路
ChatGPT4.0虚拟人直播,首要得要有2个最根本的才能:ChatGPT4.0接口和虚拟人交互才能,这两块咱们后边详细讲。整个流程如下图所示:
1.需求有具有文字驱动才能的虚拟人。详细来说,需求将文字转为语音,然后虚拟人能根据语音对口型。这儿引荐运用即构Avatar,即构Avatar能够捏脸定制,同时具有文字驱动口型才能。 2. 直播推流。抖音、快手能够用直播伴侣实时截屏推流。 3. 获取实时弹幕/谈论。虚拟人根据观众发的弹幕或许谈论文本数据发送给ChatGPT,能够去github找开源代码。这儿供给一个最简略的思路:在网页版注入JS代码,js实时读取网页上的弹幕。 4. 调用ChatGPT。将实时弹幕/谈论数据发送给ChatGPT并获取回复。 5. 虚拟人播报ChatGPT的回复。
2 ChatGPT接入
现在openAI供给的接口是ChatGPT3.5,能够直接调用。bing在最新版Edge浏览器供给ChatGPT4.0体会,有一些开源库对其做了二次封装,只需供给Cookie即可体会。这儿咱们把两种方式都解说。
2.1 ChatGPT 4.0 接入
首要注册bing账号: 1.前往www.microsoft.com/zh-cn/edge/… 下载最新的Edge浏览器。 2. 敞开VPN,注册用户或运用已有账号登录,点击右上角「设置」图标,将所在区域设置如下 3. 打开Edge,输入网址www.bing.com/search?form…
接下来在代码里面封装ChatGPT4.0接口,先装置第三方根据Edge浏览器的库:
npm i @waylaidwanderer/chatgpt-api
接下来二次封装
import { BingAIClient } from '@waylaidwanderer/chatgpt-api';
export class BingGPT {
/*
* http_proxy, apiKey
**/
constructor(http_proxy, userCookie) {
this.api = this.init(http_proxy, userCookie);
}
init(http_proxy, userCookie) {
console.log(http_proxy, userCookie)
const options = {
// Necessary for some people in different countries, e.g. China (https://cn.bing.com)
host: 'https://www.bing.com',
// "_U" cookie from bing.com
userToken: userCookie,
// If the above doesn't work, provide all your cookies as a string instead
cookies: '',
// A proxy string like "http://<ip>:<port>"
proxy: http_proxy,
// (Optional) Set to true to enable `console.debug()` logging
debug: false,
};
return new BingAIClient(options);
}
//调用chatpgt
chat(text, cb) {
var res=""
var that = this;
console.log("正在向bing发送提问", text )
this.api.sendMessage(text, {
toneStyle: 'balanced',
onProgress: (token) => {
if(token.length==2 && token.charCodeAt(0)==55357&&token.charCodeAt(1)==56842){
cb(true, res);
}
res+=token;
}
});
}
}
注意到,除了需求供给vpn地址以外,还需求供给cookie数据。cookie能够在Edge浏览器中按F12打开开发东西,点击应用程序Tab,从左侧Cookie中找到_U的value即为想要的cookie,如下图所示:
2.2 ChatGPT 3.5接入
由于ChatGPT4.0根据浏览器,非官方供给的API,整体会有些不太安稳。而OpenAI官方供给了ChatGPT3.5,比较之下更安稳。
首要要有OpenAI的ChatGPT账号,在这儿咱们不细讲,不了解的同学能够参阅我另一篇文章,链接: 《当我把ChatGPT拉进群聊里,我的朋友都玩疯了》接下来只需装置ChatGPT库:
npm install chatgpt
注意要运用nodejs 18.0以上版别装置,由于国内的IP无法运用ChatGPT,因而有必要要有VPN署理。再装置一个署理库:
npm install https-proxy-agent node-fetch
接下来,二次封装一下:
import { ChatGPTAPI } from "chatgpt";
import proxy from "https-proxy-agent";
import nodeFetch from "node-fetch";
export class ChatGPT {
constructor(http_proxy, apiKey) {
this.api = this.init(http_proxy, apiKey);
this.conversationId = null;
this.ParentMessageId = null;
}
init(http_proxy, apiKey) {
console.log(http_proxy, apiKey)
return new ChatGPTAPI({
apiKey: apiKey,
fetch: (url, options = {}) => {
const defaultOptions = {
agent: proxy(http_proxy),
};
const mergedOptions = {
...defaultOptions,
...options,
};
return nodeFetch(url, mergedOptions);
},
});
}
//调用chatpgt
chat(text, cb) {
let that = this
console.log("正在向ChatGPT发送提问:", text)
that.api.sendMessage(text, {
conversationId: that.ConversationId,
parentMessageId: that.ParentMessageId
}).then(
function (res) {
that.ConversationId = res.conversationId
that.ParentMessageId = res.id
cb && cb(true, res.text)
}
).catch(function (err) {
console.log(err)
cb && cb(false, err);
});
}
}
注意到除了需求供给VPN地址,还需求供给apiKey。登录OpenAI后,打开链接platform.openai.com/account/api… 即可获取apiKey,如下图所示
3 虚拟人接入
虚拟人供给商有很多,由于现在咱们不仅仅需求有虚拟形象,还需求虚拟人能够说话(ChatGPT供给逻辑思维才能)。因而,咱们这儿直接选用 即构Avatar,它内置了文本驱动才能,能够很便利将ChatGPT的回复文字内容直接读出来,并有口型匹配。十分合适咱们这个场景。
官方供给了十分详细的教程:官方教程地址,本文简略解说一些要害完成,详细完整代码能够参阅文末资源附件。
设置虚拟人形象:
private void setCharacter(User user) {
String sex = ZegoCharacterHelper.MODEL_ID_MALE;
if (!user.isMan) sex = ZegoCharacterHelper.MODEL_ID_FEMALE;
// 创立 helper 简化调用
// base.bundle 是头模, human.bundle 是全身人模
mCharacterHelper = new ZegoCharacterHelper(FileUtils.getPhonePath(mApp, "human.bundle", "assets"));
mCharacterHelper.setExtendPackagePath(FileUtils.getPhonePath(mApp, "Packages", "assets"));
// 设置形象配置
mCharacterHelper.setDefaultAvatar(sex);
// 角色上屏, 有必要在 UI 线程, 有必要设置过avatar形象后才可调用(用 setDefaultAvatar 或许 setAvatarJson 都能够)
mCharacterHelper.setCharacterView(user.avatarView, () -> {
});
mCharacterHelper.setViewport(ZegoAvatarViewState.half);
//设置头发、衣服等
mCharacterHelper.setPackage("ZEGO_Girl_Hair_0001");
mCharacterHelper.setPackage("ZEGO_Girl_Tshirt_0001_0002");
mCharacterHelper.setPackage("facepaint5");
mCharacterHelper.setPackage("irises2");
initTextApi();
updateUser(user);
}
能够看到,只需简略几行代码即可定制虚拟人“皮肤”,运用十分友爱。在文字驱动虚拟人说话方面就更简略:
public void playText(String text) {
if (mTextApi == null) return;
mTextApi.playTextExpression(text);
}
当然了,这儿展现的是最要害代码。要想运用即构avatar还需求做一些权鉴认证、引擎初始化等作业,直接复用本文文末供给的代码附件即可。 需求注意的是,官方供给的Demo源码中只有基础资源。换句话说,还有很多十分酷炫的“皮肤”能够运用。可是由于资源太大,不便利打包。如果读者有更多资源需求,能够直接去官网找客服索要。
下面列出一些官方能供给的虚拟形象“皮肤”示例:
还有很多捏脸才能,这儿不一一描绘,感兴趣的同学能够直接去官网 (点击这儿)去下载体会app,直接感受一下即构Avatar的强大。
4 根据即构SDK完成虚拟直播
关于B站、抖音、快手等第三方渠道,想要做虚拟直播得借助官方供给的推流东西,如直播伴侣等。但官方没有供给实时获取直播间谈论(或弹幕)的接口,当然了,你能够用一些技能手段来获取,这儿不过多解说。接下来咱们解说不用第三方渠道,自己简略几行代码完成建立直播渠道。
4.1 建立虚拟人直播渠道思路
建立虚拟直播渠道有2个思路:
1.主播实时传输手机画面,观众实时接收主播发送的内容(图画),即构实时音视频RTC 该计划完成 可检查,RTC+Avatar计划可检查。 我之前根据抖音渠道做的虚拟人直播Demo, B站、快手等第三方直播渠道的完成原理类似。
2.根据即构ZIM,实时传输文字(文字)
虚拟人直播与其他直播有一个差别是虚拟人是在用户端上运用固定算法烘托出来的,而不是主播实时拍摄的画面。因而咱们彻底不需求主播实时传输画面(图画),只需经过播送文字内容(相当于群组谈天),观众接收到文字内容后实时烘托虚拟人表情即可。这样能够大大节约带宽成本。
即构ZIM供给全面的IM才能,支撑单聊/群聊/房间谈天,可根据实践事务自由组合IM才能。群聊音讯安稳可靠、推迟低,全球任何一个地区都有接入服务的节点保证音讯到达。 了解更多
4.2 详细完成
从上面两个计划能够看到,关于虚拟直播间来说,运用文字实时传输到每个端上,再本地烘托虚拟人画面,能够做到最低成本。 详细来说,一个直播间能够经过一个房间(room)来办理,在即构IM的房间内,能够运用弹幕功用来完成收发文字。比较发送谈天音讯,发送弹幕音讯不会被存储,更合适直播间谈论功用。用户创立直播间时,底层代码创立的是一个房间,并自动参加ChatGPT这个群成员。ChatGPT在群里接收到数据时,调用ChatGPT接口,得到文字回复后,再转发到群里。每个观众接收到ChatGPT回复的文字后,自动烘托虚拟人播报文字内容。
相同的,这儿咱们只展现要害代码。创立房间、参加房间、收到实时谈论(弹幕)。 创立房间、参加房间:
//创立房间
public void createRoom(String masterId, String roomId, String roomName, CB cb) {
ZIMRoomInfo groupInfo = new ZIMRoomInfo();
groupInfo.roomID = roomId;
groupInfo.roomName = roomName;
zim.createRoom(groupInfo, new ZIMRoomCreatedCallback() {
@Override
public void onRoomCreated(ZIMRoomFullInfo roomInfo, ZIMError errorInfo) {
if (errorInfo.code == ZIMErrorCode.SUCCESS) {
inviteJoinRoom(masterId, roomId, CHATGPT_ID, cb);//这儿把chagpt的用户id硬编码
} else {
cb.complete(false, "房号已存在,请更换一个房间号!");
}
}
});
}
//参加房间
public void joinRoom(String roomId, CB cb) {
zim.joinRoom(roomId, new ZIMRoomJoinedCallback() {
@Override
public void onRoomJoined(ZIMRoomFullInfo roomInfo, ZIMError errorInfo) {
Log.e(TAG, ">>" + errorInfo.code);
if (errorInfo.code == ZIMErrorCode.ROOM_DOES_NOT_EXIST) {
cb.complete(false, "房间不存在!");
} else if (errorInfo.code == ZIMErrorCode.SUCCESS || errorInfo.code == ZIMErrorCode.THE_ROOM_ALREADY_EXISTS) {
cb.complete(true, roomInfo.baseInfo.roomName);
}
}
});
}
接收到音讯
//接收到文字音讯
@Override
public void onRcvMsg(Msg msg) {
switch (msg.proto) {//判别音讯类型
case ChatGPT: {//来自ChatGPT的音讯,语音播报文字
mZegoMngr.getAvatarMngr().playText(msg.msg);
sendDM(msg.msg.replace("\n", ""), 0);
break;
}
case DanMu: {//收到弹幕音讯,直接在屏幕上展现
sendDM(msg.msg, msg.extInt);
break;
}
case DismissRoom: {//收到闭幕房间音讯,退出房间
mZegoMngr.getZIMMngr().leaveRoom(msg.msg, new CB() {
@Override
public void complete(boolean succ, String msg) {
ShowUtils.alert(RoomActivity.this, "提示", "房间已闭幕!", new ShowUtils.OnClickOkListener() {
@Override
public void onOk() {
back();
}
});
}
});
break;
}
}
}
5 开源-Github源码
- ChatGPT调用代码(nodejs)github.com/RTCWang/Cha…
- 直播客户端客户端(android)github.com/RTCWang/Cha…
6 ChatGPT虚拟人直播Demo 运用东西
- 直播产品:RTC SDK Android Java实时音视频完成流程 – 开发者中心
- 语聊房:ZIM SDK Android即时通讯SDK完成根本音讯收发功用 – 开发者中心
- GPT4.0: New bing
- GPT3.5: ChatGPT