Unity--GPT-SoVITS接入、处理GPTAPI的SSE响应流

GPT-SoVITS

GPT-SoVITS- v2(v3也可以,两者对模型文件具有兼容)

点击后 会进入新的游览器网页

-----

看了一圈,发现主要问题集中在模型的训练很需要CPU,也就是模型的制作上,问题很多,如果有现有的模型,直接引用,使用“推理”即可

基于GPT-SoVITS一键包的合成语音基础 - 哔哩哔哩

就比如用GPT-SoVITS 一色彩羽语音模型分享_哔哩哔哩_bilibili

这个up主练出来的模型

自己要做的其实就很少了

导入之后重启webui.bat

再开启TTS推理WebUI,就进入了UI界面,自己点击交互设置,然后产出结果可以直接用

但这是SoVITS的界面交互,想在unity里使用,必须要用提供的API(不同于网络API的本地API,不需要联网,可以直接处理)

【unity+gpt-sovits接口集成】AI二次元小姐姐项目集成gpt-sovits的api模块,可以实现局域网的丝滑互动了_哔哩哔哩_bilibili

这个up的项目现在也在维护,进项目里了解是可以的,但是在里面的使用过程总是有一些报错,想解决比较麻烦

但是还是可以了解重要的区域是哪一块,哪里要改

而且up对功能的拆分也很不错,LLM类和TTS类分开,大概率是用了继承,然后下面的多个模型都可以使用,在各自里写网络传递请求的方法

---

GPT-SoVITS教程5-如何调用API_哔哩哔哩_bilibili

ViTS的Api调用,是和webui分开的一种更偏向接口功能切割,整块提供的,所以只需要api.bat文件打开,就可以连接api了

对于这个http

http://localhost:9880/docs用这个代替才能进fastapi

然后就进入了api的模块,,这里有参数设置然后自动生成请求格式的

这里的路径是可以填绝对路径的

prompt都是传入的材料的

之后的text则是需要生成的文本、语言(再后面的可以调整也可以不动)

api的格式,,在这生成的是一模一样的

URL 传输时,会对特殊字符进行 百分号编码(Percent-Encoding),比如:

  • \(反斜杠) → %5C
  • :(冒号) → %3A
  • 日文、中文等非 ASCII 字符 会用 UTF-8 编码 转成 %E7%等形式
  • 空格%20

所以会出现乱码一样的情况,但是信息没有变

把这一段直接粘贴到游览器,可以直接得到生成 的音频文件,

(换行清晰格式
localhost:9880/
?refer_wav_path=D%3A%5CBaiduNetdiskDownload%5CUnity_Related%5CIroha%5C参考音频%5C测试参考音频%5C001.私としては奉仕部が協力してくれるのが一番%E3%80%80面倒がないんです.wav
&prompt_text=私としては奉仕部が協力してくれるのが一番%E3%80%80面倒がないんです
&prompt_language=日文
&text=コネクタの使い方すら知らないなんてバカなの?
&text_language=日文
&top_k=15
&top_p=1
&temperature=1
&speed=1

TITS里的切分,是为了生成的时候不跳字吞字而切分的

但是默认的基础api里是不切分的,很容易出现问题

那问题来了,我要怎么整合到unity里用,通过这个网站上的这种格式简化肯定不现实

下面是api的注释内容,

基于 HTTP 请求的语音合成 API,支持 GETPOST 请求,并返回音频流或 JSON 结果。

在 Unity 里调用它,需要构建 HTTP 请求 并处理 返回的音频数据

简单测试的,用GET 请求,参数放在 URL 里(可见),要传的数据量少
URL 可直接访问,可以用浏览器打开测试

POST 请求,参数放在请求体里(Body),不会出现在 URL,不能用游览器打开
适用于复杂请求(大数据/JSON)浏览器不会缓存,数据不会暴露在 URL
支持 JSON、文件上传等复杂数据

直接按照api注释里的来不行

在unity中要使用http,在这里改成allow,,默认是为了安全不允许使用的

改了之后,就可以收到并和api产生交互了

本来以为这些填进去的东西一次只能一填,但并不是这样的

这个网站 是api文档,,对传输的输入字符串 的格式规则的介绍

并没有什么很复杂的地方

要做的是在unity的C#脚本里调用传入这段字符串的时候,这段字符串是符合格式的,是可以丢给UnityWebRequest去做访问请求,并且拿到返回的数据的

也就是说,在APi文档介绍下,我复制这种格式,然后把需要的部分变成变量,其实就已经可以做到APi较好的交互了

现在unity里已经可以发出声音了,,不过这个效果的确是一言难尽,

原来那些B站上发视频这么像的,都是自己一句一句挑最好的表现出来,,

那确实很肝,

---

处理GPTAPI的SSE响应流

功能是串通了,可以做到输入文本并且朗读出来了

但是没有使用流,  等待文本彻底发回----将文本整个进行TTS,有较长的等待周期,(对于DeepSeek这点更加严重,GPT回复的相对更快,两者的API文档差距并没有很多,接下来还是以GPT的API调用来develop)

为了改进,所以先去了解一下gpt的api调用里,是怎么规定实现流的传输的

想让GPT一边生成文本,TTS立刻 解析并且读出来

对于这个的解决方案就是多种的

比如GPT每生成一段文本到逗号和句号的位置,TTS就拆开了一段,并且解析成需要播放的资源

GPT生成文本的速度一般快于TTS转--读的速度,那是否需要一个queue来装载后续的每个文件,然后一直播放?这样会不会出现语句衔接不自然的问题?(但现在主要是解决等待问题,这一方面可以不考虑)

--

先是得到SSE的响应,这在OpenAI的API请求上有变化

下面是第一次成功用cmd接收了SSE响应的格式

curl -N -X POST "https://api.openai.com/v1/chat/completions" ^-x http://127.0.0.1:7890 ^-H "Authorization: Bearer sk-你的API密钥" ^-H "Content-Type: application/json" ^-H "Accept: text/event-stream" ^-H "Cache-Control: no-cache" ^-d "{ \"model\": \"gpt-4o\", \"messages\": [ { \"role\": \"user\", \"content\": \"和我讲讲陶喆是谁\" } ], \"stream\": true }"

这里坑最多的还是curl的测试,对语法的忽视,而这一点AI同样经常忽视

换行符,在很多地方粘贴为了美观会自动加上(或者自动删除没有内容的连续空格),这就让curl真的没有用都浑然不知,,比如我粘贴到了CSDN上,然后再复制,就不能在cmd窗口运行了

所以很有必要了解cmd的书写规则


cmdEnter 解析为命令的结束换行必须用^(^ 后面不能有多余的空格)

路径中有空格,必须用双引号包裹( -d 里JSON 里的空格不影响

curl 允许多个空格,但少部分情况下会出现问题,

出现More?的时候才是说明你是想为了美观用 ^换行了,本质上还是一串黏在一起的

在之后的测试里(注意这里^后面的空格是为了分开,在cmd里绝对不能加)

-X POST  并不必要特意声明post请求类型

-N 也不必要特意声明是(逐行读取流式数据,对于curl)

-x http://127.0.0.1:7890 ^  至关重要 这段对代理的引用,在cmd里curl发送请求给服务器(应该是cmd自己的问题,curl总是不按照代理的来走,手动set Proxy代理也出问题)

-H "Accept: text/event-stream" ^    这个也并不重要,可以去掉

-H "Cache-Control: no-cache" ^    这句也不重要(大部分应该都是openai的api网站已经配置好了)

最后保留的的确只有官方文档里的了curl请求格式了(注意一下换行符和空格)

-------curl可以访问之后,是想c#如何可以接收这种持久输出的格式--

可以接受响应了(apikey的粘贴复制容易出现一些莫名其妙的误差,会提示unauthorized就说明响应是没问题的,只是apikey有格式的问题,去了解一下key传过来的复制粘贴会不会额外动里面的数据)

在请求根据官方api格式发了之后,

 目前接受响应的办法,但是这些都是一次性发送到unity的,没有做到逐条更新var response = await httpClient.PostAsync(apiUrl, new StringContent(jsondata, Encoding.UTF8, "application/json"));Debug.Log(response.StatusCode);Debug.Log(response.Content.ReadAsStringAsync().Result);using (var stream = await response.Content.ReadAsStreamAsync())using (var reader = new StreamReader(stream, Encoding.UTF8)){string line;while ((line = await reader.ReadLineAsync()) != null){if (line.StartsWith("data:")){string data = line.Substring(5);// 在这里处理接收到的数据Debug.Log(data);}}}

完结,HttpClient.SendAsync 方法 (System.Net.Http) | Microsoft Learn

的确是因为httpclient本身的方法里没有可以设置接受请求头就返回的方法

要换成SendAsync(HttpRequestMessage requst)

必须 自己构建这个Message的内部消息,让httpclient帮忙发送

整个完整的函数,在各个类功能正常运行的情况下逻辑一定是没问题的(如果有问题就检查自己的httpclient要不要额外设置代理Proxy,还有就是apikey的复制粘贴可能自动修改内容的问题)

 async Task GetChatStream(string userInput){// 请求的 JSON 数据var requestData = new{model = "gpt-4",messages = new[]{new { role = "system",content = CharacterSetting },new { role = "user", content = userInput }},stream = true};string jsondata = JsonConvert.SerializeObject(requestData);// Print the complete request in a format that can be used directly with curl//string curlCommand = $"curl -X POST \"{apiUrl}\" -H \"Authorization: Bearer {apiKey}\" -H \"Content-Type: application/json\" -d '{jsondata}'";Debug.Log("jsondataBody_Ready");var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, apiUrl){Content = new StringContent(jsondata, Encoding.UTF8, "application/json")};httpRequestMessage.Headers.TryAddWithoutValidation("Authorization", $"Bearer {apiKey}");//*****************************************var response = await httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead);Debug.Log("response.StatusCode:" + response.StatusCode);//Debug.Log(response.Content.ReadAsStringAsync().Result);using (var stream = await response.Content.ReadAsStreamAsync()){//  Debug.Log("stream");using (var reader = new StreamReader(stream, Encoding.UTF8)){// Debug.Log("reader");string line;while ((line = await reader.ReadLineAsync()) != null){//  Debug.Log("line");if (line.StartsWith("data:")){string chunkdata = line.Substring(5);// 在这里处理接收到的数据var openAIChunk = JsonConvert.DeserializeObject<OpenAIChunk>(chunkdata);Debug.Log(openAIChunk.Choices[0].Delta.Content);text.text += openAIChunk.Choices[0].Delta.Content;}}}}}

优化整理

需要的功能:玩家的对话,AI记得聊天历史

项目启动的时候自动打开SoVITS,可以的话不要显示控制台

目前暂时定这两个需求

之后的打算:把这个2d的交互场景设置到3D场景里,在3D的场景里实现这个2D窗口的所有功能

---

目前先做一个Scroll view,可以滚动查看聊天记录

配置好了,接下来接入SoVITS,还有角色动嘴

Process 类 (System.Diagnostics) | Microsoft Learn

//关于SoVITS的API打开,想了一下还是不管窗口显隐的问题了,还有打开会需要10秒左右的时间,不能产生空判断,这一段的过程比较重复,是一些使用信息的积累,可以做但是还是先管更重要的东西

---所以接下来都假设在SoVITS已经打开好的条件下(正常来说游戏的进入动画就可以把这些给做了,我在这做了也不知道实际如何)

Process类也不用了,直接到队列读取那一块了

这里把对话内容的 实时更新Text组件 和  拆分句子给SoVITS去转换成audioClip文件播放  分开

而且返回的响应一般是一个字的居多,也就不考虑一次来的响应里有多个字符,标点在前面了

很好,看的到播放的队列正常更新了,Clip队列也一直在运作 

现在就差口型的绑定了,这一部分就直接绑定audioSource就可以了

就会根据音量调整嘴巴的闭合

存在嘴巴没有跟着张开的情况,这里的模式调整为override,就可以避免视线 追踪 对2D模型的动画状态一直在调整

这里是调整声音大小的标准,让嘴巴在正确的区间里开闭

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

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

相关文章

《TypeScript 快速上手:类型、编译与严格模式的简明教程》

一、TypeScript介绍 在引入编程社区 20 多年后&#xff0c;JavaScript 现在已成为有史以来应用最广泛的跨平台语言之一。JavaScript 最初是一种用于向网页添加微不足道的交互性的小型脚本语言&#xff0c;现已发展成为各种规模的前端和后端应 用程序的首选语言。虽然用 JavaSc…

ROS2 系统架构

1.操作系统层 ros2是基于Linux、Windows、macOS系统建立的&#xff0c;这一层为ros2提供了各种基础的硬件驱动&#xff0c;比如网卡驱动&#xff0c;常用USB驱动和常用摄像头驱动等。 2.DDS实现层 ros2的核心通信是采用第三方的通信组件来实现的&#xff0c;这个第三方就是数…

【HTML】二、列表、表格

文章目录 1、列表1.1 无序列表1.2 有序列表1.3 定义列表 2、表格2.1 定义2.2 表格结构标签2.3 合并单元格 1、列表 列表分为&#xff1a; 无序列表有序列表定义列表&#xff1a;一个标题下有多个小分类 1.1 无序列表 ul嵌套li&#xff0c;ul是无序列表&#xff0c;li是列表…

redis zset基本介绍以及底层实现

ZSet&#xff08;Sorted Set&#xff09;有序集合 介绍 Redis 中的有序集合(Sorted Set)是在集合(Set)的基础上,为每个成员关联了一个分数(score)。这个分数可以用来对集合中的成员进行排序。 有序集合保留了集合不能有重复成员的特性&#xff08;成员不能重复&#xff0c;分值…

政策助力,3C 数码行业数字化起航

政策引领&#xff0c;数字经济浪潮来袭 在当今时代&#xff0c;数字经济已成为全球经济发展的核心驱动力&#xff0c;引领着新一轮科技革命和产业变革的潮流。我国深刻洞察这一发展趋势&#xff0c;大力推进数字化经济发展战略&#xff0c;为经济的高质量发展注入了强大动力。 …

IntelliJ IDEA 快捷键系列:重命名快捷键详解

目录 引言一、默认重命名快捷键1. Windows 系统‌2. Mac 系统‌ 二、操作步骤与技巧1. 精准选择重命名范围‌2. 智能过滤无关内容‌ 三、总结 引言 在代码重构中&#xff0c;‌重命名变量、类、方法‌ 是最常用的操作之一。正确使用快捷键可以极大提升开发效率。本文针对 ‌Ma…

文档搜索引擎

首先获取很多网页(爬虫->一个http客户端,发送http请求获取http响应结果(就是网站))(批量化的获取很多的页面) 再根据用户输入的查询词,在网页中进行查找 用户输入查询词之后,如何让查询词和当前这些网页进行匹配 ->使用倒排索引 倒排索引 1.文档: 每个待搜索的网页(被爬…

开源工具利器:Mermaid助力知识图谱可视化与分享

在现代 web 开发中&#xff0c;可视化工具对于展示流程、结构和数据关系至关重要。Mermaid 是一款强大的 JavaScript 工具&#xff0c;它使用基于 Markdown 的语法来呈现可定制的图表、图表和可视化。对于展示流程、结构和数据关系至关重要。通过简单的文本描述&#xff0c;你可…

C# --- LINQ

C# --- LINQ 什么是LINQFluent Syntax 和 SQL-Like QueryLINQ Operations 什么是LINQ LINQ的全称为Language Integrated Query, 为各种查询(包括对象查询&#xff0c;数据库查询&#xff0c;XML查询) 提供了统一模型.LINQ源于SQL&#xff0c;但比SQL更加强大&#xff0c;更加灵…

【AI News | 20250316】每日AI进展

AI Repos 1、ReActMCP 将网络搜索能力集成到AI助手中的一个MCP服务&#xff1a;ReActMCP Web Search&#xff0c;相当于给AI装了个搜索引擎&#xff0c;可以实时查找最新的内容。它基于Exa API执行基本和高级网络搜索&#xff0c;高级搜索比如限制搜索的网站范围、指定日期范围…

【VUE】day04-组件的生命周期、组件之间的数据共享、ref引用、购物车案例

【VUE】day04-组件的生命周期、组件之间的数据共享、ref引用、购物车案例 1. 组件之间的关系2. 使用组件的三个步骤3. vue.components全局注册组件4. 自动生成右边标签插件5. 组件的props6. 结合v-bind使用自定义属性7. props的默认default值8. type值类型9. 组件之间的样式冲突…

Redis分布式锁深度剖析:从原理到Redisson实战,破解脑裂与高并发锁难题

一、&#x1f4cc; 分布式锁的核心应用场景 场景类型典型案例风险说明&#x1f680; 高并发场景电商秒杀、票务抢购库存超卖风险⏰ 定时任务场景集群日志清理、数据统计任务重复执行&#x1f504; 幂等场景支付接口重试、订单创建资金重复扣款 二、&#x1f527; Redis分布式锁…

量化交易学习笔记02:双均线策略

双均线策略示例 个股&#xff1a;中国平安 回测日期&#xff1a;2022-5-1至2023-5-1 短均线&#xff1a;5天 长无线&#xff1a;10天 代码&#xff1a; def initialize(context):# 初始化此策略# 设置我们要操作的股票池, 这里我们只操作一支股票# """标的&qu…

交换机控制软件的实现步骤猜测

一、主要目的 提出对交换机软件控制逻辑的猜测。 二、交换机控制软件的组成 (一)背景 1、交换机有很多的RJ45水晶头端口。 2、每个端口支持同时发送和接收字节数据。 3、每个端口接收的数据需要查表后才能转发给目标端口。 (二)端口状态扫描线程 负责扫描每个端口的状态&#x…

Part1:基于国内源完成Kubernetes集群部署

集群规划 操作系统&#xff1a;CentOS7 内核版本&#xff1a;5.4&#xff08;需升级&#xff09; 组件版本说明操作系统内核5.4RPM方式升级docker26.1.4yum安装cri-docker0.3.16二进制安装kubeadm1.30.11yum安装kubealet1.30.11yum安装kubectl1.30.11yum安装kubectl1.30.11yu…

中考英语之10难点单词

A abandon ~动词&#xff0c;意为 “抛弃&#xff1b;放弃”。 ~例如 He abandoned his old bike by the roadside.&#xff08;他把他的旧自行车扔在路边。&#xff09; absolute ~形容词&#xff0c;“绝对的&#xff1b;完全的”。 ~例如 We have absolute trust in him…

【GPT入门】第24课 langfuse介绍

【GPT入门】第24课 langfuse介绍 1. langfuse概念与作用2. 代码3. 页面效果4. 设计模式1. 装饰器模式2. 上下文管理模式1. langfuse概念与作用 Langfuse是一款专为大规模语言模型(LLM)应用开发设计的开源平台。其作用主要包括以下几个方面: 提升开发效率:通过消除LLM应用构…

在 React 中使用 Web Components 的实践操作

前言 在现代前端开发中&#xff0c;React 和 Web Components 都是广泛使用且备受欢迎的技术。React 是一个用于构建用户界面的 JavaScript 库&#xff0c;提供了组件化的开发方式和高效的状态管理&#xff0c;而 Web Components 是一套原生的浏览器技术标准&#xff0c;允许开…

C++单例模式精解

单例模式&#xff08;重点*&#xff09; 单例模式是23种常用设计模式中最简单的设计模式之一&#xff0c;它提供了一种创建对象的方式&#xff0c;确保只有单个对象被创建。这个设计模式主要目的是想在整个系统中只能出现类的一个实例&#xff0c;即一个类只有一个对象。 将单…

【微服务】java中http调用组件深入实战详解

目录 一、前言 二、http调用概述 2.1 什么是http调用 2.1.1 http调用步骤 2.2 HTTP调用特点 2.3 HTTP调用应用场景 三、微服务场景下http调用概述 3.1 微服务开发中http调用场景 3.2 微服务组件中http的应用 四、常用的http调用组件 4.1 java中常用的http组件介绍 4…