从零开始理解百度语音识别API的Python实现

大家好!今天我要给大家详细讲解一个使用百度语音识别API的Python代码。这个代码可以将音频文件转换成文字,非常适合做语音转文字的应用。我会从最基础的概念开始讲起,确保没有任何编程基础的朋友也能理解。

翻译

一、代码概览

这段代码主要实现了以下几个功能:

  1. 连接百度语音识别API

  2. 检查音频文件是否符合要求

  3. 将音频文件发送到百度服务器进行识别

  4. 返回识别结果

整个代码大约150行,包含了一个主类BaiduASR和几个辅助函数。下面我会逐部分详细解释。

二、准备工作:导入必要的库

代码开头部分导入了多个Python库:

import os
import time
import json
import wave
import base64
import requests
from config import BAIDU_APP_ID, BAIDU_API_KEY, BAIDU_SECRET_KEY, BAIDU_TOKEN_URL, BAIDU_ASR_URL

让我们一个个来看这些库的作用:

  1. os:用于操作系统相关的功能,比如处理文件路径

  2. time:处理时间相关操作

  3. json:处理JSON格式的数据(JSON是一种常用的数据交换格式)

  4. wave:专门处理WAV格式的音频文件

  5. base64:将二进制数据编码为ASCII字符(因为网络传输需要文本格式)

  6. requests:发送HTTP请求到百度服务器

  7. config:从自定义配置文件导入百度API的认证信息

三、BaiduASR类详解

整个代码的核心是BaiduASR类,它封装了所有与百度语音识别相关的功能。

1. 初始化方法 init:

def __init__(self):self.app_id = BAIDU_APP_IDself.api_key = BAIDU_API_KEYself.secret_key = BAIDU_SECRET_KEYself.token_url = BAIDU_TOKEN_URLself.asr_url = BAIDU_ASR_URLself.access_token = Noneself.token_expires_time = 0

这里设置了百度API所需的各种参数:

  • app_id:应用ID

  • api_key:API密钥

  • secret_key:密钥

  • token_url:获取访问令牌的URL

  • asr_url:语音识别的API地址

  • access_token:访问令牌(初始为None)

  • token_expires_time:令牌过期时间(初始为0)

这些参数中,前五个都是从config.py文件中导入的,这样做的好处是可以保护敏感信息,避免直接写在代码中。

2. 获取访问令牌 get_access_token

def get_access_token(self):"""获取百度API访问令牌"""current_time = time.time()# 如果token未过期,直接返回if self.access_token and current_time < self.token_expires_time:return self.access_token# 获取新的access_tokenparams = {'grant_type': 'client_credentials','client_id': self.api_key,'client_secret': self.secret_key}try:response = requests.post(self.token_url, params=params, timeout=10)result = response.json()if 'access_token' in result:self.access_token = result['access_token']# token有效期一般为30天,这里设置为29天后过期self.token_expires_time = current_time + result.get('expires_in', 2592000) - 86400return self.access_tokenelse:return Noneexcept Exception as e:return None

这部分代码负责获取访问百度API所需的令牌(token)。百度API使用OAuth2.0认证,需要先获取token才能使用其他服务。

这部分代码负责获取访问百度API所需的令牌(token)。百度API使用OAuth2.0认证,需要先获取token才能使用其他服务。

详细解释:

  1. 首先检查当前是否有有效的token(未过期),如果有就直接返回

  2. 如果没有有效token,就准备请求参数:

    • grant_type:固定为'client_credentials'

    • client_id:API Key

    • client_secret:Secret Key

  3. 使用requests库发送POST请求到token_url

  4. 解析返回的JSON数据

  5. 如果获取成功,保存token并设置过期时间(提前1天过期,避免临界点问题)

  6. 返回token或None(失败时)

3. 验证音频文件 validate_audio

def validate_audio(self, file_path):"""验证音频文件格式"""try:with wave.open(file_path, 'rb') as wf:nchannels = wf.getnchannels()sampwidth = wf.getsampwidth()framerate = wf.getframerate()nframes = wf.getnframes()valid = Trueif nchannels != 1:valid = Falseif sampwidth != 2:valid = False# 百度API只支持特定采样率supported_rates = [8000, 16000]if framerate not in supported_rates:valid = Falseduration = nframes / float(framerate)if duration < 0.3:valid = Falseelif duration > 60:valid = Falseif valid:return True, framerate, durationreturn False, None, Noneexcept Exception as e:return False, None, None

这个方法检查音频文件是否符合百度API的要求:

  1. 使用wave模块打开WAV文件

  2. 获取音频参数:

    • nchannels:声道数(百度要求单声道)

    • sampwidth:采样宽度(百度要求16bit,即2字节)

    • framerate:采样率(百度支持8000或16000Hz)

    • nframes:总帧数

  3. 检查音频时长是否在0.3-60秒之间

  4. 返回检查结果、采样率和时长

4. 语音识别主函数 recognize_audio

这是最核心的方法,负责实际的语音识别工作:

def recognize_audio(self, file_path):"""语音识别主函数"""# 验证音频格式is_valid, sample_rate, duration = self.validate_audio(file_path)if not is_valid:return "音频格式不符合要求~"# 获取access_tokenaccess_token = self.get_access_token()if not access_token:return "获取访问令牌失败,请检查API密钥~"

首先验证音频文件并获取token,这两步是前置条件检查。

接下来是处理音频数据:

    # 读取音频文件并编码try:with open(file_path, 'rb') as f:audio_data = f.read()# base64编码audio_base64 = base64.b64encode(audio_data).decode('utf-8')# 确定音频格式file_ext = os.path.splitext(file_path)[1].lower()if file_ext == '.wav':format_type = 'wav'elif file_ext == '.pcm':format_type = 'pcm'elif file_ext == '.amr':format_type = 'amr'elif file_ext == '.m4a':format_type = 'm4a'else:format_type = 'wav'  # 默认wav格式

这部分代码:

  1. 读取音频文件的二进制数据

  2. 使用base64编码(因为HTTP传输需要文本数据)

  3. 根据文件扩展名确定格式类型

然后是准备请求参数:

        # 修复:确保采样率为整数,并根据百度API要求进行规范化if sample_rate == 16000:api_rate = 16000elif sample_rate == 8000:api_rate = 8000else:# 如果采样率不是标准值,使用最接近的标准值api_rate = 16000 if sample_rate > 12000 else 8000# 构建请求数据 - 注意:百度ASR使用POST请求,参数放在body中data = {'format': format_type,'rate': api_rate,  # 确保使用标准采样率'channel': 1,'speech': audio_base64,'len': len(audio_data),'cuid': 'python_client_v3',  # 修改cuid'token': access_token,'dev_pid':80001  # 改为普通话(纯中文识别),如果还有问题可以尝试15372}

这里构建了发送给百度API的请求数据,包括:

  • 音频格式

  • 采样率

  • 声道数(固定为1)

  • base64编码的音频数据

  • 音频数据长度

  • 客户端ID

  • 访问令牌

  • 语言模型ID(80001表示普通话纯中文识别)

接下来发送请求并处理响应

        # 设置请求头headers = {'Content-Type': 'application/json; charset=utf-8'}# 发送识别请求 - 注意:所有参数都在body中,不使用URL参数response = requests.post(self.asr_url,data=json.dumps(data),headers=headers,timeout=30)# 打印响应状态码和内容,用于调试result = response.json()# 处理识别结果if result.get('err_no') == 0:# 识别成功if 'result' in result and result['result']:recognized_text = ''.join(result['result'])print(f"{recognized_text}")return recognized_textelse:return "识别不到内容~"else:# 识别失败error_msg = result.get('err_msg', '未知错误')# 提供更详细的错误信息if result.get('err_no') == 3311:return f"采样率参数错误~ 请确保音频采样率为8000Hz或16000Hz"elif result.get('err_no') == 3300:return f"输入参数不正确~ 请检查音频格式"elif result.get('err_no') == 3301:return f"音频质量问题~ 请检查音频文件是否损坏"else:return f"识别失败~ 错误信息: {error_msg}"

这部分代码:

  1. 设置HTTP请求头,指定内容类型为JSON

  2. 发送POST请求到百度语音识别API

  3. 解析返回的JSON数据

  4. 根据返回的错误码处理不同情况:

    • 成功时返回识别结果

    • 失败时返回相应的错误信息

    • 异常处理

          except FileNotFoundError:return "找不到音频文件喵~"except requests.exceptions.RequestException as e:return "网络请求失败喵~"except Exception as e:return "识别过程发生异常喵~"
      

      捕获了三种可能的异常:

    • 文件不存在

    • 网络请求失败

    • 其他未知异常

四、单例模式实现

代码后面部分实现了单例模式,确保整个应用中只有一个BaiduASR实例:

# 全局ASR实例
_asr_instance = Nonedef get_asr_instance():"""获取ASR实例(单例模式)"""global _asr_instanceif _asr_instance is None:_asr_instance = BaiduASR()return _asr_instance

单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。这样做的好处是:

  1. 避免重复创建对象

  2. 节省系统资源

  3. 保持全局一致性

五、对外接口函数

为了方便使用,代码提供了两个简单的对外函数:

def validate_audio(file_path):"""验证音频文件格式(保持原有函数名)"""asr = get_asr_instance()is_valid, _, _ = asr.validate_audio(file_path)return is_validdef recognize_audio(file_path):"""语音识别函数(保持原有函数名和功能)"""asr = get_asr_instance()return asr.recognize_audio(file_path)

这样外部代码只需要调用这两个函数即可,不需要关心内部的复杂实现。

六、本地调试入口

最后是一个简单的测试代码:

# 本地调试入口
if __name__ == "__main__":file_path = "../input.wav"recognize_audio(file_path)

当直接运行这个Python文件时(而不是被导入为模块),会尝试识别"../input.wav"文件。

七、总结

这个百度语音识别的Python实现包含了以下几个关键点:

  1. 认证机制:使用OAuth2.0获取访问令牌

  2. 音频验证:确保音频格式符合API要求

  3. 数据编码:使用base64编码二进制音频数据

  4. API请求:构建正确的HTTP请求并处理响应

  5. 错误处理:全面考虑各种可能的错误情况

  6. 设计模式:使用单例模式管理实例

通过这样的封装,外部代码可以非常简单地进行语音识别,而不用关心内部复杂的实现细节。

希望这篇详细的解释能帮助你理解这段代码的工作原理!如果有任何不明白的地方,欢迎留言讨论。

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

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

相关文章

中小企业适用的几种会议签到工具

对企业行政来说&#xff0c;会议签到是件小事&#xff0c;但处理不好&#xff0c;会直接拖慢会议流程、影响管理效率、降低参会体验。尤其是面对人数多、时间紧、场地临时变动等情况&#xff0c;靠传统纸笔或简单Excel管理&#xff0c;往往应对乏力。 实际上&#xff0c;签到看…

android 11.0 打开ALOGV ALOGI ALOGD日志输出的方法

1.前言 在11.0的系统rom定制化开发中,在某些时候,需要打印ALOGV,ALOGI等TAG日志,在系统中,默认是关闭这些日志的, 防止日志打印过多,系统过于卡顿,但是有时候会为了调试,需要打开日志开关,所以就需要在系统源码中查看哪里 需要打开日志的开关,来实现日志的打印解决…

语言大模型or时序大模型?原理、应用与未来发展

引言 随着人工智能技术的飞速发展&#xff0c;大规模预训练模型已成为当前研究的热点。其中&#xff0c;语言模型和时序大模型作为两类重要的模型架构&#xff0c;分别在自然语言处理和时间序列分析领域展现出卓越的性能。然而&#xff0c;这两类模型在基本原理和应用场景上存…

【Excel数据分析】花垣县事业单位出成绩了,用Excel自带的M语言做一个数据分析

这里写自定义目录标题 花垣县事业单位出成绩了&#xff0c;用Excel自带的M语言做一个数据分析需求 花垣县事业单位出成绩了&#xff0c;用Excel自带的M语言做一个数据分析 Power Query M 语言&#xff0c;简称 M 语言&#xff0c;全名叫 Power Query Formula Language。 需求…

微处理器原理与应用篇---音频采集与串口传输功能的系统设计

这段内容是基于 STM32F407VGT6 单片机&#xff0c;实现音频采集与串口传输功能的嵌入式系统设计方案&#xff0c;包含硬件架构、软件逻辑和代码实现&#xff0c;核心是通过 ADC 采集音频、串口收发指令与数据 &#xff0c;以下分模块拆解&#xff1a; 一、系统设计概述 硬件&…

【大模型学习 | 量化】pytorch量化基础知识(1)

pytorch量化 [!note] 官方定义&#xff1a;performing computations and storing tensors at lower bitwidths than floating point precision.支持INT8量化&#xff0c;可以降低4倍的模型大小以及显存需求&#xff0c;加速2-4倍的推理速度通俗理解&#xff1a;降低权重和激活值…

ES和 Kafka 集群搭建过程中的典型问题、配置规范及最佳实践

Kafka 集群搭建与配置经验库文档&#xff08;完整会话汇总&#xff09; 一、会话问题分类与解决方案 1. Elasticsearch 映射解析错误 问题现象&#xff1a; {"error":{"root_cause":[{"type":"mapper_parsing_exception","re…

Linux-信号量

目录 POSIX信号量 信号量的原理 信号量的概念 申请信号量失败被挂起等待 信号量函数 二元信号量模拟实现互斥功能 基于环形队列的生产消费模型 下面环形队列采用数组模拟&#xff0c;用模运算来模拟环状特性&#xff0c;类似如此 空间资源和数据资源 生产者和消费者申请…

Unity2D 街机风太空射击游戏 学习记录 #14 环射和散射组合 循环屏幕道具

概述 这是一款基于Unity引擎开发的2D街机风太空射击游戏&#xff0c;笔者并不是游戏开发人&#xff0c;作者是siki学院的凉鞋老师。 笔者只是学习项目&#xff0c;记录学习&#xff0c;同时也想帮助他人更好的学习这个项目 作者会记录学习这一期用到的知识&#xff0c;和一些…

vue3 定时刷新

在Vue 3中实现定时刷新&#xff0c;你可以使用多种方法。这里列举几种常见的方法&#xff1a; 方法1&#xff1a;使用setInterval 这是最直接的方法&#xff0c;你可以在组件的mounted钩子中使用setInterval来定时执行某些操作&#xff0c;例如重新获取数据。 <template&…

局域网环境下浏览器安全限制的实用方法

在现代 Web 开发和网络应用中&#xff0c;我们常常会遇到浏览器出于安全考虑对某些功能进行限制的情况。例如麦克风、摄像头、地理位置等敏感功能&#xff0c;通常只能在 HTTPS 协议或 localhost 下使用。然而在局域网开发、测试或特定应用场景中&#xff0c;我们可能需要突破这…

如果你在为理解RDA、PCA 和 PCoA而烦恼,不妨来看看丨TomatoSCI分析日记

当你学习了 RDA、PCA 和 PCoA 这三种常见排序方法后&#xff0c;脑子里是不是也冒出过类似的疑问&#xff1a; PCA、PCoA、RDA 不都能画图吗&#xff1f;是不是可以互相替代&#xff1f; RDA 图上也有样本点&#xff0c;那我还需要 PCoA 干什么&#xff1f; ... 这些看似“…

MySQL (二):范式设计

在 MySQL 数据库设计中&#xff0c;范式设计是构建高效、稳定数据库的关键环节。合理的范式设计能够减少数据冗余、消除操作异常&#xff0c;让数据组织更加规范和谐。然而&#xff0c;过度追求范式也可能带来多表联合查询效率降低的问题。本文将深入讲解第一范式&#xff08;1…

什么是财务共享中心?一文讲清财务共享建设方案

目录 一、财务共享中心是什么 1.标准化流程 2.集中化处理 3.智能化系统 4.专业化分工 二、财务共享中心的四大模块 1. 共享系统 2. 共享流程 3. 共享组织 4. 共享数据 三、为什么很多财务共享中心做不下去&#xff1f; 1.只搬人&#xff0c;不换流程 2.系统买了&a…

001 双指针

双指针 双指针&#xff08;Two Pointers&#xff09; 双指针&#xff08;Two Pointers&#xff09; 对撞指针&#xff08;Opposite Direction Two Pointers&#xff09;&#xff1a; 对撞指针从两端向中间移动&#xff0c;一个指针从最左端开始&#xff0c;另一个最右端开始&a…

【unitrix】 4.7 库数字取反(not.rs)

一、源码 这段代码是用Rust语言实现的一个库&#xff0c;主要功能是对数字进行位取反操作&#xff08;按位NOT运算&#xff09;。 /*库数字取反* 编制人: $ource* 修改版次:0版完成版* 本版次创建时间: 2025年6月25日* 最后修改时间: 无* 待完善问题&#xff1a;无*/ use cor…

在ASP.NET Core WebApi中使用日志系统(Serilog)

一.引言 日志是构建健壮 Web API 的重要组成部分&#xff0c;能够帮助我们追踪请求、诊断问题、记录关键事件。在 .Net 中&#xff0c;日志系统由内置的 Microsoft.Extensions.Logging 抽象提供统一接口&#xff0c;并支持多种第三方日志框架&#xff08;如 Serilog、NLog 等&…

(链表:哈希表 + 双向链表)146.LRU 缓存

题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 LRU是Least Recently Used的缩写&#xff0c;即最近最少使用&#xff0c;是一种常用的页面置换算法&#xff0c;选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段&#xff0c;用来记…

Go Web开发框架实践:模板渲染与静态资源服务

Gin 不仅适合构建 API 服务&#xff0c;也支持 HTML 模板渲染和静态资源托管&#xff0c;使其可以胜任中小型网站开发任务。 一、模板渲染基础 1. 加载模板文件 使用 LoadHTMLGlob 或 LoadHTMLFiles 方法加载模板&#xff1a; r : gin.Default() r.LoadHTMLGlob("templ…

缓存与加速技术实践-Kafka消息队列

目录 #1.1消息队列 1.1.1什么是消息队列 1.1.2消息队列的特征 1.1.3为什么需要消息队列 #2.1ksfka基础与入门 2.1.1kafka基本概念 2.1.2kafka相关术语 2.1.3kafka拓扑架构 #3.1zookeeper概述介绍 3.1.1zookeeper应用举例 3.1.2zookeeper的工作原理是什么&#xff1f; 3.1.3z…