共计 7217 个字符,预计需要花费 19 分钟才能阅读完成。
0 前言
最近朋友圈以及身边很多敌人都在钻研 GPT 开发,做了各种各样的小工具小 Demo,AI 工具用起来是真的香!在他们的影响下,我也持续捣鼓 GPT Demo,心愿更多的开发者退出一起多多交换。
上一篇联合即时通 IM SDK 捣鼓了一个 Demo ChatGPT 群聊机器人 Demo,也收到了一些还不错的反馈,有搭档用于客服场景解放了一部分人工反复工作晋升了效率。趁着周末我捣鼓了一个 ChatGPT 虚拟人直播,联合了同样热门的元宇宙技术。
本文将通过具体开发流程来为大家举例如何疾速实现一个虚拟人直播,可用于无人直播场景。ChatGPT 虚拟人可抓取直播中粉丝弹幕和评论并回复来进行用户互动,晋升直播间的沉闷与用户体验。
最终实现成果如下所示:
GPT 虚拟人直播
1 实现思路
ChatGPT4.0 虚拟人直播,首先得要有 2 个最根本的能力:ChatGPT4.0 接口和虚拟人交互能力,这两块咱们前面具体讲。整个流程如下图所示:
1. 须要有具备文字驱动能力的虚拟人。具体来说,须要将文字转为语音,而后虚拟人能依据语音对口型。这里举荐应用即构 Avatar,即构 Avatar 能够捏脸定制,同时具备文字驱动口型能力。
- 直播推流。抖音、快手能够用直播伴侣实时截屏推流。
- 获取实时弹幕 / 评论。虚拟人依据观众发的弹幕或者评论文本数据发送给 ChatGPT,能够去 github 找开源代码。这里提供一个最简略的思路:在网页版注入 JS 代码,js 实时读取网页上的弹幕。
- 调用 ChatGPT。将实时弹幕 / 评论数据发送给 ChatGPT 并获取回复。
-
虚拟人播报 ChatGPT 的回复。
2 ChatGPT 接入
目前 openAI 提供的接口是 ChatGPT3.5,能够间接调用。bing 在最新版 Edge 浏览器提供 ChatGPT4.0 体验,有一些开源库对其做了二次封装,只需提供 Cookie 即可体验。这里咱们把两种形式都解说。
2.1 ChatGPT 4.0 接入
首先注册 bing 账号:
1. 返回 https://www.microsoft.com/zh-cn/edge/download?ch&form=MA13FJ 下载最新的 Edge 浏览器。- 开启 VPN,注册用户或应用已有账号登录,点击右上角「设置」图标,将所在区域设置如下
- 关上 Edge,输出网址 https://www.bing.com/search?form=MY0291&OCID=MY0291&q=Bing+AI…
接下来在代码外面封装 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 后,关上链接 https://platform.openai.com/account/api-keys 即可获取 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)https://github.com/RTCWang/ChatGPT-Avatar-live?source=sfarticle66
- 直播客户端客户端(android)https://github.com/RTCWang/ChatGPT-Avatar-live?source=sfarticle66
6 ChatGPT 虚拟人直播 Demo 应用工具
- 直播产品:RTC SDK Android Java 实时音视频实现流程 – 开发者核心
- 语聊房:ZIM SDK Android 即时通讯 SDK 实现根本音讯收发性能 – 开发者核心
- GPT4.0: New bing
- GPT3.5: ChatGPT