Unity接入ChatGPT基于Python.Runtime的实现

目录

前言

编译Python.Runtime.dll

Unity接入ChatGPT

1.第一步 准备环境

2.第二步 python代码的书写

3.第三步 C#调用python代码


前言:

相信各位游戏人都用过ChatGPT吧,那么怎么在unity里接入ChatGPT呢?本文章会通过一种极其简单的方式来实现,最终效果如下:

  1. 可以进行中文对话,可以记住一点的上下文(实际上几乎记不住任何上下文,可能是free版本的限制吧,等拿到万事达卡再试试plus版本的)
  2. 可调节的准确率(诚恳度越低准确度越高,但是更冷漠),Ai说话时的“温度”
  3. 简单的python和c#交互

好的,下面开始教程:

编译Python.Runtime.dll

看标题可知,这是基于Python.Runtime的,所以首先要拿到这个.dll文件

github地址
GitHub - pythonnet/pythonnet: Python for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers.Python for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers. - GitHub - pythonnet/pythonnet: Python for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers.https://github.com/pythonnet/pythonnet

在GitHub上clone 下来的文件需要编译成dll文件,建议使用vs进行编译,下面是教程

用vs打开解决方案(根目录下的pythonnet.sln)

 

 在python.runtime项目上右键打开属性

  1. 将目标平台设置为x64
  2. 选择一个基路径,这个路径是你在编译好的dll文件的存放路径,是相对根目录而言的,我的就在这里面了,大家编译完成后直接在根目录里面找就好了
  3. 哦,忘记了,输出类型选择类库

 然后再次右键选择生成

 等待编译完成后即可在设置的基目录下看到这个dll文件

 然后把这个dll文件拖到unity里

 好了,准备工作已经完成,现在开始正式在Unity里接入ChatGPT!!!

Unity接入ChatGPT

首先要获取openai的api的使用权限,所以我们要有key才行

在openai的官网可以获取:key在这里弄

弄好key一定要复制好,保存好,因为一旦获取了之后,key就永久隐藏了。如果丢失了就只能再获取一次(虽然不麻烦,但是耗money呀)

ok废话介绍完毕,开始撸码,注意哦,教程是循循渐进的,代码都不是完整的,如果只想copy可以直接跳到底部复制完整代码自己看。

1.第一步 准备环境

首先引入using Python.Runtime的命名空间,设置好时间间隔,建议为20s,为啥,我也不知道,官网说的...

再就是要告诉这个插件python解释器的dll文件路径,这个很好弄,在官网上下载好python就直接能看到这个dll,还有环境变量别忘记配置了,有的大佬可能懒得登录,但是又想复制,所以我直接贴出来代码,hh

using System.IO;
using Python.Runtime;
using UnityEngine;public class PythonManager : MonoBehaviour
{// Start is called before the first frame update[SerializeField] public float _timer;private float _interval = 20;void Start(){_timer = _interval;// 获取python.all的路径(调用python解释器来执行python代码)string pythonPath = @"C:\Python311"; string dllPath = Path.Combine(pythonPath, "python311.dll");Runtime.PythonDLL = dllPath;}
}
using System.IO;
using Python.Runtime;
using UnityEngine;public class PythonManager : MonoBehaviour
{// Start is called before the first frame update[SerializeField] public float _timer;private float _interval = 20;void Start(){_timer = _interval;// 获取python.all的路径(调用python解释器来执行python代码)string pythonPath = @"C:\Python311"; string dllPath = Path.Combine(pythonPath, "python311.dll");Runtime.PythonDLL = dllPath;}
}

2.第二步 python代码的书写

这里我先说一下我的实现思路,免得大家看不懂。

我没有使用文件读取的方式来提交prompt和获取gpt回答的内容,因为我很菜,hhh,用python调用resources里的文件实在是麻烦透顶,研究了一会就放弃了,当然也可以使用绝对路径的方式来用,但是这样一打包就彻底废了,因为路径全乱了,所以干脆放弃使用文件读取的方式。然后怎么办呢???突然我想到了一个极其极其的野路子,哈哈哈哈,就是用游戏物体的名字来当临时储存“文件”,这样就方便多了,而且还不用开线程去读文件,性能也高了不少,哈哈哈哈哈快夸我。

其实呢。。。我这个文章的缺陷也很多,就是应该只能在pc上运行,我用安卓测试的时候会闪退,应该和python解释器的调用有关系,没有去研究....要是有大佬知道怎么解决的话欢迎提供解决方案哈,嘻嘻嘻嘻。

然后这是python代码的部分(纯享版,没有注释)

import UnityEngine as ue
import openai
import random
objects = ue.Object.FindObjectsOfType(ue.GameObject)
duiBaQis = []
for obj in objects:if obj.tag == 'duiBaQi':duiBaQis.append(obj)
openai.api_key = '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'
model_engine = 'gpt-3.5-turbo' 
prompt = 'hello'
temperature = random.uniform(0.1,2)
for o in duiBaQis:if('@temperature:' in o.name):temperatureStr = format(temperature,'.2f')o.name = '@temperature:' + temperatureStr;
max_tokens = 255
for o in duiBaQis:if('@prompt:' in o.name):promptText = o.name.replace('@prompt:','');prompt = promptText
completion = openai.ChatCompletion.create(model='gpt-3.5-turbo',messages=[{'role': 'user', 'content': prompt}],temperature = temperature,max_tokens = max_tokens
)
print(completion.choices[0].message.content)
for o in duiBaQis:if('@ai:' in o.name):o.name = '@ai:'+ completion.choices[0].message.content;
import UnityEngine as ue
import openai
import random
objects = ue.Object.FindObjectsOfType(ue.GameObject)
duiBaQis = []#这个数组是储存所有含有duibaqi标签的游戏物体,为了加快查找速度用的,当然要是大家熟悉python的话,应该可以使用一个全局管理器来管理每一个用到的游戏物体,这样就只需要查找一遍就行了(思路就是定义几个bool值,查找完毕后设置为false,检测到false就跳过for in 循环),但是我不太会用python,hhh,没有学过...所以就放弃了,大家完全可以不比这样做
for obj in objects:if obj.tag == 'duiBaQi':duiBaQis.append(obj)#将这三个游戏物体推进这里面,哪怕是提高一丢丢的效率也是好的...
openai.api_key = '这里填在官网拿到的key'#这里是在官网得到的key
model_engine = 'gpt-3.5-turbo' #在这里选择gpt的模型,因为不同模型的使用方法有点不同,所以这里最好和我一样,等这个实现了以后大家再去琢磨别的。
prompt = 'hello'#这里是prompt,就是大家在用ChatGPT的时候给问他的那些问题
temperature = random.uniform(0.1,2)#这里就是可调节“温度”了,也就是gpt的语气
for o in duiBaQis:#查找temperature物体if('@temperature:' in o.name):temperatureStr = format(temperature,'.2f')o.name = '@temperature:' + temperatureStr;
max_tokens = 255#这个是gpt回答内容的最大字符,因为我们用的是游戏物体的名字来存储这个数据,但是在unity里游戏物体的名字最多也就能存255个字符,所以....就这样咯。
for o in duiBaQis:#查找prompt物体if('@prompt:' in o.name):promptText = o.name.replace('@prompt:','');#需要把"@prompt:"这个字符串替换掉才能作为prompt使用,不要忘记了,不然的话prompt都成啥了,笑死。prompt = promptText
#最核心的代码,调用openai提供的api,将我们设置好的model,prompt,temperature,max_tokens参数严格按照官方文档给出的格式填入,然后用completion接受返回结果。返回的是一个对象,结构比较复杂,包含很多细节,大家有兴趣可以打印出来看看,这里我们只需要使用choices[0].message.content这个数据即可。
completion = openai.ChatCompletion.create(model='gpt-3.5-turbo',messages=[{'role': 'user', 'content': prompt}],temperature = temperature,max_tokens = max_tokens
)
print(completion.choices[0].message.content)
for o in duiBaQis:#查找ai物体if('@ai:' in o.name):o.name = '@ai:'+ completion.choices[0].message.content;#直接更改ai物体的名字为gpt回答的内容,注意前缀不要忘记加上"@ai:",因为我们不是只用一次,不要卸磨杀驴了,hhh

 代码讲解我都放在注释里面了,大家可以对照着代码一起看,我觉得还是蛮清晰的,哈哈。

 好了,python代码的部分就是这么多,还是挺简单的,下面是用c#来调用python的部分

3.第三步 C#调用python代码

string code = @"那一坨python代码"
PythonEngine.Initialize();
using (Py.GIL())
{PythonEngine.Exec(code);
}
        string code = @"那一坨python代码"PythonEngine.Initialize();using (Py.GIL()){PythonEngine.Exec(code);}

code就是刚才写的那一坨python代码 ,注意@不要忘记写了哈,不然就没法缩进。

就这么简单?对!就这么简单,哈哈哈哈。

没了,完了,调用成功了,接入完成了,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈。(博主已疯)

至于怎么gpt和游戏进行交互,怎么弄出好玩的效果,就靠各位大佬就自己发挥想象力吧~。

下面贴上我自己的代码给大家,这部分我就放在code里面了,就不贴出来凑字数了,hhh。

这是PythonManager.cs文件

using System.IO;
using Python.Runtime;
using UnityEngine;public class PythonManager : MonoBehaviour
{[SerializeField] public float _timer;private float _interval = 20;void Start(){_timer = _interval;// 获取python.all的路径(调用python解释器来执行python代码)string pythonPath = @"C:\Python311"; string dllPath = Path.Combine(pythonPath, "python311.dll");Runtime.PythonDLL = dllPath;}void Update(){_timer += Time.deltaTime;UIManager.Instance.timer.fillAmount = _timer / _interval;if (_timer < _interval) return;//控制代码执行顺序if (GameManager.Instance.canReadPy && GameManager.Instance.typeDone){ExecCode();}}public void ExecCode(){   string code = @"
import UnityEngine as ue
import openai
import random
objects = ue.Object.FindObjectsOfType(ue.GameObject)
duiBaQis = []
for obj in objects:if obj.tag == 'duiBaQi':duiBaQis.append(obj)
openai.api_key = '这里填在官网拿到的key'
model_engine = 'gpt-3.5-turbo' 
prompt = 'hello'
temperature = random.uniform(0.1,2)
for o in duiBaQis:if('@temperature:' in o.name):temperatureStr = format(temperature,'.2f')o.name = '@temperature:' + temperatureStr;
max_tokens = 255
for o in duiBaQis:if('@prompt:' in o.name):promptText = o.name.replace('@prompt:','');prompt = promptText
completion = openai.ChatCompletion.create(model='gpt-3.5-turbo',messages=[{'role': 'user', 'content': prompt}],temperature = temperature,max_tokens = max_tokens
)
print(completion.choices[0].message.content)
for o in duiBaQis:if('@ai:' in o.name):o.name = '@ai:'+ completion.choices[0].message.content;
";GameManager.Instance.canReadPy = false;GameManager.Instance.typeDone = false;_timer = 0;PythonEngine.Initialize();using (Py.GIL()){PythonEngine.Exec(code);}}
}

 这是DialogueManager.cs文件

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;public class DialogueManager : MonoBehaviour
{public static DialogueManager Instance;public string taDialogue;private float _timer;//缓冲时间private float _interval = 1.6f;private bool _writeDone;private string prompt;public GameObject promptObj;public GameObject aiObj;public GameObject temperatureObj;private void Awake(){Instance = this;}private void FixedUpdate(){//判断是不是点击完成了,如果点击了,就开始计时,然后执行readfile函数,放出ai的内容if (_writeDone){_timer += Time.deltaTime;if (_timer >= _interval){_writeDone = false;_timer = 0;ReadFile();}}}public void ReadFile(){//读取在temperature游戏物体的名字,来显示诚恳度,然后更改进度条。float temperature = float.Parse(temperatureObj.name.Replace("@temperature:", ""));GameManager.Instance.volume = temperature;//读取ai游戏物体的名字,来显示ai的内容string aiText = aiObj.name.Replace("@ai:", "");//哈哈哈,这里就体现我的菜了,不会正则,正能这样傻瓜式的校验if (aiText.Contains("AI") || aiText.Contains("ai") || aiText.Contains("语言模型") || aiText.Contains("开发") || aiText.Contains("人工智能")|| aiText.Contains("程序")){aiText = aiText.Replace("AI", UIManager.Instance.taName.text);aiText = aiText.Replace("ai", UIManager.Instance.taName.text);aiText = aiText.Replace("语言模型", "玩伴");aiText = aiText.Replace("开发", "培育出来");aiText = aiText.Replace("人工智能", "超级聪明");aiText = aiText.Replace("程序", "人");}taDialogue = aiText;Debug.Log("@ReadSuccess");StartCoroutine(Type(taDialogue));Debug.Log(taDialogue);}//这个函数是在玩家输入完毕以后调用的,用的是On End Edit事件,在input field这个组件里面可以看到public void Ask(string ask){prompt = ask;}//这个函数是按下准备按钮以后调用的,调用的是On Click事件,在button这个组件里可以看到public void WriteFile(){//加个判断条件,免得玩家们太多兴奋一直按个不停,导致我们的钱钱不断流失,哈哈哈,因为每次发请求都是要收费的呀!!!if (UIManager.Instance.timer.fillAmount < 0.99f){UIManager.Instance.warning.SetActive(true);return;}UIManager.Instance.taDialogue.text = UIManager.Instance.taName.text + "正在思考哦~";if (prompt == ""){prompt = "hello";}promptObj.name = "@prompt:" + prompt;//这里就是更改游戏物体的名字为我们设置好的prompt了,注意"@prompt:"不要忘记了,因为我们在python里是通过这个来查找的GameManager.Instance.canReadPy = true;GameManager.Instance.typeDone = true;_writeDone = true;Debug.Log("@WriteSuccess");}private IEnumerator Type(string str){UIManager.Instance.taDialogue.text = "";for (int i = 0; i < str.Length; i++){UIManager.Instance.taDialogue.text += str[i];yield return null;}}
}

既然都贴出来了,那就讲一下吧(其实都在注释里写上了),大家完全可以不用看的,就是我自己想写一下,hh,上面讲的那些就是核心了,这部分大家可以自己发挥创意的。

我的思路就是玩家可以输入文字(那个输入框),然后输入完以后会调用ask函数,然后把输入的内容传到prompt里,然后接着玩家点击小爪子(那个按钮)就会执行writefile函数(但是呢?还要先校验一下是不是在冷却时间里,我的ui改变都是在UIManager里完成的)

然后这是代码:

using System.Collections;
using UnityEngine;
using UnityEngine.UI;public class UIManager : MonoBehaviour
{public static UIManager Instance;public Image chenKenDu;private float _value;public Text youName;public Text taName;public Text taDialogue;public Image timer;public GameObject warning;public Text error;public bool useGpt;private void Awake(){Instance = this;_value = useGpt ? 2 : 200;}public IEnumerator ChangeValueToUI(){chenKenDu.fillAmount = 0;var filla = GameManager.Instance.volume / _value;var f = filla / 60;for (float i = 0; i < filla; i += f){yield return null;chenKenDu.fillAmount += f;}}
}

接着上面的讲,执行完WriteFile这个函数以后,就会把这三个bool值改成true,一旦为true了,PythonManager里马上就会检测到,然后执行ExceCod函数,运行python代码。这个时候_writeDone也成true了,然后开始计时,计时1.6s以后执行readfile函数,读取游戏物体的名字,然后在UI里显示出来。

至此,ChatGPT的接入就完全结束了,感谢大家能读到  3.第三步 C#调用python代码 或者能坚持读到这里,哈哈哈,那就不浪费大家时间了,就这样,结束!拜拜!

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

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

相关文章

2023全新ChatGPT网页程序源码V4.2版本+支持用户付费套餐/有后台模块

正文: 4.2版本来了&#xff0c;优化新增了不少东西&#xff0c;安装简单 安装教程: 搭建宝塔 解析域名 上传程序至根目录 配置数据库信息:lib/config.php 导入数据库 PHP选择:7.3 访问网页即可&#xff01; 配置APIKEY&#xff0c;登录网站后台自定义配置&#xff0c…

基于uni-app+vue3跨端「h5+小程序+App」仿制chatGPT模板实例

uni-chatgpt 一款uniappvite4uview-plus多端ChatGPT模板实例。 全新首发的一款多端仿制chatgpt智能对话实战项目&#xff0c;基于uniAppVue3PiniauViewUIMarkdownIt等技术开发搭建项目。支持编译到h5小程序APP端&#xff0c;支持markdown语法解析及代码高亮。 功能特点 全屏沉…

论文查重平台对比

备注 普通本科、计算机专业软件开发论文学校要求维普查重论文包括文字、数据文字&#xff08;不是图片&#xff09;、图片、表、代码Word显示字数1.42W&#xff0c;实际字符数&#xff08;计空格&#xff09;为2.66W论文内容包括&#xff1a;摘要、绪论、系统需求分析、系统总…

什么查重软件比较好用?

原创性论文不仅是新的阐释空间&#xff0c;也是新理论的生长空间。 由于创新要素的聚集&#xff0c;必然会产生一系列原创性成果&#xff0c;成为新思想、新知识、新技术、新产品和新模式的发源地。但是&#xff0c;在保持研究热度的同时&#xff0c;我们必须追求实质性的理论…

使用ChatGPT写代码写论文教程小白免费使用教程

使用教程请看https://blog.csdn.net/qq_38735017/article/details/128874172?spm1001.2014.3001.5501

免费idea插件Boit (ChatGPT)

推荐一款免费idea插件Boit &#xff08;ChatGPT&#xff09; Bito是一款在IntelliJ IDEA编辑器中的插件&#xff0c;Bito插件是由ChatGPT团队开发的&#xff0c;它是ChatGPT团队为了提高开发效率而开发的一款工具。ChatGPT团队是一支专注于自然语言处理技术的团队&#xff0c;…

CHATGPT-4模型免费使用研究报告

GPT-4是一个多模态大型语言模型&#xff0c;使用了1.5万亿个参数&#xff0c;比GPT-3.5增加了10倍&#xff0c;也是目前世界上最大的人工智能模型。 它可以接受文本、图像、音频等多种输入&#xff0c;并生成相应的输出。还使用了一种后训练对齐的方法&#xff0c;通过与人类专…

在电脑上剪辑视频用什么工具,视频制作和剪辑工具

在进行短视频创作时&#xff0c;必不可少的便是剪辑工具。在电脑上剪辑视频用什么工具&#xff1f;今天小编就带大家了解几款日常使用中性价比较高的几款视频剪辑工具。 工具一&#xff1a;Adobe Premiere&#xff08;Pr&#xff09; Adobe Premiere是一款很常用的视频编辑工具…

如何视频剪辑制作?几个剪辑软件分享

如何视频剪辑制作&#xff1f;不知道大家平时会不会上网观看短视频&#xff0c;我们都知道很多博主都会拍摄短视频剪辑成片&#xff0c;发布在自己的账号上。那么为什么他们的视频可以剪辑的那么流畅呢&#xff1f;究其原因是他选择了好用的视频剪辑软件。这里小编就来给大家分…

有没有免费的视频剪辑软件?快来看看这些视频裁剪软件

我们有时候将视频拍好后&#xff0c;会觉得视频中有些画面的边缘出现了瑕疵&#xff0c;就想要将那些边缘裁剪掉&#xff0c;但是却不知道要怎么操作才能裁剪视频的画面。其实想要裁剪视频的画面很简单&#xff0c;我们只需要借助一些视频处理工具就可以实现裁剪视频画面的操作…

Shotcut软件中如何剪辑视频文件(截取其中一段)

https://jingyan.baidu.com/article/6181c3e04cb025542ff15331.html 在计算机中&#xff0c;打开Shotcut软件&#xff0c;并鼠标左键单击【新建文件】&#xff0c;如下图所示。 然后&#xff0c;鼠标左键单击菜单下【时间轴】&#xff0c;如下图所示。 接着&#xff0c;在窗口…

ShotCut——视频处理剪辑神器

官网&#xff1a;https://www.shotcut.org/ Shotcut 是一款由外国人开发的视频剪辑软件&#xff0c;功能强大且免费&#xff0c;相比 PR 冗杂的安装包&#xff0c;它虽只有 100 多兆&#xff0c;却能够做出媲美与 PR 效果的视频。对剪辑小白非常友好&#xff01; 多种内置滤镜特…

视频剪辑软件哪个好用?快把这些软件收好

现如今自媒体行业正在如火如荼的发展&#xff0c;越来越多的人加入进视频剪辑的队伍中。小伙伴们也有萌生想要剪辑视频的念头吗&#xff1f;大家是否苦于不知道该如何视频剪辑呢&#xff1f;为了帮助大家解决这个问题&#xff0c;今天我就来为大家教几种不错的剪辑方法&#xf…

如何在电脑上剪辑视频?自用多年的软件分享

如何在电脑上剪辑视频&#xff1f;如今会剪辑视频已经不是什么奇怪的事情了&#xff0c;除了专业的剪辑师之外&#xff0c;我们其他人也是就可以进行视频剪辑的。可能许多小伙伴们觉得视频剪辑十分困难&#xff0c;是因为没有找到一款合适的剪辑软件。今天小编就来给大家介绍一…

剪辑视频软件哪个好?快来试试这几个方法

剪辑视频软件哪个好&#xff1f;现如今短视频发展十分迅速&#xff0c;剪辑视频作为我们日常必备的技能之一&#xff0c;还是十分重要的。那么我们在剪辑视频的时候选择一个合适的剪辑软件就显得尤为重要。这里小编就来给大家分享几款好用的视频剪辑软件&#xff0c;希望能对大…

开源跨平台视频编辑器 Shotcut 22.06.23 下载安装

Shotcut 是一款免费、开源、跨平台的视频编辑器&#xff0c;适用于 Windows、Mac 和 Linux。 主要功能包括支持多种格式&#xff1b; 无需导入意味着原生时间线编辑&#xff1b; Blackmagic Design 支持输入和预览监控&#xff1b; 和分辨率支持到 4k。&#xff08;开源跨平台视…

七大视频剪辑软件,达人必备,你用过几个?

随着自媒体和短视频时代的到来&#xff0c;越来越多的人参与其中&#xff0c;各大平台短视频内容层出不穷。找一款实用的视频编辑软件是很有必要的。如果你还在为视频剪辑而迷茫&#xff0c;不知道如何选择剪辑软件&#xff0c;那么今天这篇文章你一定要读一读&#xff01; 首…

如何将电脑中的视频进行剪辑?电脑视频剪辑工具哪个好

如何将电脑中的视频进行剪辑&#xff1f;对于不同的人剪辑视频的需求也是不一样的&#xff0c;很多人一说到视频剪辑就会想到pr这样一款专业级的视频剪辑工具&#xff0c;的确很多的视频经过pr的处理过后&#xff0c;都会变得非常的精良&#xff0c;但是pr的入门门槛有点高&…

c#实现视频的批量剪辑

篇首&#xff0c;完全没有技术含量的帖子&#xff0c;高手略过&#xff0c;只为十几年后重新捡起的我爱好玩玩。。。 起因&#xff0c;一个朋友说他下载了很多短视频&#xff0c;但只需要要其中的一小截&#xff0c;去头掐尾&#xff0c;在软件里搞来搞去太麻烦&#xff0c;让…

你可以跟 ChatGPT 视频聊天了!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 2010 年&#xff0c;苹果公司正式推出 FaceTime&#xff0c;一款可以让你与朋友直接进行视频通话的聊天软件。 只要你的朋友也使用苹果设备&#xff0c;例如 iPhone、Mac、iPad&#xff0c…