项目概述
本项目实现了一个图形化用户界面(GUI)的应用程序,该程序具有以下功能:
- 录音和保存音频文件。
- 将音频文件转换为文本(语音识别)。
- 通过聊天机器人接口(Coze API)生成回答,并将其合成语音(语音合成)。
- 将用户提问和AI回答保存到数据库,并支持查看历史记录
关键代码讲解
1. 导入对应的包以及初始化与设置
在项目中,我们首先设置了环境变量以配置Coze API的访问令牌和机器人ID。然后,我们创建了一个Coze
对象用于后续的聊天机器人接口调用。
import threading
import wave
import pygame
from datetime import datetime
from pyaudio import paInt16, PyAudio
from TextToSpeech import BaiduVoice
from untitled import Ui_MainWindow
from coze import Coze
import os
from PySide6.QtWidgets import QMessageBox
import sqlite3
os.environ['COZE_API_TOKEN'] = 'your_api_token'
os.environ['COZE_BOT_ID'] = 'your_bot_id'
chat = Coze(api_token=os.environ['COZE_API_TOKEN'], bot_id=os.environ['COZE_BOT_ID'])
2. GUI 初始化
在GUI初始化中,我们设置了录音按钮、发送按钮等控件的事件连接,并初始化了数据库连接及表的创建。
class mw(Ui_MainWindow):
def __init__(self, window):
super().__init__()
self.setupUi(window)
self.window = window
self.recording = False
self.BotText = ""
self.UserText = ""
self.conn = sqlite3.connect('hy.db')
self.cur = self.conn.cursor()
self.cur.execute("""create table if not exists hy(
id integer primary key autoincrement,
problems text,
answer text,
datetime date)
""")
# 连接按钮和功能
self.pushButton_5.pressed.connect(self.star)
self.pushButton_5.released.connect(self.stop)
self.pushButton.clicked.connect(self.send)
self.pushButton_2.clicked.connect(self.clean)
self.pushButton_3.clicked.connect(self.cleanHistory)
self.comboBox.currentTextChanged.connect(self.change)
self.comboBox.setCurrentIndex(0)
self.pushButton_12.clicked.connect(self.history)
3. 录音功能实现
这部分代码实现了录音的开始、停止、保存功能。我们使用pyaudio
库进行音频录制,并将录音保存为WAV格式文件。
def star(self):
if not self.recording:
self.recording = True
self.pushButton_5.setStyleSheet(u"image: url(:/icons/icons/ly.png)")
with self.frames_lock:
self.frames.clear()
print("录音中...")
self.record_audio_thread = threading.Thread(target=self.record_audio)
self.record_audio_thread.start()
def stop(self):
if self.recording:
self.recording = False
print("停止录音...")
self.pushButton_5.setStyleSheet(u"image: url(:/icons/icons/yy.png)")
self.record_audio_thread.join()
success = self.save_audio()
if success:
print("录音文件保存成功!")
self.speech_recognition()
else:
print("录音文件保存失败!")
def record_audio(self):
try:
stream = self.audio.open(format=self.FORMAT,
channels=self.CHANNELS,
rate=self.RATE,
input=True,
frames_per_buffer=self.CHUNK)
while self.recording:
data = stream.read(self.CHUNK)
with self.frames_lock:
self.frames.append(data)
stream.stop_stream()
stream.close()
except Exception as e:
print(f"Error during recording: {e}")
def save_audio(self):
try:
filename = 'medium/user.wav'
wf = wave.open(filename, 'wb')
wf.setnchannels(self.CHANNELS)
wf.setsampwidth(self.audio.get_sample_size(self.FORMAT))
wf.setframerate(self.RATE)
with self.frames_lock:
wf.writeframes(b''.join(self.frames))
wf.close()
print(f"录音文件已保存为 {filename}")
return True
except Exception as e:
print(f"Error saving audio file: {e}")
return False
4. 语音识别与合成
这部分代码实现了语音识别和语音合成。BaiduVoice
类用于与百度语音API交互,将音频转换为文本,或将文本转换为音频。生成的音频通过pygame
播放。
def speech_recognition(self):
voice = BaiduVoice()
usertext = voice.recognize_speech('medium/user.wav')
self.UserText = usertext
print("已识别的文本:", usertext)
if usertext:
nowtime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.textBrowser.append(f"{self.username}:\n {usertext}")
if self.comboBox.findText(self.UserText) == -1:
self.comboBox.addItem(self.UserText)
threading.Thread(target=self.coze_api, args=(usertext, nowtime)).start()
else:
print("识别失败")
def speech_synthesis(self, bottext, nowtime):
voice = BaiduVoice()
voice.synthesize_text(bottext, 'medium/bot.mp3')
print("已合成的语音文本:", bottext)
self.textBrowser.append(f"AI客服:\n {bottext}")
self.BotText = bottext
pygame.init()
pygame.mixer.music.load('medium/bot.mp3')
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
pygame.quit()
conn = sqlite3.connect('hy.db')
cur = conn.cursor()
cur.execute("insert into hy ('problems', 'answer','datetime') VALUES (?, ?, ?)",
(self.UserText, self.BotText, nowtime))
conn.commit()
5. 数据管理
这些方法用于管理数据库记录,包括保存用户问题和AI回答、清除历史记录和查看历史记录。
def saveDate(self, content, nowtime, db_path="hy.db"):
result = chat(content)
print(result)
self.textBrowser.append(f"AI客服:\n {result}")
conn = sqlite3.connect(db_path)
cur = conn.cursor()
try:
cur.execute("insert into hy ('problems', 'answer','datetime') VALUES (?, ?, ?)",
(content, result, nowtime))
conn.commit()
except Exception as e:
print(f"Error occurred: {e}")
finally:
conn.close()
def clean(self):
self.textEdit.clear()
def cleanHistory(self):
self.cur.execute("delete from hy")
print("历史记录被清空")
self.conn.commit()
def history(self):
self.cur.execute("select * from hy")
result = self.cur.fetchall()
history = ""
for t in result:
history += f"时间:{t[3]}\n{self.username}:{t[1]}\nAI客服:{t[2]}"
print(history)
print("以上是问过的问题和历史记录")
if not result:
print("历史记录为空")
QMessageBox.warning(self.window, "提示", "你还没有提问的记录,赶紧去提问吧")
else:
qbox = QMessageBox(self.window)
qbox.setWindowTitle("历史记录信息")
qbox.setText(history)
qbox.setStandardButtons(QMessageBox.Ok)
qbox.exec_()
以上是该项目的部分代码展示与讲解
总结
这个项目展示了如何结合多种Python库来实现一个复杂的应用程序。通过录音、语音识别、语音合成、聊天机器人接口和数据库操作,我们能够创建一个功能丰富的聊天机器人系统。以下是一些总结和建议:
-
模块化设计:将不同的功能(如录音、语音识别、语音合成等)分解为独立的方法,有助于提高代码的可维护性和可读性。
-
线程处理:使用线程来处理音频录制和网络请求,能够确保应用程序的主线程不会被阻塞,提升用户体验。
-
异常处理:在涉及到文件操作和网络请求的地方,添加适当的异常处理,可以提高程序的健壮性。
-
数据库管理:使用SQLite数据库来存储记录是一个简单有效的方案,但随着数据量的增加,可能需要考虑更复杂的数据库解决方案。