手搓智能音箱——语音识别及调用大模型回应

一、代码概述

 

此 Python 代码实现了一个语音交互系统,主要功能为监听唤醒词,在唤醒后接收用户语音问题,利用百度语音识别将语音转换为文本,再调用 DeepSeek API 获取智能回复,最后使用文本转语音功能将回复朗读出来。

二、环境依赖

 

在运行此代码前,需要安装以下 Python 库:

 

  • baidu-aip:用于调用百度语音识别服务。
  • pyttsx3:实现文本转语音功能。
  • dotenv:用于加载环境变量。
  • pyaudio:用于录制音频。
  • wave:用于处理音频文件。
  • requests:用于发送 HTTP 请求。
  • json:用于处理 JSON 数据。

 

可以使用以下命令进行安装:

 

bash

pip install baidu-aip pyttsx3 python-dotenv pyaudio requests

三、环境变量配置

 

需要在项目根目录下创建一个 .env 文件,并添加以下环境变量:

 

plaintext

BAIDU_APP_ID=your_baidu_app_id
BAIDU_API_KEY=your_baidu_api_key
BAIDU_SECRET_KEY=your_baidu_secret_key
DEEPSEEK_API_KEY=your_deepseek_api_key

 

请将 your_baidu_app_idyour_baidu_api_keyyour_baidu_secret_key 替换为你在百度语音平台申请的应用 ID、API 密钥和 Secret 密钥,将 your_deepseek_api_key 替换为你在 DeepSeek 平台申请的 API 密钥。

四、代码模块详细解释

1. 导入必要的库

 

python

from aip import AipSpeech
import pyttsx3
import os
from dotenv import load_dotenv
import wave
import pyaudio
import requests
import json
from datetime import datetime

 

  • AipSpeech:用于调用百度语音识别服务。
  • pyttsx3:实现文本转语音功能。
  • os:用于操作环境变量。
  • load_dotenv:从 .env 文件中加载环境变量。
  • wave:用于处理音频文件。
  • pyaudio:用于录制音频。
  • requests:用于发送 HTTP 请求。
  • json:用于处理 JSON 数据。
  • datetime:虽然代码中未实际使用,但可用于后续添加时间相关功能。

2. 加载环境变量并初始化客户端

 

python

# Load environment variables
load_dotenv()
APP_ID = os.getenv("BAIDU_APP_ID")
API_KEY = os.getenv("BAIDU_API_KEY")
SECRET_KEY = os.getenv("BAIDU_SECRET_KEY")# Initialize Baidu Speech client
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

 

  • load_dotenv():从 .env 文件中加载环境变量。
  • AipSpeech:使用百度提供的应用 ID、API 密钥和 Secret 密钥初始化百度语音识别客户端。

3. 初始化文本转语音引擎

 

python

# Initialize text-to-speech
engine = pyttsx3.init()# Set Chinese voice if available, and choose a gentle female voice
voices = engine.getProperty('voices')
for voice in voices:# 检查音色是否为中文,并且音色名称中包含“female”或“woman”等关键词if 'chinese' in voice.name.lower() and ('female' in voice.name.lower() or 'woman' in voice.name.lower()):engine.setProperty('voice', voice.id)break

 

  • pyttsx3.init():初始化文本转语音引擎。
  • 通过遍历可用语音,选择支持中文且为女性的语音。

4. 调用 DeepSeek API 获取智能回复

 

python

def call_deepseek_api(prompt):"""Call DeepSeek API for intelligent response"""url = "https://api.deepseek.com/v1/chat/completions"headers = {"Content-Type": "application/json","Authorization": f"Bearer {os.getenv('DEEPSEEK_API_KEY')}"}data = {"model": "deepseek-chat","messages": [{"role": "user","content": prompt}],"temperature": 0.7,"max_tokens": 200}try:response = requests.post(url, headers=headers, json=data)response.raise_for_status()result = response.json()return result['choices'][0]['message']['content'].strip()except Exception as e:print(f"Error calling DeepSeek API: {str(e)}")return "抱歉,我暂时无法回答这个问题"

 

  • call_deepseek_api 函数:接收用户的问题 prompt,向 DeepSeek API 发送请求,获取智能回复。
  • requests.post:发送 HTTP POST 请求。
  • response.raise_for_status():检查请求是否成功。
  • 若请求失败,捕获异常并返回错误提示信息。

5. 录制音频

 

python

def record_audio(filename, record_seconds=5):"""Record audio from microphone"""CHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 1RATE = 16000p = pyaudio.PyAudio()stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)print("开始录音...")frames = []for _ in range(0, int(RATE / CHUNK * record_seconds)):data = stream.read(CHUNK)frames.append(data)print("录音结束")stream.stop_stream()stream.close()p.terminate()wf = wave.open(filename, 'wb')wf.setnchannels(CHANNELS)wf.setsampwidth(p.get_sample_size(FORMAT))wf.setframerate(RATE)wf.writeframes(b''.join(frames))wf.close()

 

  • record_audio 函数:用于录制音频,将录制的音频保存为指定文件名的 .wav 文件。
  • pyaudio.PyAudio():初始化 PyAudio 对象。
  • p.open:打开音频输入流。
  • wave.open:打开音频文件进行写入操作。

6. 监听唤醒词

 

python

def listen_for_wake_word(wake_word="小绿同学"):"""Listen for the wake word using Baidu Speech Recognition"""temp_file = "temp.wav"record_audio(temp_file, 3)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537  # Mandarin})if result.get('err_no') == 0:text = result['result'][0]if wake_word in text:return Truereturn False

 

  • listen_for_wake_word 函数:录制 3 秒音频,使用百度语音识别将音频转换为文本,检查文本中是否包含唤醒词。
  • client.asr:调用百度语音识别服务。

7. 获取回复

 

python

def get_response(prompt):"""Generate response using DeepSeek API"""return call_deepseek_api(prompt)

 

  • get_response 函数:调用 call_deepseek_api 函数获取智能回复。

8. 文本转语音

 

python

def speak(text):"""Convert text to speech"""engine.say(text)engine.runAndWait()

 

  • speak 函数:使用 pyttsx3 引擎将文本转换为语音并朗读出来。

9. 主函数

 

python

def main():print("小绿同学已启动,等待唤醒...")while True:if listen_for_wake_word():print("唤醒成功!请说出你的问题...")speak("您好,需要什么帮助")temp_file = "question.wav"record_audio(temp_file, 5)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537  # Mandarin})if result.get('err_no') == 0:user_input = result['result'][0]print(f"你说: {user_input}")response = get_response(user_input)print(f"小绿同学: {response}")speak(response)else:print("抱歉,我没有听清楚")speak("抱歉,我没有听清楚")if __name__ == "__main__":main()

 

 

 

 

 

  • main 函数:程序的入口点,不断监听唤醒词,唤醒后录制用户问题,进行语音识别,调用 DeepSeek API 获取回复,并将回复朗读出来。

五、注意事项

 

  • 确保 .env 文件中的环境变量配置正确。
  • 若网络连接不稳定或 DeepSeek API 服务不可用,可能会导致获取回复失败。
  • 录音设备需要正常工作,否则可能无法录制音频。

 

完整代码

 

from aip import AipSpeech
import pyttsx3
import os
from dotenv import load_dotenv
import wave
import pyaudio
import requests
import json
from datetime import datetime# Load environment variables
load_dotenv()
APP_ID = os.getenv("BAIDU_APP_ID")
API_KEY = os.getenv("BAIDU_API_KEY")
SECRET_KEY = os.getenv("BAIDU_SECRET_KEY")# Initialize Baidu Speech client
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)# Initialize text-to-speech
engine = pyttsx3.init()# Set Chinese voice if available, and choose a gentle female voice
voices = engine.getProperty('voices')
for voice in voices:# 检查音色是否为中文,并且音色名称中包含“female”或“woman”等关键词if 'chinese' in voice.name.lower() and ('female' in voice.name.lower() or 'woman' in voice.name.lower()):engine.setProperty('voice', voice.id)break
def call_deepseek_api(prompt):"""Call DeepSeek API for intelligent response"""url = "https://api.deepseek.com/v1/chat/completions"headers = {"Content-Type": "application/json","Authorization": f"Bearer {os.getenv('DEEPSEEK_API_KEY')}"}data = {"model": "deepseek-chat","messages": [{"role": "user","content": prompt}],"temperature": 0.7,"max_tokens": 200}try:response = requests.post(url, headers=headers, json=data)response.raise_for_status()result = response.json()return result['choices'][0]['message']['content'].strip()except Exception as e:print(f"Error calling DeepSeek API: {str(e)}")return "抱歉,我暂时无法回答这个问题"def record_audio(filename, record_seconds=5):"""Record audio from microphone"""CHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 1RATE = 16000p = pyaudio.PyAudio()stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)print("开始录音...")frames = []for _ in range(0, int(RATE / CHUNK * record_seconds)):data = stream.read(CHUNK)frames.append(data)print("录音结束")stream.stop_stream()stream.close()p.terminate()wf = wave.open(filename, 'wb')wf.setnchannels(CHANNELS)wf.setsampwidth(p.get_sample_size(FORMAT))wf.setframerate(RATE)wf.writeframes(b''.join(frames))wf.close()def listen_for_wake_word(wake_word="小绿"):"""Listen for the wake word using Baidu Speech Recognition"""temp_file = "temp.wav"record_audio(temp_file, 3)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537  # Mandarin})if result.get('err_no') == 0:text = result['result'][0]if wake_word in text:return Truereturn Falsedef get_response(prompt):"""Generate response using DeepSeek API"""return call_deepseek_api(prompt)def speak(text):"""Convert text to speech"""engine.say(text)engine.runAndWait()def main():print("小绿已启动,等待唤醒...")while True:if listen_for_wake_word():print("唤醒成功!请说出你的问题...")speak("您好,需要什么帮助")temp_file = "question.wav"record_audio(temp_file, 5)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537  # Mandarin})if result.get('err_no') == 0:user_input = result['result'][0]print(f"你说: {user_input}")response = get_response(user_input)print(f"小绿: {response}")speak(response)else:print("抱歉,我没有听清楚")speak("抱歉,我没有听清楚")if __name__ == "__main__":main()

修改了一些,调用百度进行了语音合成输出,回答更自然一些

 

from aip import AipSpeech
import os
from dotenv import load_dotenv
import wave
import pyaudio
import requests
import json
from datetime import datetime
import pygame  # 用于播放音频
import tempfile# Load environment variables
load_dotenv()
APP_ID = os.getenv("BAIDU_APP_ID")
API_KEY = os.getenv("BAIDU_API_KEY")
SECRET_KEY = os.getenv("BAIDU_SECRET_KEY")# Initialize Baidu Speech client
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)def call_deepseek_api(prompt):"""Call DeepSeek API for intelligent response"""url = "https://api.deepseek.com/v1/chat/completions"headers = {"Content-Type": "application/json","Authorization": f"Bearer {os.getenv('DEEPSEEK_API_KEY')}"}data = {"model": "deepseek-chat","messages": [{"role": "user","content": prompt}],"temperature": 0.7,"max_tokens": 200}try:response = requests.post(url, headers=headers, json=data)response.raise_for_status()result = response.json()return result['choices'][0]['message']['content'].strip()except Exception as e:print(f"Error calling DeepSeek API: {str(e)}")return "抱歉,我暂时无法回答这个问题"def record_audio(filename, record_seconds=5):"""Record audio from microphone"""CHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 1RATE = 16000p = pyaudio.PyAudio()stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)print("开始录音...")frames = []for _ in range(0, int(RATE / CHUNK * record_seconds)):data = stream.read(CHUNK)frames.append(data)print("录音结束")stream.stop_stream()stream.close()p.terminate()wf = wave.open(filename, 'wb')wf.setnchannels(CHANNELS)wf.setsampwidth(p.get_sample_size(FORMAT))wf.setframerate(RATE)wf.writeframes(b''.join(frames))wf.close()def listen_for_wake_word(wake_word="小绿"):"""Listen for the wake word using Baidu Speech Recognition"""temp_file = "temp.wav"record_audio(temp_file, 3)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537  # Mandarin})if result.get('err_no') == 0:text = result['result'][0]if wake_word in text:return Truereturn Falsedef get_response(prompt):"""Generate response using DeepSeek API"""return call_deepseek_api(prompt)def speak(text):"""Convert text to speech using Baidu TTS"""result = client.synthesis(text, 'zh', 1, {'vol': 5,  # 音量,取值0-15,默认为5中音量'spd': 4,  # 语速,取值0-9,默认为5中语速'pit': 5,  # 音调,取值0-9,默认为5中语调'per': 4   # 发音人选择,0为女声,1为男声,3为度逍遥,4为度丫丫})if not isinstance(result, dict):# 使用临时文件with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f:f.write(result)temp_path = f.name# 播放语音文件pygame.mixer.init()pygame.mixer.music.load(temp_path)pygame.mixer.music.play()# 等待播放完成while pygame.mixer.music.get_busy():pygame.time.Clock().tick(10)  # 控制循环频率,避免占用过多 CPU# 强制释放资源pygame.mixer.music.stop()pygame.mixer.quit()# 播放完成后删除临时文件os.remove(temp_path)else:print(f"语音合成失败: {result}")def main():print("小绿已启动,等待唤醒...")while True:if listen_for_wake_word():print("您好,需要什么帮助....")speak("您好,需要什么帮助")temp_file = "question.wav"record_audio(temp_file, 5)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537  # Mandarin})if result.get('err_no') == 0:user_input = result['result'][0]print(f"你说: {user_input}")response = get_response(user_input)print(f"小绿: {response}")speak(response)else:print("抱歉,我没有听清楚")speak("抱歉,我没有听清楚")if __name__ == "__main__":main()

 

 

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

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

相关文章

超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction

1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术,广泛应用于医学影像领域。通过重建和可视化三维结构,3D超声能够显著提高诊断精度和效率,同时减少医生的脑力负担。本技术文档将详细阐述…

Docker 部署 Graylog 日志管理系统

Docker 部署 Graylog 日志管理系统 前言一、准备工作二、Docker Compose 配置三、启动 Graylog 服务四、访问 Graylog Web 界面总结 前言 Graylog 是一个开源的日志管理平台,专为实时日志收集、分析和可视化设计。它支持强大的搜索功能,并且与 Elastics…

【图论】并查集的学习和使用

目录 并查集是什么? 举个例子 组成 父亲数组: find函数: union函数: 代码实现: fa[] 初始化code: find code: 递归实现: 非递归实现: union code : 画图模拟: 路径压缩&#xff1a…

FPGA-流水灯

Quartus中使用Verilog实现 根据之前所学内容,打开Quartus 软件,新建FPGA项目文件,建立好空项目过后,选择Verilog HDL File,因为我们要使用Verilog代码实现仿真。 详细操作可参考往期博客: FPGA 实验报告&a…

React19源码系列之createRoot的执行流程是怎么的?

2024年12月5日,react发布了react19版本。后面一段时间都将学习它的源码,并着手记录。 react官网:react19新特性 https://react.dev/blog/2024/12/05/react-19 在用vite创建react项目的使用,main.tsx主文件都会有以下代码。 //i…

全网首创/纯Qt/C++实现国标GB28181服务/实时视频/云台控制/预置位/录像回放和下载/事件订阅/语音对讲

一、前言说明 用纯Qt来实现这个GB28181的想法很久了,具体可以追溯到2014年,一晃十年都过去了,总算是整体的框架和逻辑都打通了,总归还是杂七杂八的事情多,无法静下心来研究具体的协议,最开始初步了解协议后…

Qt 实操记录:打造自己的“ QQ 音乐播放器”

目录 一.界面设计1.成品界面分析2.head界面实现3.body界面实现4.主界面设置(1).设置无标题栏与阴影效果(2).重写鼠标事件实现拖拽 二.自定义控件1.BtFrom界面设计2.推荐页面设计3.recBox页面设计4.recBoxItem页面设计(1).eventFilter介绍和使用(2).QJsonObject介绍和使用(3).向…

如何打造安全稳定的亚马逊采购测评自养号下单系统?

在当今的电商领域,亚马逊作为全球领先的在线购物平台,其商品种类繁多,用户基数庞大,成为了众多商家和消费者的首选。而对于一些需要进行商品测评或市场调研的用户来说,拥有一个稳定、安全的亚马逊账号体系显得尤为重要…

Python文字识别OCR

一.引言 文字识别,也称为光学字符识别(Optical Character Recognition, OCR),是一种将不同形式的文档(如扫描的纸质文档、PDF文件或数字相机拍摄的图片)中的文字转换成可编辑和可搜索的数据的技术。随着技…

如何在 Github 上获得 1000 star?

作为程序员,Github 是第一个绕不开的网站。我们每天都在上面享受着开源带来的便利,我相信很多同学也想自己做一个开源项目,从而获得大家的关注。然而,理想很丰满,现实却是开发了很久的项目仍然无人问津。 最近&#x…

汽车机械钥匙升级一键启动的优点

汽车机械钥匙升级一键启动的优点主要包括: 便捷性:一键启动功能的引入极大地提升了用车便捷性。车主无需翻找钥匙,只需在车辆感应范围内轻触启动键,即可轻松发动汽车。 安全性:移动管家专车专用一键启动系统配备了防…

[QT]深入理解Qt中的信号与槽机制

文章目录 信号与槽1. 信号和槽概述信号的本质槽的本质说明 2. 信号和槽的使用2.1 连接信号和槽2.2 查看内置信号和槽2.3 通过 Qt Creator 生成信号槽代码 3. 自定义信号和槽3.1 基本语法3.2 带参数的信号和槽**示例1:重载信号槽****示例2:信号槽参数列表…

Axure设计之下拉多选框制作教程C(中继器)

利用Axure制作下拉多选器组件可以极大地提升原型制作的效率和效果。以下是基于你提供的详细步骤的详细指导,帮助你在Axure中实现一个功能完善、高保真且可复用的下拉多选器组件。 一、案例预览 预览地址:https://pghy0i.axshare.com 实现效果包括&#…

STC89C52单片机学习——第25节: [11-1]蜂鸣器

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.03.18 51单片机学习——第25节: [11-1]蜂鸣器 前言开发板说明引用解答和科普一、蜂鸣器…

Linux上的`i2c-tools`工具集的详细介绍;并利用它操作IMX6ULL的I2C控制器进而控制芯片AP3216C读取光照值和距离值

IC-Tools 工具集介绍 i2c-tools 是 Linux 下用于 IC 设备调试 的用户空间工具集(你也可以把它看成是一个库,类似于之前自己用过的触摸屏库tslib库、FreeType矢量字符库),它提供了一系列命令行工具,可以扫描、读取、写入 IC 设备,…

《CircleCI:CircleCI:解锁软件开发持续集成(CI)和持续部署(CD)高效密码》:此文为AI自动生成

《CircleCI:CircleCI:解锁软件开发持续集成(CI)和持续部署(CD)高效密码》:此文为AI自动生成 一、CircleCI 初印象 在当今软件开发的快节奏赛道上,持续集成(CI&#xff0…

LinuX---Shell脚本创建和执行

概述: 它是一个命令行解释器,接收应用程序/用户命令,然后调用操作系统内核。 Shell还是一个功能强大的编程语言,易编写、易调试、灵活性强。 Linux提供的Shell解析器有 atguiguubuntu:~$ cat /etc/shells # /etc/shells: valid …

再学:Solidity数据类型

目录 1.uint:无符号整型 2.引用类型 3.数组 4.注意gas的消耗 ​编辑 5.映射 1.uint:无符号整型 注意能容纳的最大值和最小值 2.引用类型 值类型赋值 相当于 拷贝 若拷贝开销过大,可以考虑引用类型。 memory:只存在于函数内部…

Docker Desktop配置国内镜像源教程

在使用 Docker 时,由于默认镜像源在国外,经常会遇到下载速度慢、连接超时等问题。本文将详细介绍如何在 Windows 系统中为 Docker 配置国内镜像源,以提升镜像拉取速度。 常用国内镜像源 https://docker.1ms.run清华镜像源 https://docker.m…

C#中SerialPort 的使用

最近在学习C#的SerialPort ,关于SerialPort 的使用,做如下总结: 1.可以通过函数System.IO.Ports.SerialPort.GetPortNames() 将获得系统所有的串口名称。C#代码如下: string[] sPorts SerialPort.GetPortNames(); foreach(stri…