之前在网上看到一个题目使用语音控制你的浏览器,感觉挺有意思的,就想着实现一个简单的语音识别程序,这里我选择的是百度语音识别,还有好多不错的如科大讯飞等都可以使用。
语音识别过程分为三个部分:
1)录音
2)获取参数access token,有效期为一个月(开发文档)
3)上传录音文件
1.首先你需要一个注册一个百度账号,进行登录,可以直接使用注册过的百度网盘账号进行登录,登录的网址在此处https://login.bce.baidu.com/,选择语音识别,点击创建应用,为你的应用起一个名字:
创建完成后,如下图所示,AppID,API Key,Secret Key这三个参数需要用到
然后看百度相关的技术开发文档,必要的参数一定带全。
2.由于需要进行录音,这里使用到pyaudio库,需要先进行安装,但是直接使用pip install pyaudio进行安装会出现错误,推荐使用下面的命令进行安装:
sudo apt-get install portaudio19-dev python-all-dev python3-all-dev
pip install pyaudio
安装成功后,接下来开始第1部分录音,代码中都有详细的注释,直接上代码:
import pyaudio
import wave
import requests
import json
import base64
import os
#1.录音
#用Pyaudio录制音频(该库可以进行录音,播放,生成wav文件)
def audio_record(rec_time,filename):
"""
:param rec_time: 音频录制时间
:param filename: 输出音频文件名
"""
CHUNK=1024#定义数据流块
FORMAT=pyaudio.paInt16#16bit编码格式
CHANNELS=1#单声道
RATE=16000#16000采样频率
#创建一个音频对象
p=pyaudio.PyAudio()
#创建音频数据流
stream=p.open(format=FORMAT,#音频流wav格式
channels=CHANNELS,#单声道
rate=RATE,#采样率16000
input=True,#输入
frames_per_buffer=CHUNK)
print('start recording...')
frames=list()#空列表用于保存录制的音频流
#录制音频数据
for i in range(0,int(RATE/CHUNK*rec_time)):
data=stream.read(CHUNK)
frames.append(data)
#录制完成
print(frames)
#停止数据流
stream.stop_stream()
stream.close()
#关闭pyaudio
p.terminate()
print('recording done...')
#保存音频文件
with wave.open(filename,'wb') as f:
f.setnchannels(CHANNELS)#设置音频声道数
f.setsampwidth(p.get_sample_size(FORMAT))#以字节为单位返回样本宽度
f.setframerate(RATE)#设置取样频率
第2部分,获取参数token
#2 使用appKey secretKey 访问 https://openapi.baidu.com 换取 token
def Get_token():
#baidu_server='https://openapi.baidu.com/oauth/2.0/token'
grant_type = 'client_credentials'
# API KEY
client_id = 'PrKnhUppGEsqrG8mVG2qIq8O'
# SECRERT KEY
client_secret = 'Al4cRfrlRGaMCCkz3kLsd4MXOoQP28iD'
# 拼接url
url = 'https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id={}&client_secret={}'.format(
client_id, client_secret)
# 发送Post请求 获取acess_token
req = requests.post(url)
data_dict = json.loads(req.text) # 将json字符串转换为python字典
print(req.text)
print(data_dict['access_token'])
return data_dict['access_token']
此段代码,可以单独运行下,打印token看是否能获取到,token指为如下所示:
返回的数据:scope中含有audio_voice_assistant_get 表示有语音识别能力, 注意语音服务的调用地址是https://openapi.baidu.com/oauth/2.0/token
第3部分,上传录音(有两种方式:第一种是Json方式,第二种方式是Raw方式,详细见开发文档)
#3.上传录音文件
def BaiduYuYin(file_url,token):
try:
RATE='16000'
FORMAT='wav'
CUID='wate_play'
DEV_PID='1536' #普通话:支持简单的英文识别
file_url=file_url
token = token
#以字节格式读取文件之后进行编码
with open(file_url,'rb') as f:
speech=base64.b64encode(f.read()).decode('utf-8')
size = os.path.getsize(file_url)#语音文件的字节数
headers={'Content-Type':'application/json'}#json格式post上传本地文件
url='https://vop.baidu.com/server_api'
data={
"format":FORMAT,#格式
"rate":RATE,#取样频率,固定值16000
"dev_pid":DEV_PID,#语音识别类型
"speech":speech,#本地语音文件的二进制数据,需要进行base64编码
"cuid":CUID,#用户唯一标识,用来区分用户 建议填写能区分用户的机器MAC地址或IMEI码,长度为60字符以内。
"len":size,#语音文件的字节数
"channel":1,#声道数,仅支持单声道,固定值为1
"token":token,
}
req=requests.post(url,json.dumps(data),headers)
data_dict=json.loads(req.text)
print(data_dict['result'][0])
return data_dict['result'][0][::-1]
except:
return '识别不清楚'
最后写一个调度函数run(),运行程序
#4.调度
def run(rec_time,file_name):
#1.录音
audio_record(rec_time,file_name)
#2.获取token
access_token=Get_token()
#3.上传录音
BaiduYuYin(file_name,access_token)
if __name__ == '__main__':
#录音时间为5秒,文件名为'record1.wav'
run(5,'record1.wav')
若想要你的电脑可以录音,需要提前打开麦克风,运行此程序后在五秒内说出一段话(可能需要大点声),控制台会打印出来,测试过之后发现准确率还可以,