使用 PyAudio、语音识别、pyttsx3 和 SerpApi 构建简单的基于 CLI 的语音助手

一、介绍
正如您从标题中看到的,这是一个演示项目,显示了一个非常基本的语音助手脚本,可以根据 Google 搜索结果在终端中回答您的问题。
您可以在 GitHub 存储库中找到完整代码:dimitryzub/serpapi-demo-projects/speech-recognition/cli-based/
后续博客文章将涉及:
- 使用Flask、一些 HTML、CSS 和 Javascript 的基于 Web 的解决方案。
- 使用Flutter和Dart的基于 Android 和 Windows 的解决方案。
二、我们将在这篇博文中构建什么
2.1 环境准备
首先,让我们确保我们处于不同的环境中,并正确安装项目所需的库。最难(可能)是 安装 .pyaudio,关于此种困难可以参看下文克服:
[解决]修复 win 32/64 位操作系统上的 PyAudio pip 安装错误
2.2 虚拟环境和库安装
在开始安装库之前,我们需要为此项目创建并激活一个新环境:
# if you're on Linux based systems
$ python -m venv env && source env/bin/activate
$ (env) <path># if you're on Windows and using Bash terminal
$ python -m venv env && source env/Scripts/activate
$ (env) <path># if you're on Windows and using CMD
python -m venv env && .\env\Scripts\activate
$ (env) <path>
解释python -m venv env
告诉 Python 运行 module( -m
)venv
并创建一个名为 的文件夹env
。&&
代表“与”。source <venv_name>/bin/activate
将激活您的环境,并且您将只能在该环境中安装库。
现在安装所有需要的库:
pip install rich pyttsx3 SpeechRecognition google-search-results
现在到pyaudio
. 请记住,pyaudio
安装时可能会引发错误。您可能需要进行额外的研究。
如果您使用的是 Linux,我们需要安装一些开发依赖项才能使用pyaudio
:
$ sudo apt-get install -y libasound-dev portaudio19-dev
$ pip install pyaudio
如果您使用的是 Windows,则更简单(使用 CMD 和 Git Bash 进行测试):
pip install pyaudio
三、完整代码
import os
import speech_recognition
import pyttsx3
from serpapi import GoogleSearch
from rich.console import Console
from dotenv import load_dotenvload_dotenv('.env')
console = Console()def main():console.rule('[bold yellow]SerpApi Voice Assistant Demo Project')recognizer = speech_recognition.Recognizer()while True:with console.status(status='Listening you...', spinner='point') as progress_bar:try:with speech_recognition.Microphone() as mic:recognizer.adjust_for_ambient_noise(mic, duration=0.1)audio = recognizer.listen(mic)text = recognizer.recognize_google(audio_data=audio).lower()console.print(f'[bold]Recognized text[/bold]: {text}')progress_bar.update(status='Looking for answers...', spinner='line')params = {'api_key': os.getenv('API_KEY'),'device': 'desktop','engine': 'google','q': text,'google_domain': 'google.com','gl': 'us','hl': 'en'}search = GoogleSearch(params)results = search.get_dict()try:if 'answer_box' in results:try:primary_answer = results['answer_box']['answer']except:primary_answer = results['answer_box']['result']console.print(f'[bold]The answer is[/bold]: {primary_answer}')elif 'knowledge_graph' in results:secondary_answer = results['knowledge_graph']['description']console.print(f'[bold]The answer is[/bold]: {secondary_answer}')else:tertiary_answer = results['answer_box']['list']console.print(f'[bold]The answer is[/bold]: {tertiary_answer}')progress_bar.stop() # if answered is success -> stop progress bar.user_promnt_to_contiune_if_answer_is_success = input('Would you like to to search for something again? (y/n) ')if user_promnt_to_contiune_if_answer_is_success == 'y':recognizer = speech_recognition.Recognizer()continue # run speech recognizion again until `user_promt` == 'n'else:console.rule('[bold yellow]Thank you for cheking SerpApi Voice Assistant Demo Project')breakexcept KeyError:progress_bar.stop()error_user_promt = input("Sorry, didn't found the answer. Would you like to rephrase it? (y/n) ")if error_user_promt == 'y':recognizer = speech_recognition.Recognizer()continue # run speech recognizion again until `user_promt` == 'n'else:console.rule('[bold yellow]Thank you for cheking SerpApi Voice Assistant Demo Project')breakexcept speech_recognition.UnknownValueError:progress_bar.stop()user_promt_to_continue = input('Sorry, not quite understood you. Could say it again? (y/n) ')if user_promt_to_continue == 'y':recognizer = speech_recognition.Recognizer()continue # run speech recognizion again until `user_promt` == 'n'else:progress_bar.stop()console.rule('[bold yellow]Thank you for cheking SerpApi Voice Assistant Demo Project')breakif __name__ == '__main__':main()
四、代码说明
导入库:
import os
import speech_recognition
import pyttsx3
from serpapi import GoogleSearch
from rich.console import Console
from dotenv import load_dotenv
rich
用于在终端中进行漂亮格式化的 Python 库。pyttsx3
Python 的文本到语音转换器可离线工作。SpeechRecognition
用于将语音转换为文本的 Python 库。google-search-results
SerpApi 的 Python API 包装器,可解析来自 15 个以上搜索引擎的数据。os
读取秘密环境变量。在本例中,它是 SerpApi API 密钥。dotenv
从文件加载环境变量(SerpApi API 密钥).env
。.env
文件可以重命名为任何文件:(.napoleon
.
点)代表环境变量文件。
定义rich
Console()
. 它将用于美化终端输出(动画等):
console = Console()
定义main
所有发生的函数:
def main():console.rule('[bold yellow]SerpApi Voice Assistant Demo Project')recognizer = speech_recognition.Recognizer()
在函数的开头,我们定义speech_recognition.Recognizer()
并将console.rule
创建以下输出:
───────────────────────────────────── SerpApi Voice Assistant Demo Project ─────────────────────────────────────
下一步是创建一个 while 循环,该循环将不断监听麦克风输入以识别语音:
while True:with console.status(status='Listening you...', spinner='point') as progress_bar:try:with speech_recognition.Microphone() as mic:recognizer.adjust_for_ambient_noise(mic, duration=0.1)audio = recognizer.listen(mic)text = recognizer.recognize_google(audio_data=audio).lower()console.print(f'[bold]Recognized text[/bold]: {text}')
console.status
-rich
进度条,仅用于装饰目的。speech_recognition.Microphone()
开始从麦克风拾取输入。recognizer.adjust_for_ambient_noise
旨在根据环境能量水平校准能量阈值。recognizer.listen
监听实际的用户文本。recognizer.recognize_google
使用 Google Speech Recongition API 执行语音识别。lower()
是降低识别文本。console.print
允许使用文本修改的语句rich
print
,例如添加粗体、斜体等。
spinner='point'
将产生以下输出(使用python -m rich.spinner
查看列表spinners
):
之后,我们需要初始化 SerpApi 搜索参数以进行搜索:
progress_bar.update(status='Looking for answers...', spinner='line')
params = {'api_key': os.getenv('API_KEY'), # serpapi api key 'device': 'desktop', # device used for 'engine': 'google', # serpapi parsing engine: https://serpapi.com/status'q': text, # search query 'google_domain': 'google.com', # google domain: https://serpapi.com/google-domains'gl': 'us', # country of the search: https://serpapi.com/google-countries'hl': 'en' # language of the search: https://serpapi.com/google-languages# other parameters such as locations: https://serpapi.com/locations-api
}
search = GoogleSearch(params) # where data extraction happens on the SerpApi backend
results = search.get_dict() # JSON -> Python dict
progress_bar.update
将会progress_bar
用新的status
(控制台中打印的文本)进行更新,spinner='line'
并将产生以下动画:
之后,使用 SerpApi 的Google 搜索引擎 API从 Google 搜索中提取数据。
代码的以下部分将执行以下操作:
try:if 'answer_box' in results:try:primary_answer = results['answer_box']['answer']except:primary_answer = results['answer_box']['result']console.print(f'[bold]The answer is[/bold]: {primary_answer}')elif 'knowledge_graph' in results:secondary_answer = results['knowledge_graph']['description']console.print(f'[bold]The answer is[/bold]: {secondary_answer}')else:tertiary_answer = results['answer_box']['list']console.print(f'[bold]The answer is[/bold]: {tertiary_answer}')progress_bar.stop() # if answered is success -> stop progress baruser_promnt_to_contiune_if_answer_is_success = input('Would you like to to search for something again? (y/n) ')if user_promnt_to_contiune_if_answer_is_success == 'y':recognizer = speech_recognition.Recognizer()continue # run speech recognizion again until `user_promt` == 'n'else:console.rule('[bold yellow]Thank you for cheking SerpApi Voice Assistant Demo Project')breakexcept KeyError:progress_bar.stop() # if didn't found the answer -> stop progress barerror_user_promt = input("Sorry, didn't found the answer. Would you like to rephrase it? (y/n) ")if error_user_promt == 'y':recognizer = speech_recognition.Recognizer()continue # run speech recognizion again until `user_promt` == 'n'else:console.rule('[bold yellow]Thank you for cheking SerpApi Voice Assistant Demo Project')break
最后一步是处理麦克风没有拾取声音时的错误:
# while True:
# with console.status(status='Listening you...', spinner='point') as progress_bar:
# try:# speech recognition code# data extraction codeexcept speech_recognition.UnknownValueError:progress_bar.stop() # if didn't heard the speech -> stop progress baruser_promt_to_continue = input('Sorry, not quite understood you. Could say it again? (y/n) ')if user_promt_to_continue == 'y':recognizer = speech_recognition.Recognizer()continue # run speech recognizion again until `user_promt` == 'n'else:progress_bar.stop() # if want to quit -> stop progress barconsole.rule('[bold yellow]Thank you for cheking SerpApi Voice Assistant Demo Project')break
console.rule()
将提供以下输出:
───────────────────── Thank you for cheking SerpApi Voice Assistant Demo Project ──────────────────────
添加if __name__ == '__main__'
惯用语,以防止用户在无意时意外调用某些脚本,并调用main
将运行整个脚本的函数:
if __name__ == '__main__':main()
五、链接
rich
pyttsx3
SpeechRecognition
google-search-results
os
dotenv
相关文章:

使用 PyAudio、语音识别、pyttsx3 和 SerpApi 构建简单的基于 CLI 的语音助手
德米特里祖布☀️ 一、介绍 正如您从标题中看到的,这是一个演示项目,显示了一个非常基本的语音助手脚本,可以根据 Google 搜索结果在终端中回答您的问题。 您可以在 GitHub 存储库中找到完整代码:dimitryzub/serpapi-demo-project…...

C++11——多线程
目录 一.thread类的简单介绍 二.线程函数参数 三.原子性操作库(atomic) 四.lock_guard与unique_lock 1.lock_guard 2.unique_lock 五.条件变量 一.thread类的简单介绍 在C11之前,涉及到多线程问题,都是和平台相关的,比如windows和linu…...

力扣每日一题48:旋转图像
题目描述: 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],…...

操作系统——吸烟者问题(王道视频p34、课本ch6)
1.问题分析:这个问题可以看作是 可以生产多种产品的 单生产者-多消费者问题 2.代码——这里就是由于同步信号量的初值都是1,所以没有使用mutex互斥信号, 总共4个同步信号量,其中一个是 finish信号量...

通讯协议学习之路:CAN协议理论
通讯协议之路主要分为两部分,第一部分从理论上面讲解各类协议的通讯原理以及通讯格式,第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN;视频会发布在bilibili(UID:399951374) 序、…...

Redis常用配置详解
目录 一、Redis查看当前配置命令二、Redis基本配置三、RDB全量持久化配置(默认开启)四、AOF增量持久化配置五、Redis key过期监听配置六、Redis内存淘汰策略七、总结 一、Redis查看当前配置命令 # Redis查看当前全部配置信息 127.0.0.1:6379> CONFIG…...

卷积神经网络CNN学习笔记-MaxPool2D函数解析
目录 1.函数签名:2.学习中的疑问3.代码 1.函数签名: torch.nn.MaxPool2d(kernel_size, strideNone, padding0, dilation1, return_indicesFalse, ceil_modeFalse) 2.学习中的疑问 Q:使用MaxPool2D池化时,当卷积核移动到某位置,该卷积核覆盖区域超过了输入尺寸时,MaxPool2D会…...
基于图像字典学习的去噪技术研究与实践
图像去噪是计算机视觉领域的一个重要研究方向,其目标是从受到噪声干扰的图像中恢复出干净的原始图像。字典学习是一种常用的图像去噪方法,它通过学习图像的稀疏表示字典,从而实现对图像的去噪处理。本文将详细介绍基于字典学习的图像去噪技术…...

记一次Clickhouse 复制表同步延迟排查
现象 数据从集群中一个节点写入之后,其他两个节点无法及时查询到数据,等了几分钟。因为我们ck集群是读写分离架构,也就是一个节点写数据,其他节点供读取。 排查思路 从业务得知,数据更新时间点为:11:30。…...
Maven的详细安装步骤说明
Step 1: 下载Maven 首先,您需要从Maven官方网站(https://maven.apache.org/)下载Maven的最新版本。在下载页面上,找到与您操作系统对应的二进制文件(通常是.zip或.tar.gz格式),下载到本地。 St…...

金融机器学习方法:K-均值算法
目录 1.算法介绍 2.算法原理 3.python实现示例 1.算法介绍 K均值聚类算法是机器学习和数据分析中常用的无监督学习方法之一,主要用于数据的分类。它的目标是将数据划分为几个独特的、互不重叠的子集或“集群”,以使得同一集群内的数据点彼此相似&…...

移远通信携手MIKROE推出搭载LC29H系列模组的Click boards开发板,为物联网应用带来高精定位服务
近日,移远通信与MikroElektronika(以下简称“MIKROE”)展开合作,基于移远LC29H系列模组推出了多款支持实时动态载波相位差分技术(RTK)和惯性导航(DR)技术的Click Boards™ 开发板&am…...

Spring Cloud 之 Sentinel简介与GATEWAY整合实现
简介 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 熔断 …...

搭建网站七牛云CDN加速配置
打开七牛云后台;添加域名; 添加需要加速的域名,比如我添加的是motoshare.cn 源站配置,这里要用IP地址,访问的目录下面要有能访问测试的文件,尽量不要用源站域名,这个只能用加速二级域名&#x…...
算法|每日一题|做菜顺序|贪心
1402. 做菜顺序 原题地址: 力扣每日一题:做菜顺序 一个厨师收集了他 n 道菜的满意程度 satisfaction ,这个厨师做出每道菜的时间都是 1 单位时间。 一道菜的 「 like-time 系数 」定义为烹饪这道菜结束的时间(包含之前每道菜所花…...

json-server工具准备后端接口服务环境
1.安装全局工具json-server(全局工具仅需要安装一次) 官网:json-server - npm 点击Getting started可以查看使用方法 在终端中输入yarn global add json-server或npm i json-server -g 如果输入json-server -v报错 再输入npm install -g j…...

文心一言 VS 讯飞星火 VS chatgpt (118)-- 算法导论10.3 3题
三、用go语言,在ALLOCATE-OBJECT和 FREE-OBJECT过程的实现中,为什么不需要设置或重置对象的 prev 属性呢? 文心一言: 在 Go 语言中,ALLOCATE-OBJECT 和 FREE-OBJECT 过程的实现通常不需要显式地设置或重置对象的 prev 属性。这…...

numpy矩阵画框框
在n>5(n是奇数)的nn数组中,用*画外方框和内接菱形。 (本笔记适合熟悉numpy的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那…...

三十六、【进阶】show profiles分析
1、profiles (1)详情 可以帮助清楚的展现,每一条SQL语句的执行耗时,以及时间都耗费到哪里去了 (2)基础语句 2、查看是否支持profiles mysql> select have_profiling; ------------------ | have_prof…...

商品规格项数据的遍历以及添加
简介 今天在处理规格项的数据时遇到了一些问题,接下来就给大家分享一下 规格项数据设计 "specifications": [{"goodsSpecificationId": 6,"goodsSpecificationName": "网络类型","goodsTypeId": 24,"goods…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
深度解析云存储:概念、架构与应用实践
在数据爆炸式增长的时代,传统本地存储因容量限制、管理复杂等问题,已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性,成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理,云存储正重塑数据存储与…...

高保真组件库:开关
一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...
PostgreSQL 与 SQL 基础:为 Fast API 打下数据基础
在构建任何动态、数据驱动的Web API时,一个稳定高效的数据存储方案是不可或缺的。对于使用Python FastAPI的开发者来说,深入理解关系型数据库的工作原理、掌握SQL这门与数据库“对话”的语言,以及学会如何在Python中操作数据库,是…...
java+webstock
maven依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.5</version></dependency><dependency><groupId>org.apache.tomcat.websocket</groupId&…...