智能语音助手开发

import threading
import AI_Chatbots
from pyaudio import PyAudio, paInt16
import wave
from TextToSpeech import BaiduVoice
from cozeAPI import chat
import pygame
from datetime import datetime

# 继承AI_Chatbots.Ui_MainWindow类,实现AI聊天机器人的主要功能
class AI_botImpl(AI_Chatbots.Ui_MainWindow):
    def __init__(self, window):
        super().__init__()
        self.setupUi(window)
        # 设置推送按钮的样式
        self.pushButton.setStyleSheet(u"background-color: rgb(85, 170, 0);\n"
                                      "color: rgb(255, 255, 255);\n"
                                      "font-size:20px;\n"
                                      "border-radius:5px")
        # # 初始化录音状态为False
        # self.recording_status = False
        # 连接按钮的pressed和released信号到相应的槽函数
        self.recording_status = False  # 录音状态,默认为False
        self.pushButton.pressed.connect(self.start_recording)
        self.pushButton.released.connect(self.stop_recording)

        self.recording = False
        # 创建线程锁,用于安全地操作共享数据frames
        self.frames_lock = threading.Lock()
        # 初始化音频数据列表
        self.frames = []
        # 设置音频块的大小
        self.CHUNK = 1024
        # 设置音频格式为16位整数
        self.FORMAT = paInt16
        # 设置音频通道数为1(单声道)
        self.CHANNELS = 1
        # 设置音频采样率为16000Hz
        self.RATE = 16000
        # 创建PyAudio对象
        self.audio = PyAudio()

    # 显示聊天记录的方法
    def display_chat(self, user_input, bot_response):
        # 获取当前时间
        current_time = self.get_current_time()
        # 格式化用户输入和机器人响应的时间戳文本
        user_text = f"{current_time} 用户: {user_input}\n"
        bot_text = f"{current_time} Bot: {bot_response}\n"
        # 将文本添加到文本浏览器中显示
        self.textBrowser.append(user_text)
        self.textBrowser.append(bot_text)

    # 获取当前时间的方法
    def get_current_time(self):
        # 返回格式化后的时间字符串
        return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # 开始录音的方法
    def start_recording(self):
        # 如果当前没有录音,则开始录音的方法
        if not self.recording:
            self.recording = True
        # 清空音频数据列表

        with self.frames_lock:
            self.frames.clear()
        # 更新按钮文本和样式,以反映录音中的状态
        self.pushButton.setText("录音中...")
        self.pushButton.setStyleSheet(u"background-color: rgb(255, 0, 0);\n"
                                      "color: rgb(255, 255, 255);\n"
                                      "font-size:20px;\n"
                                      "border-radius:5px")
        print("录音中...")

        # 创建录音线程并开始录音
        self.record_audio_thread = threading.Thread(target=self.record_audio)
        self.record_audio_thread.start()

    # 停止录音的方法
    def stop_recording(self):
        """
        停止录音功能的方法。

        本方法通过改变对象的状态来停止录音,同时更新用户界面的按钮文本和样式,
        并尝试保存录音文件。确保录音线程安全结束是其核心功能之一。
        """
        # 检查是否正在录音,是则停止录音
        if self.recording:
            self.recording = False
        # 更新按钮文本和样式,以反映录音停止的状态
        self.pushButton.setText("按住话筒说话")
        self.pushButton.setStyleSheet(u"background-color: rgb(85, 170, 0);\n"
                                      "color: rgb(255, 255, 255);\n"
                                      "font-size:20px;\n"
                                      "border-radius:5px")
        print("停止录音...")
        # 等待录音线程结束
        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}")

    # 保存录音为WAV文件的方法
    def save_audio(self):
        """
        保存录音为WAV文件。

        此函数尝试将之前录制的音频数据保存为WAV文件。它负责创建一个新的WAV文件,
        设置适当的声道数、采样宽度、帧率,并将音频数据写入文件。如果操作成功,它将
        打印确认消息并返回True。如果过程中发生任何错误,它将捕获异常,打印错误消息,
        并返回False。
        返回:
            bool: 如果成功保存音频文件,则为True,否则为False。
        """
        try:
            # 定义文件名和路径,创建WAV文件并写入音频数据
            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


    def speech_recognition(self):
        """
        语音识别功能。

        该方法使用百度语音识别服务识别预录制的音频文件。
        如果识别成功,将调用coze_api方法处理识别结果。
        如果识别失败,将输出失败信息。
        """
        voice = BaiduVoice()
        recognition_result = voice.recognize_speech('medium/user.wav')
        print("已识别的文本:", recognition_result)
        if recognition_result:
            self.coze_api(recognition_result)
        else:
            print("识别失败")

    def speech_synthesis(self, kword):
        """
        语音合成功能。

        该方法使用百度语音合成服务将文本转换为语音,并播放合成的语音。
        初始化pygame模块以处理音频播放,并在播放完成后进行清理。
        """
        voice = BaiduVoice()
        voice.synthesize_text(kword, 'medium/bot.mp3')
        print("已合成的语音文本:", kword)
        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()

    def coze_api(self, kword):
        """
        调用cozeapi接口并处理响应。

        该方法首先调用cozeapi接口,传入关键词(kword),获取响应内容,
        然后调用语音合成功能将响应内容转换为语音输出。

        参数:
        kword (str): 用户输入的关键词,用于查询或发送请求。

        返回:
        无
        """
        print("调用cozeapi接口")
        chat_response = chat(kword)
        print(chat_response)
        self.speech_synthesis(chat_response)

    def on_send_button_clicked(self):
        """
        处理发送按钮点击事件。

        该方法在用户点击发送按钮时被触发,获取用户输入的文本,
        并进行一些基本的验证,如检查输入是否为空。如果验证通过,
        则清除输入框,并进行对话处理,显示用户输入和Bot的响应。
        """
        user_input = self.textEdit.toPlainText()
        if not user_input:
            print("输入框不能为空")
            return
        self.textEdit.clear()
        response = self.coze_bot_dialogue(user_input)
        self.display_chat(user_input, response)

    def coze_bot_dialogue(self, message):
        """
        与coze机器人进行对话。

        该方法作为与coze机器人交互的中介,将用户的消息传递给chat函数,
        并返回机器人的响应。

        参数:
        message (str): 用户的消息。

        返回:
        str: 机器人的响应消息。
        """
        return chat(message)

    def display_chat(self, user_input, bot_response):
        """
        在界面中显示聊天内容。

        该方法将用户和机器人的对话内容格式化并显示在文本浏览器中,
        同时为发送按钮绑定点击事件处理函数。

        参数:
        user_input (str): 用户的输入。
        bot_response (str): 机器人的响应。

        返回:
        无
        """
        user_text = f"用户: {user_input}\n"
        bot_text = f"Bot: {bot_response}\n"

        self.pushButton_2.clicked.connect(self.on_send_button_clicked)

1. 类定义和初始化

class AI_botImpl(AI_Chatbots.Ui_MainWindow):
    def __init__(self, window):
        super().__init__()
        self.setupUi(window)
        self.pushButton.setStyleSheet(u"background-color: rgb(85, 170, 0);\n"...
  • AI_botImpl类继承自AI_Chatbots.Ui_MainWindow,这表明它是一个基于Qt Designer的UI类。

  • 在初始化方法__init__中,首先调用基类的构造函数super().__init__(),然后调用self.setupUi(window)来设置UI界面。

  • 设置了推送按钮self.pushButton的样式,包括背景颜色、文字颜色、字体大小和边框圆角。

2. 录音状态和线程锁

       
 self.recording_status = False  # 录音状态,默认为False
        self.pushButton.pressed.connect(self.start_recording)
        self.pushButton.released.connect(self.stop_recording)
        self.recording = False
        self.frames_lock = threading.Lock()
        self.frames = []
  • self.recording_statusself.recording用于控制录音的开始和停止。

  • self.frames_lock是一个线程锁,用于在多线程环境下安全地操作self.frames(音频数据列表)。

3. 音频参数设置

    
    self.CHUNK = 1024
        self.FORMAT = paInt16
        self.CHANNELS = 1
        self.RATE = 16000
        self.audio = PyAudio()
  • self.CHUNK设置音频块的大小为1024字节。

  • self.FORMAT设置音频格式为16位整数。

  • self.CHANNELS设置音频通道数为1(单声道)。

  • self.RATE设置音频采样率为16000Hz。

  • self.audio创建一个PyAudio对象,用于音频的录制和播放。

4. 显示聊天记录

   
 def display_chat(self, user_input, bot_response):
        current_time = self.get_current_time()
        user_text = f"{current_time} 用户: {user_input}\n"
        bot_text = f"{current_time} Bot: {bot_response}\n"
        self.textBrowser.append(user_text)
        self.textBrowser.append(bot_text)
  • display_chat方法用于在文本浏览器中显示用户和机器人的对话。

  • get_current_time方法获取当前时间并格式化为字符串。

5. 录音方法

    
def start_recording(self):
        if not self.recording:
            self.recording = True
        with self.frames_lock:
            self.frames.clear()
        self.pushButton.setText("录音中...")
        self.pushButton.setStyleSheet(u"background-color: rgb(255, 0, 0);\n"...
        print("录音中...")
        self.record_audio_thread = threading.Thread(target=self.record_audio)
        self.record_audio_thread.start()
  • start_recording方法开始录音过程。

  • 清空self.frames列表,准备新的录音数据。

  • 更新按钮文本和样式,表示正在录音。

  • 创建并启动一个线程来执行record_audio方法。

6. 停止录音

    
def stop_recording(self):
        if self.recording:
            self.recording = False
        self.pushButton.setText("按住话筒说话")
        self.pushButton.setStyleSheet(u"background-color: rgb(85, 170, 0);\n"...
        print("停止录音...")
        self.record_audio_thread.join()
        success = self.save_audio()
        if success:
            print("录音文件保存成功!")
            self.speech_recognition()
        else:
            print("录音文件保存失败!")
  • stop_recording方法停止录音。

  • 更新按钮文本和样式,表示录音已停止。

  • 等待录音线程结束。

  • 调用save_audio方法保存录音文件,并根据结果进行后续处理。

7. 录音线程

    
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}")
  • record_audio方法在单独的线程中运行,负责实际的录音工作。

  • 使用PyAudio对象打开音频流,循环读取音频数据并存储到self.frames列表中。

  • 读取直到self.recording变为False,然后停止并关闭音频流。

8. 保存录音文件

    
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
  • save_audio方法将录音数据保存为WAV文件。

  • 使用wave库创建WAV文件,并设置通道数、采样宽度和帧率。

  • 将音频数据写入文件,并在成功时返回True,失败时返回False。

9. 语音识别

 def speech_recognition(self):
        voice = BaiduVoice()
        recognition_result = voice.recognize_speech('medium/user.wav')
        print("已识别的文本:", recognition_result)
        if recognition_result:
            self.coze_api(recognition_result)
        else:
            print("识别失败")
  • speech_recognition方法使用BaiduVoice类进行语音识别。

  • 识别成功后,调用coze_api方法处理识别结果。

10. 语音合成

    
def speech_synthesis(self, kword):
        voice = BaiduVoice()
        voice.synthesize_text(kword, 'medium/bot.mp3')
        print("已合成的语音文本:", kword)
        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()
  • speech_synthesis方法使用BaiduVoice类将文本转换为语音并播放。

  • 使用pygame库加载和播放合成的语音文件。

11. 处理用户输入和显示聊天内容

    
def on_send_button_clicked(self):
        user_input = self.textEdit.toPlainText()
        if not user_input:
            print("输入框不能为空")
            return
        self.textEdit.clear()
        response = self.coze_bot_dialogue(user_input)
        self.display_chat(user_input, response)
​
    def coze_bot_dialogue(self, message):
        return chat(message)
  • on_send_button_clicked方法处理发送按钮的点击事件,获取用户输入并调用coze_bot_dialogue方法。

  • coze_bot_dialogue方法调用chat函数与聊天机器人进行交互。

总结

这段代码实现了一个完整的AI聊天机器人,包括录音、语音识别、语音合成和聊天功能。它使用了多线程、音频处理和GUI交互,是一个综合性的Python项目。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值