ChatAudio 通过TTS + STT + GPT 实现语音对话(低仿微信聊天)

news2025/6/16 13:46:34

de9442a866ef46a5460bfed079cdf577.png

效果图

什么是 STT 和 TTS?

  • STT 是语音转文字(Speech To Text)

  • TTS 是文字转语音(Text To Speech)

为什么要使用 SST + TTS 如果用户直接输入音频,OpenAIAPI 中并没有直接使用语音和 GPT 进行对话的功能。

所需依赖

  • express

  • express-fileupload

  • openai

  • websocket

  • nodemon

  • dotenv

实现语音转文字(STT)

前面说到了,OpenAI 中不存在这种 API,但是提供了一个 Whisper 机器人,支持将音频流转化为文本,也就是 STT

648849aa03121ddf06918beb400fb692.png

实现如下返回的 text 就是识别的语音内容

const {
   data: { text: prompt },
} = await openai.createTranscription(
  fs.createReadStream(fileName),
  "whisper-1"
);

实现文字转语音(TTS)

OpenAI 目前只提供了 STT,如果需要返回给用户一个音频的话。就需要用到国内的 科大讯飞 每天有 5.05w 次免费的 TTS[1]

f3f36b65dc79bd7d98b99ac8da9294a7.png

如果你有国外信用卡,可以考虑使用微软推出 Azure,很多电报机器人就是用的它来开发的,免费使用 12个月。

714d876135d09564ed6c3960dae0483f.png

所以在这里还是使用科大讯飞的 TTS

文字生成音频文件

音频没有直接返回流,而是直接生成一个音频返回文件路径给前端播放。

回复音频存放在 chat-audio/client/audio 中

先在 讯飞TTS[2] 中获取需要的 keys

c8a9db9639e1c8300a1517559bcf4030.png
const tts = promisify(require("./utils/tts"));
// 环境变量
require("dotenv").config();
// 生成音频
const generateAudio = (text) => {
  return new Promise((resolve, reject) => {
    const auth = {
      app_id: process.env.TTS_APP_ID,
      app_skey: process.env.TTS_API_SECRET,
      app_akey: process.env.TTS_API_KEY
    };
    // 讯飞 api 参数配置
    const business = {
      aue: "lame",
      sfl: 1,
      speed: 50,
      pitch: 50,
      volume: 100,
      bgs: 0,
    };
    const id = new Date().getTime()
    // 存储文件的路径
    const file = path.resolve(__dirname, `client/audio/${id}.m4a`);
    try {
      // 执行请求
      tts(auth, business, text, file).then((res) => {
        // 返回静态文件地址
        resolve(`audio/${id}.m4a`)
      });
    } catch (e) {
      reject(e)
    }
  })
};

封装好的讯飞的语音包 TTS,放在 ChatAudio 仓库[3] 里面。这里就不展示出来了

调用 STT & TTS

音频对话接口

通过 api/audio,让客户端调用此方法

app.use(fileUpload());
app.post("api/audio", async (req, res) => {
  // 没有上传音频抛出异常
  if (!req.files) return res.status(400).send({ message: "缺少参数", error: true });

  const file = req.files.file;
  // 存放用户上传的文件
  const fileName = "audio.m4a";

  file.mv(fileName, async (err) => {
    if (err) {
      return res.status(500).send(err);
    }
        // 使用ChatGPT 的 STT 机器人(Whisper)
    const {
      data: { text: prompt },
    } = await openai.createTranscription(
      fs.createReadStream(fileName),
      "whisper-1"
    );
    console.log("解析的音频内容是>>>", prompt);

    // 判断用户上传音频是否存在内容
    if (!prompt.trim().length)
      return res.send({ message: "未识别到语音内容", error: true });

    // 将转用户提问的文本内容,去调用 ChatGPT 的回复
    const chatReply = await handleIssueReply(prompt);

    // 将 ChatGPT 的回复通过 TTS 转化为语音
    const content = await generateAudio(chatReply);
    console.log("生成的音频是>>>", content);

    res.send([
      { type: "system", content, chatReply, infoType: "audio", playStatus: false },
    ]);
  });
});

ChatGPT 回复问题能力

不管是 TTSSTT还是TTT,最核心对话功能还是通过 ChatGPT实现的。

503eaa092fef714a71b12c415d13b1d0.png

ChatGPT 配置就不细说了,配置一个 KEY 然后封装一个回复问题的方法

获取 ChatGPT KEY [4]

const { Configuration, OpenAIApi } = require("openai");
// openai 配置
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
// 创建 openai 实例
const openai = new OpenAIApi(configuration);

const handleIssueReply = async (prompt) => {
  const {
    data: { choices },
  } = await openai.createCompletion({
    model: "text-davinci-003",
    prompt,
    temperature: 0.5,
    max_tokens: 1000,
    top_p: 1.0,
    frequency_penalty: 0.0,
    presence_penalty: 0.0,
  });
  const chat = choices[0].text?.trim();
  console.log("生成的文本内容是>>>", chat);
  return chat;
};

实现效果如下,没有录屏可以自行感受下。

补充功能 Text To Text

前面做的语音对话,只是为了让你不再孤单寂寞,但是在日常开发工作中基本上不会使用到语音对话,所以单独做了个可以直接使用的文字聊天功能。

所以新开了一个接口直接调用 ChatGPT 的回复。

app.get("/api/issue", async (req, res) => {
  // 从 query 中取出用户提出的问题
  const { issue } = req.query;
    if (!issue.trim()) return res.status(400).send({ message: "缺少参数", error: true });
  const chatReply = await handleIssueReply(issue);
  return res.send([{ type: "system", content: chatReply }]);
});

前端实现

前端没什么太多需要注意的,列一下依赖吧,均采用的 CDN

  • Vue

  • Elment UI

代码在 chat-audio/client/index.html 这里

使用 ChatAudio

克隆

git clone git@github.com:CrazyMrYan/chat-audio.git

配置 Key

在 ENV 文件中配置 科大讯飞OpenAIkey

安装启动

yarn install

yarn start

使用

浏览器打开 localhost:3000

就可以看到聊天界面了

tips:

开下 ke xue shang wang

最好是 🇺🇸 节点

参考资料

[1]

TTS: https://console.xfyun.cn/services/tts

[2]

讯飞TTS: https://console.xfyun.cn/services/tts

[3]

ChatAudio 仓库: https://github.com/CrazyMrYan/chat-audio

[4]

获取 ChatGPT KEY : https://platform.openai.com/account/api-keys

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

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

相关文章

(C++)模板分离编译面对的问题

什么是分离编译模板的分离编译什么是分离编译 一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。 模板的分离编译 假如有以下…

Java锁机制

Java锁机制1. 什么是锁JVM运行时内存结构2. 对象、对象头结构Mark Word中的字段3. synchronizedMonitor原理四种锁状态的由来4. 锁的4种状态4.1 无锁CAS(Compare and Swap)4.2 偏向锁实现原理4.3 轻量级锁如何判断线程和锁之间的绑定关系自旋4.4 重量级锁…

【计算机视觉·OpenCV】使用Haar+Cascade实现人脸检测

前言 人脸检测的目标是找出图像中所有的人脸对应的位置,算法的输出是人脸的外接矩形在图像中的坐标。使用 haar 特征和 cascade 检测器进行人脸检测是一种传统的方式,下面将给出利用 OpenCV 中的 haarcascade 进行人脸检测的代码。 程序流程 代码 impo…

摩兽Pesgo plus首发爆卖,全网关注度破亿!中国潮玩跨骑电自浪潮已至?

2023年4月11日,TROMOX摩兽圆满举办了“跨骑潮电,大有所玩”Pesgo plus新品发布会。发布会在抖音、天猫、视频号平台进行了同步直播并开启线上预定。发布会直播当晚,摩兽Pesgo plus即狂揽线上订单,全网各大平台相关话题累计热度已破…

XXL-JOB分布式任务调度平台详细介绍

一、概述 在平时的业务场景中,经常有一些场景需要使用定时任务,比如: 时间驱动的场景:某个时间点发送优惠券,发送短信等等。 批量处理数据:批量统计上个月的账单,统计上个月销售数据等等。 固…

用SQL语句操作oracle数据库--数据查询(上篇)

SQL操作Oracle数据库进行数据查询 Oracle 数据库是业界领先的关系型数据库管理系统之一,广泛应用于企业级应用和数据仓库等场景中。本篇博客将介绍如何使用 SQL 语句对 Oracle 数据库进行数据查询操作。 1.连接到数据库 在开始查询之前,需要使用合适的…

素材管理系统概念导入

引言 由于工作上的调整安排,有幸参加营销素材管理系统的产品建设工作中,营销宣传领域一直是我的知识盲区,所以素材管理系统的产品建设对我来说是个富有挑战性的工作,在这过程中,我也秉持着“好记性不如烂笔头”的原则&…

Golang每日一练(leetDay0033) 二叉树专题(2)

目录 97. 交错字符串 Interleaving String 🌟🌟 98. 验证二叉搜索树 Validate Binary Search Tree 🌟🌟 99. 恢复二叉搜索树 Recover Binary Search Tree 🌟🌟 🌟 每日一练刷题专栏 &am…

中国人工智能企业CIMCAI世界前三大船公司落地,智能船公司产品20秒AI自动验箱,箱信息箱况+精确地点报备智慧港航中国人工智能企业

中国人工智能企业CIMCAI世界前三大船公司落地,智能船公司产品20秒AI自动验箱,箱信息箱况精确地点报备智慧港航。小程序全时全域自动化箱况检测信息识别,CIMCAI全球领先新一代集装箱管理方案,人工智能AI自动化箱信息识别箱况检测地…

Python 小型项目大全 21~25

二十一、DNA 可视化 原文:http://inventwithpython.com/bigbookpython/project21.html 脱氧核糖核酸是一种微小的分子,存在于我们身体的每个细胞中,包含着我们身体如何生长的蓝图。它看起来像一对核苷酸分子的双螺旋结构:鸟嘌呤、…

【跟着陈七一起学C语言】今天总结:C语言的函数相关知识

友情链接:专栏地址 知识总结顺序参考C Primer Plus(第六版)和谭浩强老师的C程序设计(第五版)等,内容以书中为标准,同时参考其它各类书籍以及优质文章,以至减少知识点上的错误&#x…

太阳能电池板AI视觉检测:不良品全程阻断,高效助力光伏扩产

2022年,面对复杂严峻的国内外形势,我国光伏行业依然实现高速增长,多晶硅、硅片、电池片、组件产量稳居全球首位。2023年以来,扩产项目已多点开花。光伏装机量天花板将不断提升,分布式电站占比也将逐年上升。中国光伏行…

4月软件测试面试太难,吃透这份软件测试面试笔记后,成功跳槽涨薪30K

4 月开始,生活工作渐渐步入正轨,但金三银四却没有往年顺利。昨天跟一位高级架构师的前辈聊天时,聊到今年的面试。有两个感受,一个是今年面邀的次数比往年要低不少,再一个就是很多面试者准备明显不足。不少候选人能力其…

python学籍管理系统

1,创建登陆的首页面,且封装起来。LoginPage.py import tkinter as tk#导入tk模块 from tkinter import messagebox#导入消息提示模块 from tkinter import messagebox from db import db #导入数据库db class LoginPage:#把整个登陆页面创建一个class类…

搭建自己的饥荒Don‘t Starve服务器-饥荒Don‘t Starve开服教程

前言 饥荒这个游戏,虽然首发于2016年,但是贵在好玩呀。和Minecraft一样,可玩性很高,并且有很多mods,最近和小伙伴玩的过程中,就想着搭建一个服务器,方便在主机玩家不在线时候,也可以…

Linux软件安装---Tomcat安装

安装Tomcat 操作步骤: 使用xftp上传工具将tomcat的 二进制发布包上传到Linux解压安装包,命令为tar -zxvf apache-tomcat*** -C /usr/local进入Tomcat的bin的启动目录,命令为sh startup.sh或者./startup.sh 验证Tomcat启动是否成功&#xff0…

LeetCode:376. 摆动序列——说什么贪心和动规~

🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱376. 摆动序列 题目描述:如果连续数字之间的差严格地在正数和…

Python 小型项目大全 46~50

# 四十六、百万骰子投掷统计模拟器 原文:http://inventwithpython.com/bigbookpython/project46.html 当你掷出两个六面骰子时,有 17%的机会掷出 7。这比掷出 2 的几率好得多:只有 3%。这是因为只有一种掷骰子的组合给你 2(当两个…

「 分布式技术 」一致性哈希算法(Hash)详解

「 分布式技术 」一致性哈希算法(Hash)详解 参考&鸣谢 一致性 Hash 算法原理总结 kylinkzhang,腾讯 CSIG 后台开发工程师 什么是一致性哈希? xiaolinCoding 文章目录「 分布式技术 」一致性哈希算法(Hash&#xff…

imagenet val 按类别分类

前言 有时候想看imagenet下某个类别的效果,但它又没划分… 之前看了这篇文章将ImageNet的验证集val数据分类到不同文件夹中,但不是很清楚那代码。 本文基于它的代码去做更改 把这个下下来 https://raw.githubusercontent.com/soumith/imagenetloader.…