「GPT虚拟直播」实战篇二|无人直播间如何接入虚拟人

摘要

虚拟人和数字人是人工智能技术在现实生活中的具体应用,它们可以为人们的生活和工作带来便利和创新。在直播间场景里,虚拟人和数字人可用于直播主播、智能客服、营销推广等。接入GPT的虚拟人像是加了超强buff,具备更强大的自然语言处理能力和智能对话能力,可以实现更加智能化、自然化的人机交互。

  • 直播主播:虚拟人可以作为直播间的主播角色,通过与粉丝的对话和互动,提高粉丝的互动效果和兴趣
  • 代替客服:数字人可以作为客服角色,通通过自然语言处理和智能对话,解决客户的问题,并提高客户满意度。
  • 营销推广:虚拟人可以作为品牌形象进行推广,数字人可以通过客观数据进行精准营销,提高粉丝的黏性和忠诚度。

前言

续上一篇文章《干货分享|GPT虚拟直播的设计与实战》 ,我们实现了ChatGPT与ZIM的对接。使得加入聊天群组就相当于加入了直播间,实时与ChatGPT文字互动。但还缺了点什么:直播间可不是只有文字,还有主播!接下来进入本文主题:如何接入虚拟人直播。

虚拟主播我们可以通过即构Avatar进行个人化定制,之前在他们《官网》体验过Avatar Demo,一键可以打造多元化风格,支持Q版、二次元、动漫、拟人等多种风格,即构自研虚拟形象引擎强大AI驱动能力,四种驱动方式:表情驱动、声音驱动、文本驱动、肢体驱动。根据本期Demo需求定制了拟人版本的主播小姐姐。即构AvatarQ版形象软萌可爱含丰富的服饰和妆容素材库,推荐大家去体验。即构Avatar的文本驱动方式刚好符合咱们的业务需求。

微信图片_20230529131522.png

1 加入ZIM房间,实时收发消息

加入ZIM房间跟上一篇文章介绍的nodejs版原理一致:

  1. 先登录ZIM
  2. 加入房间或创建房间
  3. 发送弹幕
  4. 监听房间消息,如果来自ChatGPT则朗读

1.1 创建ZIM对象

首先引入ZIM库后,可以调用ZIM的create函数创建ZIM对象,然后调用ZIM对象的setEventHandler函数,将ZIMEventHandler对象传入。ZIMEventHandler主要用于处理一些回调事件如用户上线等回调事件。

public class ZIMMngr {/*** 创建ZIM对象*/private ZIM createZIM(Application app, ZIMEventHandler handler) {// 创建 ZIM 对象,传入 APPID 与 Android 中的 ApplicationZIM zim = ZIM.create(KeyCenter.APP_ID, app);zim.setEventHandler(handler);return zim;}//其他代码略...
}

1.2 群聊-登录、创建房间、加入房间

登录即构服务首选需要token,生成token算法在附件源码已经给出,直接调用即可。但是需要注意,在这个Demo中直接在客户端上生成了,这是非常危险的操作,因为你的密钥和appid暴露出来了,黑客可以通过密钥和appid蹭你的额度费用。因此,建议把token计算放在服务器端生成。

ZIM的createRoom函数用于创建房间,需要提供房间号;joinRoom函数用于加入房间,同样也需要提供房间号。具体代码如下所示:

public class ZIMMngr {//其他代码略..../*** 登录zim*/public void login(String userId, CB cb) {String token = ZIMMngr.getToken(userId);ZIMMngr.login(zim, token, userId, new ZIMLoggedInCallback() {@Overridepublic void onLoggedIn(ZIMError errorInfo) {if (errorInfo.getCode() != ZIMErrorCode.SUCCESS) {Log.e(TAG, "login error:" + errorInfo.getMessage());cb.complete(false, "登录失败");} else {cb.complete(true, null);}}});}/*** 加入房间*/public void joinRoom(String roomId, CB cb) {zim.joinRoom(roomId, new ZIMRoomJoinedCallback() {@Overridepublic 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);}}});}/*** 创建房间*/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() {@Overridepublic void onRoomCreated(ZIMRoomFullInfo roomInfo, ZIMError errorInfo) {if (errorInfo.code == ZIMErrorCode.SUCCESS) {inviteJoinRoom(masterId, roomId, CHATGPT_ID, cb);//这里把chagpt的用户id硬编码} else {Log.e(TAG, "创建房间失败:" + errorInfo.message);cb.complete(false, "房号已存在,请更换一个房间号!");}}});}
}

1.3 即时通讯实现收发消息

接下来实现消息收发,主动发送消息与监听接收消息。注意,这里因为我们只关注弹幕消息,因此非弹幕消息过滤。发送消息封装两类:

  • P2P
  • ROOM

注意,因为我们这里只用弹幕消息,因此ROOM消息只表示弹幕消息。

public class ZIMMngr {//定义属性略..../*** 收到房间消息*/private void onRcvMsg(ArrayList<ZIMMessage> messageList) {if (mListener == null) return;for (ZIMMessage zimMessage : messageList) {if (zimMessage instanceof ZIMBarrageMessage) {//只看弹幕消息ZIMBarrageMessage zimTextMessage = (ZIMBarrageMessage) zimMessage;if (zimMessage.getTimestamp() < this.startTime)continue;String fromUID = zimTextMessage.getSenderUserID();ZIMConversationType ztype = zimTextMessage.getConversationType();String toUID = zimTextMessage.getConversationID();Msg.MsgType type = Msg.MsgType.P2P; String data = zimTextMessage.message; Msg msg = Msg.parseMsg(data, fromUID, toUID, ztype == ZIMConversationType.ROOM);mListener.onRcvMsg(msg);}}} /*** 发送zim消息* */public void sendMsg(Msg msg, CB cb) {//p2p消息则发送Text,room发送弹幕类型消息ZIMMessage zimMsg = null;ZIMConversationType type;if (msg.type == Msg.MsgType.P2P) {ZIMTextMessage m = new ZIMTextMessage();m.message = msg.msg;zimMsg = m;type = ZIMConversationType.PEER;} else {ZIMBarrageMessage m = new ZIMBarrageMessage();m.message = msg.msg;zimMsg = m;type = ZIMConversationType.ROOM;}ZIMMessageSendConfig config = new ZIMMessageSendConfig();// 消息优先级,取值为 低:1 默认,中:2,高:3config.priority = ZIMMessagePriority.LOW;// 设置消息的离线推送配置ZIMPushConfig pushConfig = new ZIMPushConfig();pushConfig.title = "离线推送的标题";pushConfig.content = "离线推送的内容";config.pushConfig = pushConfig; zim.sendMessage(zimMsg, msg.toUID, type, config, new ZIMMessageSentCallback() {@Overridepublic void onMessageAttached(ZIMMessage message) {} @Overridepublic void onMessageSent(ZIMMessage message, ZIMError errorInfo) { cb.complete(errorInfo.code == ZIMErrorCode.SUCCESS, errorInfo.message); }}); }  // 其他代码略....
}

上面代码只挑选了关键函数, 更多关于即构ZIM接口与官方Demo可以点击参考这里,或者参考附录源码。

2 创建虚拟形象-即构Avatar

接下来需要创建虚拟形象,读者可以参考官方文档获取更多详细信息。

需要注意的是,通过官方封装的ZegoCharacterHelper可以非常简单的创建Avatar。创建虚拟形象封装到setCharacter函数中,在程序初始化期间,需要执行initRes函数,将资源拷贝到SDCard。作为演示,这里是将Assets里面的相关资源拷贝到SDCard。在实际项目中,建议将资源存放在服务器端,通过离线下载的方式存储到SDCard。这样既可以降低安装包的大小,也更灵活。

public class AvatarMngr implements ZegoAvatarServiceDelegate {//属性定义略.... /*** 设置虚拟形象如衣服、头发、性别等*/private void setCharacter(User user) {  // 创建 helper 简化调用// base.bundle 是头模, human.bundle 是全身人模mCharacterHelper = new ZegoCharacterHelper(FileUtils.getPhonePath(mApp, "human.bundle", "assets"));mCharacterHelper.setExtendPackagePath(FileUtils.getPhonePath(mApp, "Packages", "assets"));// 设置形象配置mCharacterHelper.setDefaultAvatar(ZegoCharacterHelper.MODEL_ID_FEMALE);// 角色上屏, 必须在 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");  updateUser(user);  }   private void initRes(Application app) {// 先把资源拷贝到SD卡,注意:线上使用时,需要做一下判断,避免多次拷贝。资源也可以做成从网络下载。if (!FileUtils.checkFile(app, "AIModel.bundle", "assets"))FileUtils.copyAssetsDir2Phone(app, "AIModel.bundle", "assets");if (!FileUtils.checkFile(app, "base.bundle", "assets"))FileUtils.copyAssetsDir2Phone(app, "base.bundle", "assets");if (!FileUtils.checkFile(app, "human.bundle", "assets"))FileUtils.copyAssetsDir2Phone(app, "human.bundle", "assets");if (!FileUtils.checkFile(app, "Packages", "assets"))FileUtils.copyAssetsDir2Phone(app, "Packages", "assets");}//...//其他代码略....//...
}

除了衣服、首饰、发型等"装饰类"形象定义,还可以捏脸,这里不详细描述,建议读者前往官网查看。即构Avatar官网。

4 直播间虚拟人与粉丝互动聊天

创建完虚拟人后,接下来将收到的ChatGPT消息朗读出来,使虚拟主播嘴巴动起来,互动玩法更好。首先执行initTextApi函数,初始化本地文字驱动引擎。接下来就可以调用ZegoTextAPI的playTextExpression函数,驱动虚拟人语音播报文字内容。

/*** 朗读文字(嘴唇+语音)
*/
public void playText(String text) {if (mTextApi == null) return;mTextApi.playTextExpression(text);Log.e(TAG, ">>>>已播放" + text);
}
/*** 初始化文本驱动接口
*/
private void initTextApi() {mTextApi = new ZegoTextAPI(mCharacterHelper.getCharacter());mTextApi.setTextExpressionCallback(new ITextExpressionCallback() {/*** 文本驱动播放启动时,回调*/@Overridepublic void onStart() {Log.d(TAG, "text drive start");}/*** 文本驱动播放出错时,回调* @param errorCode 错误码,详情请参考 [常见错误码 - 文本驱动](https://doc-zh.zego.im/article/14884#2)。*/@Overridepublic void onError(int errorCode, String msg) {}/*** 文本驱动播放结束时,回调*/@Overridepublic void onEnd() {Log.d(TAG, "text drive end");}});
}

文本驱动部分代码比较简单,也反映了官方对这块封装的比较好。播报文字主要借助即构avatar的文本能力,读者可以查看官方文档描述:官方文档。仔细阅读可以发现,关键核心代码非常少,附件里面的其他代码主要是开发App非核心代码。

本文演示了从0开发、无须服务端开发完成的基于ChatGPT的虚拟人直播,任何人下载该App即可加入直播间。一些小伙伴可能并不需要开发一个虚拟人直播平台,而是想着在抖音、快手、视频号等平台实现虚拟人直播。这里提供一个实现思路:

  1. 复用本文代码,可以实现ChatGPT回复、并将回复的文字驱动虚拟人
  2. 使用直播伴侣等工具录制虚拟人,推流到抖音平台
  3. 去github找开源工具,实时爬取直播间的弹幕
  4. 读取到弹幕后,调用ChatGPT得到回复,再回到第1步。

未来想象方面,虚拟人接入GPT可以实现更加智能化、个性化的服务,可以预见的是,未来的虚拟人将更加人性化,通过情感计算等技术,可以实现更加真实、自然的人机交互。虚拟人还可以与物理机器人结合,成为未来的机器人助手,为人们的生活和工作提供更加便利的服务。

5 Github源码

供一个实现思路:

  1. 复用本文代码,可以实现ChatGPT回复、并将回复的文字驱动虚拟人
  2. 使用直播伴侣等工具录制虚拟人,推流到抖音平台
  3. 去github找开源工具,实时爬取直播间的弹幕
  4. 读取到弹幕后,调用ChatGPT得到回复,再回到第1步。

未来想象方面,虚拟人接入GPT可以实现更加智能化、个性化的服务,可以预见的是,未来的虚拟人将更加人性化,通过情感计算等技术,可以实现更加真实、自然的人机交互。虚拟人还可以与物理机器人结合,成为未来的机器人助手,为人们的生活和工作提供更加便利的服务。

5 Github源码

  1. ChatGPT虚拟直播源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22875.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从腾讯实时音视频发家史,看爆发中的 RTC 将何去何从

作者 | 夕颜 头图 | 下载于视觉中国 出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09; 早在2015年左右&#xff0c;直播和短视频的兴起渗透进普通人的日常生活&#xff0c;人们信息消费的内容已经开始从文字向语音、视频信息转变。而疫情期间全民“家里蹲”的窘境&am…

腾讯云html5直播开发,腾讯云IM开发 直播 聊天室

2019年6月工作总结 总结时间&#xff1a;2019年6月30日 总结人&#xff1a;韩放 工作内容&#xff1a; 1.哟呵直播开发 2.一乙农场客服商品对接 项目总结&#xff1a; 这个月主要是又做了一个直播类项目&#xff0c;这次主要的不同是根据客户的定制要求完全使用了腾讯IM加腾讯云…

微信团队分享:微信直播聊天室单房间1500万在线的消息架构演进之路

本文由微信开发团队工程师“ kellyliang”原创发表于“微信后台团队”公众号&#xff0c;收录时有修订和改动。 1、引言 随着直播和类直播场景在微信内的增长&#xff0c;这些业务对临时消息&#xff08;在线状态时的实时消息&#xff09;通道的需求日益增长&#xff0c;直播…

有哪些值得关注的AIGC细分方向?

&#xff08;以下内容&#xff0c;来自咱们社群“AI产品经理大本营” 1月12日的团员内部讨论&#xff1b;本文不求大而全&#xff0c;但会有一些大家“没听说过的一手信息input”&#xff09;‍‍‍‍ 【参与团员】 A&#xff1a;某司 负责 AIGC B&#xff1a;某司 负责 医疗AI…

音视频技术开发周刊 | 282

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 畅谈音视频未来无限可能&#xff0c;2022音视频技术大会北京站 最新日程公布 2023年3月31日-4月1日&#xff0c;LiveVideoStackCon 2022音视频技术大会北京站&#xff0c;…

chatgpt赋能Python-python_cdo

Python-CDO: 数据处理的超棒工具 Python-CDO是一种极为实用的工具&#xff0c;用于在Python中使用CDO&#xff08;Climate Data Operators&#xff09;命令。CDO是一个功能强大的工具&#xff0c;用于处理气候和气象大型数据集&#xff0c;如Satellite and Reanalysis数据。而…

时间序列分析——基于R | 第2章 时间序列的预处理习题代码

时间序列分析——基于R | 第2章 时间序列的预处理习题 1.考虑序列{1,2,3,4,5,…,20} 1.1判断该序列是否平稳 x <- seq(1,20);x ## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1.2样本自相关系数 max_lag <- 6 acf_x <- acf(x, lag.max max_l…

Google 人机验证(reCaptcha)无法显示解决方案

Google 人机验证无法显示解决方案 第一步 安装插件Chrome/Edge 电脑版Firefox 电脑版 第二步 配置插件原理参考文章 前言&#xff1a;为了防止机器人攻击&#xff0c;国外很多网站都使用了 Google reCaptcha 验证码。reCaptcha 对于国外用户非常的友好&#xff0c;但是… 对于国…

解决谷歌人机验证(Captcha)显示问题

文章目录 前言一、Header Editor 下载、安装与配置1. 插件下载2. 插件安装3. 插件配置 前言 由于谷歌服务在国内不可用&#xff0c;所以正常访问时某些网址时&#xff0c;经常会出现需要人机验证的问题&#xff0c;影响正常使用。在不使用科学上网的情况下&#xff0c;我们可以…

利用Python解决掉谷歌人机验证,全自动识别真的牛啊

一、接触前感受 第一次带我领略yolov5风骚的是这个视频&#xff1a;【亦】警惕AI外挂&#xff01;我写了一个枪枪爆头的视觉AI&#xff0c;又亲手“杀死”了它。 这样一来&#xff0c;我对人工智能打游戏产生了浓厚的兴趣&#xff0c;于是在B站查找人工智能基础&#xff0c;随便…

【开源项目】ChatGPT智能聊天系统后台管理解析

ChatGPT是likeshop近期新研发出来的一款AI智能聊天对话的产品&#xff0c;此系统是基于likeadmin-PHP开发的智能对话系统&#xff0c;ChatGPT是一种基于人工智能技术的聊天机器人&#xff0c;它可以与用户进行自然语言对话&#xff0c;提供各种服务和答案。ChatGPT的核心技术是…

checkra1n越狱工具下载地址

https://checkra.in/releases/ 虚拟机 checkra1n -26和-31错误 不支持虚拟机,需要在黑苹果&#xff0c;Ra1nUSB&#xff0c;Linux下越狱 AMD的黑苹果&#xff0c;错误&#xff0d;31&#xff0c; AMD的CPU使用checkra1n越狱黑苹果会报错-31 适用系统iOS13-13.3.1基本都是…

RabbitMQ快速实战以及核心概念详解

RabbitMQ快速实战以及核心概念详解 一、MQ介绍 1、什么是MQ&#xff1f;为什么要用MQ&#xff1f; ChatGPT中对于消息队列的介绍是这样的&#xff1a; 什么是消息队列 消息队列是一种在应用程序之间传递消息的技术。它提供了一种异步通信模式&#xff0c;允许应用程序在不同…

闰秒终于要取消了!一文详解其来源及影响

导读 | 第27届国际计量大会宣布最迟不晚于2035年取消引入闰秒&#xff0c;这一消息引起轰动。上一次闰秒产生&#xff0c;对Reddit、Mozilla、FourSquare等都产生了一定的问题&#xff0c;其中Reddit宕机时间超过1个半小时&#xff01;本栏目特邀腾讯后台开发工程师陶松桥&…

GPT-5暂时来不了 OpenAI悄然布局移动端

OpenAI彻底用GPT-4带火自然语言大模型后&#xff0c;互联网科技行业的大头、小头都在推出自家的大模型或产品。一时间&#xff0c;生成式AI竞速赛上演&#xff0c;“吃瓜群众”也等着看谁能跑赢OpenAI。 坊间预测&#xff0c;干掉GPT-4的还得是GPT-5。结果&#xff0c;OpenAI的…

悄然招募移动端工程师 OpenAI矛头调向移动端

2022年底&#xff0c;人工智能程序ChatGPT爆火&#xff0c;上线短短两月&#xff0c;就获1亿月度活跃用户&#xff0c;成为历史上增长最快的面向消费者的应用。随后全球的科技巨头都热火朝天地入局自然语言大模型赛道。不过推出ChatGPT的人工智能巨头OpenAI目前并不打算训练GPT…

马斯克宣布打造 ChatGPT 竞品!OpenAI CEO 给他泼了一盆冷水,GPT-5 或将大变

无脑增加 模型规模 已经落伍 当你在 ChatGPT 或者新 bing 里输入一个问题&#xff0c;AI 会调用它的云端大脑&#xff0c;思索一番&#xff0c;生成一段较为合理的回答。 而在 OpenAI 开发 GPT 时&#xff0c;也反复提到了参数正变得庞大&#xff0c;模型的规模也在逐代变得复…

死磕数据库系列(二十六):MySQL 高可用之单主、双主模型组复制配置实践

点关注公众号&#xff0c;回复“1024”获取2TB学习资源&#xff01; 前面我们学习&#xff1a;MySQL 高可用之组复制&#xff08;MGR&#xff09;技术的相关原理知识&#xff0c;今天我将详细的为大家介绍 MySQL 高可用技术组复制的单主、双主两种模型下的原理及配置相关知识&a…

chatgpt赋能python:Python中三角函数的使用

Python中三角函数的使用 介绍 Python是一种非常流行的编程语言&#xff0c;因为它非常易于学习和使用。Python中有很多实用的库和模块&#xff0c;可以帮助开发人员更轻松地完成各种任务。其中包括Python的数学库&#xff0c;其中包括三角函数。 三角函数是最基本的数学函数…

断网了,还能ping通 127.0.0.1 吗?[localhost与127.0.0.1区别]

1.应用场景 主要用于学习了解localhost 与 127.0.0.1的区别&#xff0c; 本质. 以及计算机关于本机地址是如何工作的。 为什么要有这个地址。 2.学习/操作 1.文档阅读 断网了&#xff0c;还能ping通 127.0.0.1 吗&#xff1f; 开发环境- 配置虚拟主机域名/hosts文件 2.整理输…