【GPT开发】人人都能用ChatGPT4.0做Avatar虚拟人直播
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.前往https://www.microsoft.com/zh-cn/edge/download?ch&form=MA13FJ 下载最新的Edge浏览器。
2. 注册用户或使用已有账号登录,点击右上角「设置」图标,将所在区域设置如下
3. 打开Edge,输入网址https://www.bing.com/search?form=MY0291&OCID=MY0291&q=Bing+AI&showconv=1
接下来在代码里面封装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=cnblogarticle66
- 直播客户端客户端(android)https://github.com/RTCWang/ChatGPT-Avatar-live?source=cnblogarticle66
6 ChatGPT虚拟人直播Demo 使用工具
- 直播产品:RTC SDK Android Java实时音视频实现流程 - 开发者中心
- 语聊房:ZIM SDK Android即时通讯SDK实现基本消息收发功能 - 开发者中心
- GPT4.0: New bing
- GPT3.5: ChatGPT
【GPT开发】人人都能用ChatGPT4.0做Avatar虚拟人直播的更多相关文章
- 人人都是产品经理<2.0>
之前有看过<人人都是产品经理1.0>,还认真的做了笔记,看完后不久,得知作者在第一版的内容基础上,升华性的出了第二版,即<人人都是产品经理2.0>.注:第一版和第二版跨度有6年 ...
- 学习《人人都是产品经理2.0:写给泛产品经理》高清中文PDF+苏杰(作者)
<人人都是产品经理2.0--写给泛产品经理>将从人开始,以人结束,中间说事,以一个产品从无到有的过程为框架--想清楚.做出来.推出去,外加一章综合案例.其中,最重要的想清楚.做出来.推出去 ...
- 人人都是产品经理<1.0>
用了大概2个月的时间,细细的读完了<人人都是产品经理>这本书,受益良多,期间也做了一些笔记,都在前面的博客————products系列中... 当然,更多的收获,还是沉滞在书中的注释,以及 ...
- IT行业供应过剩?“减负路线”助你成为人人都想要的抢手开发
开发者的IT技能:良莠不齐,优秀的软件开发人员在招聘时往往可遇不可求.包括国家统计局在内的多家权威机构的报告提示,在数字化转型的浪潮下,市场对于软件开发人员的需求数量已经远远地超过现有开发者群体的数量 ...
- 【腾讯Bugly干货分享】人人都可以做深度学习应用:入门篇
导语 2016年,继虚拟现实(VR)之后,人工智能(AI)的概念全面进入大众的视野.谷歌,微软,IBM等科技巨头纷纷重点布局,AI 貌似将成为互联网的下一个风口. 很多开发同学,对人工智能非常感兴趣, ...
- 初识Dash -- 构建一个人人都能够轻松上手的界面,操控数据和可视化
从事数据科学工作,少不了使用Pandas.scikit-learn这些Python生态系统中的利器,还有就是控制工作流的Jupyter Notebooks,没的说,你和同事都爱用.但是,要想将工作成果 ...
- 【总结整理】面试pm常见的问题---摘自《人人都是产品经理》
求职路上,“怼”来“怼”去的面试问题 人人都是产品经理社区 发布于 2018-10-29 19:53:06 举报 阅读数:1418 在求职路上,面对那些被“怼”到过的面试问题,应该如何处理? 一个 ...
- CozyRSS开发记录18-番外之Atom1.0的支持
CozyRSS开发记录18-番外之Atom1.0的支持 1.对CozyRSS.Syndication批判一番 由于我工作的主要开发语言是c++,所以会看到我的c#代码写得非常朴素,很多语法糖都没有用上 ...
- 人人都是 DBA(XII)查询信息收集脚本汇编
什么?有个 SQL 执行了 8 秒! 哪里出了问题?臣妾不知道啊,得找 DBA 啊. DBA 人呢?离职了!!擦!!! 程序员在无处寻求帮助时,就得想办法自救,努力让自己变成 "伪 DBA& ...
- 人人都是 DBA(XV)锁信息收集脚本汇编
什么?有个 SQL 执行了 8 秒! 哪里出了问题?臣妾不知道啊,得找 DBA 啊. DBA 人呢?离职了!!擦!!! 程序员在无处寻求帮助时,就得想办法自救,努力让自己变成 "伪 DBA& ...
随机推荐
- 调用mglearn时的报错 TypeError: __init__() got an unexpected keyword argument 'cachedir'
import mglearn的时候发生的报错 原因是调用了joblib包中的memory类,但是cachedir这个参数已经弃用了 查到下面帖子之后改掉cachedir解决问题 https://blo ...
- JAVA 学习打卡 day2
2022-04-23 16:43:32 1.字符类型 (1)字符和整型之间的相互转换 给字符变量赋值可以使用数值和字符,它们都可以使程序正确地运行.要注意的是,字符要用一对单引号('')括起 (2)常 ...
- js数组原型方法
今天学习了一下js数组原型的操作方法,小结一下学习地址https://www.cnblogs.com/obel/p/7016414.html 1.join() join(separator): 将数组 ...
- 【Unity】2021接Bugly踩坑记录
写在前面 因为在工作项目中用到Bugly,所以我在自己的测试工程中尝试接入Bugly,却没有成功,明明一切是按照说明书操作,为什么会不成功?当时在网上找了很久的资料,最后试成功了,这里把当时遇到的问题 ...
- cvs 常见命令
一.cvs上传一个新的工程到server 假如上传目录test到xxxx_project下1. copy test到xxxx_project2. 删除test目录及子目录下的CVS目录3. 在xxxx ...
- python学习记录(三)-数据类型
字符串格式化 var = 'abcde' # 切片 print(var[2],var[-1]) # c e print(var[1:3:1],var[-2:-5:-1],var[::-1]) # bc ...
- python xlwings实用操作记录
import xlwings as xw tfile="test.xlsx" newfile="new.xlsx" app = xw.App(visible=F ...
- Linux挂载SMB共享文件夹
mount -t cifs -o username=xxxx,password=xxxx //PATH/TO/Shared/Folder /mount/point
- 9. PEP8规范
1. 每一级缩进4个空格 2. 续行时缩进要比正常行多缩进, 要能明显看出是续行的 3. 每一行最多79个字符 4. 函数和类定义时在前后加2个空行, 类内接口在定义时, 前后加1个空行 5. 二元运 ...
- IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤
IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤 . @ 目录 IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤 IDEA 导入项目模块 Modul ...