微信登录
注册忘记密码
查看: 1300|回复: 5

树莓派开发自己的智能语音系统 - 百度语音识别API

[复制链接]

该用户从未签到

发表于 2022-6-26 18:04:10 | 显示全部楼层 |阅读模式
上一篇完成了软硬件环境的准备,这个章节将介绍如何借助免费的百度智能云平台API实现语音识别,会涉及一些代码,但是不多,主要是学习如何通过python和百度的API建立连接并返回识别结果,识别的过程不需要你操心,百度云帮你搞定就是了。类似的云平台还有很多,国内主要是百度,科大讯飞,阿里云,国外主要用google和亚马逊的alexa,中文识别的话当然推荐用国内的,如果你想弄一个英语聊天机器人,你最好用国外的。另外如果你想搭建聊天的机器人,推荐使用图灵机器人云平台,免费版的也提供了很多功能。闲话少说,进入正题。

第一步当然是先到云平台上注册,注册完之后你需要创建一个应用,系统会自动生成一个APIKey和SecretKey,如下图:


百度智能云API




这两个key是你连接百度云API的钥匙,所以一定得有。

第二步去图灵机器人网站注册一个账户,和百度云类似,注册后你一样会得到类似以下的东西:





好了,到目前为止,API注册完成,接下来就是如何去调用啦,是不是有点小激动^_^.

因为不是科班出身,在编程上没有那么正规,基本上想到什么写什么,没有认真规划程序的逻辑和架构,虽然没有系统的搭建,既然要写出来给大家看,好歹得整理一下实现的思路才行,不然很容易把大家搞晕,自己也会写晕。好吧,我大概整理了一下。
大概的程序架构,有点乱




大概的框架就是这样,因为这个章节是实现语音识别和对话,所以先看这个模块的程序构成,其中voice.py,voiceAPI.py属于百度提供的连接API的标准程序,只需要该一下上面的Key就行了,当然是改成你自己的。

为了便于后续调用,我把函数封装成Voice类,详细请看voice.py
# -*- coding: utf-8 -*-"""__autor__ : JERRY"""import sysimport os#reload(sys)#sys.setdefaultencoding("utf-8")class Voice: def __init__(self): self.RECORD_PATH = r"./record_voice.wav"#定义录音的路径 def recordVoice(self): print ("开始录音...") os.system('sudo arecord -D "plughw:1" -f S16_LE -r 16000 -d 4 %s'%self.RECORD_PATH) print ("录音结束...")  def recordCMD(self): print ("开始录音...") os.system('sudo arecord -D "plughw:1" -f S16_LE -r 16000 -d 3 %s'%self.RECORD_PATH) print ("录音结束...") def playVoice(self,url): #播放声音 #print url os.system('mpg123 "%s"'%url)#使用mplayer也可以确保系统安装了mpg123.
关于python类函数的调用,请读者自己度娘详情,相信很快了解怎么弄。这里不会详细介绍如何使用python。下面这个程序baiduAPI.py封装了BaiDuAPI类和TuLingAPI类:
# -*- coding: utf-8 -*-"""__autor__ : JERRY"""import sysimport requestsimport jsonimport urllib2import base64import urllibreload(sys)sys.setdefaultencoding("utf-8")class BaiDuAPI: def __init__(self): self.GRANT_TYPE = "client_credentials" self.CLIENT_ID = "你自己的key" #百度应用的 API Key self.CLIENT_SECRET = "你自己的secret" #百度应用的 API Secret self.TOKEN_URL = "https://openapi.baidu.com/oauth/2.0/token" self.RECOGNITION_URL = "http://vop.baidu.com/server_api" self.CUID = "b8-27-eb-be-eb-08" self.RECOGNITION_PATH = r"./record_voice.wav" self.SYNTHESIS_PATH = r"./play_voice.mp3" def getToken(self): #获取access_token body = { "grant_type":self.GRANT_TYPE, "client_id":self.CLIENT_ID, "client_secret":self.CLIENT_SECRET } r = requests.post(self.TOKEN_URL,data=body,verify=True) self.access_token = json.loads(r.text)["access_token"] return self.access_token def voiceRecognition(self): #语音识别 erro_dict = { 3300:"输入参数不正确", 3301:"音频质量过差", 3302:"鉴权失败", 3303:"语音服务器后端问题", 3304:"用户的请求QPS超限", 3305:"用户的日pv(日请求量)超限", 3307:"语音服务器后端识别出错问题", 3308:"音频过长", 3309:"音频数据问题", 3310:"输入的音频文件过大", 3311:"采样率rate参数不在选项里", 3312:"音频格式format参数不在选项里" } f = open(self.RECOGNITION_PATH,"rb") voice_data = f.read() f.close() speech_data = base64.b64encode(voice_data).decode("utf-8") speech_length = len(voice_data) post_data = { "format": "wav", "rate": 16000, "channel": 1, "cuid": self.CUID, "token": self.access_token, "speech": speech_data, "len": speech_length } json_data = json.dumps(post_data).encode("utf-8") json_length = len(json_data) req = urllib2.Request(self.RECOGNITION_URL, data=json_data) req.add_header("Content-Type", "application/json") req.add_header("Content-Length", json_length) resp = urllib2.urlopen(req) resp = resp.read() resp_data = json.loads(resp.decode("utf-8")) try: recognition_result = resp_data["result"][0] print (recognition_result) return recognition_result except: print (erro_dict[resp_data["err_no"]]) return False def voiceSynthesis(self,word): #语音合成 token = self.access_token cuid = self.CUID word = urllib.quote(word.encode("utf8")) url = "http://tsn.baidu.com/text2audio?tex="+word+"&lan=zh&cuid="+cuid+"&ctp=1&tok="+token+"&per=4" #urllib.urlretrieve(url,self.SYNTHESIS_PATH) ''' voice_data = urllib2.urlopen(url).read() voice_fp=open(filename,'wb+') voice_fp.write(voice_data) voice_fp.close() ''' return urlclass TurLingAPI: def __init__(self): self.Tuling_API_KEY = "你自己的key" self.URL = "http://www.tuling123.com/openapi/api" def turlingReply(self,word): #图灵获取回复 body = {"key": self.Tuling_API_KEY, "info": word.encode("utf-8")} res = requests.post(self.URL, data=body, verify=True) if res: date = json.loads(res.text) print (date["text"]) return date["text"] else: print ("对不起,未获取到回复信息") return False
以上程序除了key之外,不需要改动,直接调用类函数即可。你可以在树莓派上测试一下是否可以实现,以下是测试代码:
# -*- coding: utf-8 -*-"""__autor__ : Jerry zhong"""from voice import Voiceimport voiceAPIimport sys,osimport random#调用类voice = Voice()baiduAPI = voiceAPI.BaiDuAPI()turlingAPI = voiceAPI.TurLingAPI()baiduAPI.getToken()#定义对话函数def dialogue(text): url = baiduAPI.voiceSynthesis(text) voice.playVoice(url)#定义一个聊天函数def talk(): while True: voice.recordVoice()#开始录音5秒 try: recognition_result = baiduAPI.voiceRecognition()#返回识别结果 except: print("connection issue happened.") continue #return recognition_result #返回识别结果 don't use it otherwise exit the while the following code will not execute. if recognition_result:#返回识别结果为真 try: reply_result = turlingAPI.turlingReply(recognition_result)#调用图灵聊天机器人 except:#处理网络异常 print("connection issue happened.") continue if reply_result:#返回聊天结果为真时合成声音并播放 url = baiduAPI.voiceSynthesis(reply_result) voice.playVoice(url) else: dialogue(random.choice(["嗯,不知道该怎么回答呢","超出我的认知范围了","我的大脑短路了,哎","你得耐心点,网络不好"])) else: #返回识别结果为假 talk_num +=1  if talk_num >2: #超过3次无法获取应答,退出聊天 break else: continue dialogue(random.choice(["有事再叫我!","嗯,我先闪了","嗯,下次再聊","再见咯"]))#如果超时没有回应退出#直接调用运行主程序结束按ctr+ctalk()
如果你的程序不能运行,可能缺少笔必要的库,或者语法问题,自己仔细检查,编程就是如此,反复测试直到通过为止。当你发现识别和合成都没有问题时,恭喜你已经成功一半了。接下来我们要让她实现跟多的功能,不然只是和机器人尬聊感觉很傻。


声明:以上内容来源于网络,如有侵权请联系我们(123@shiyan.com)删除!

该用户从未签到

发表于 2022-6-26 18:09:07 | 显示全部楼层
不开源的不要!
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2022-6-26 18:11:00 | 显示全部楼层
早就用java实现过了
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2022-6-26 18:15:00 | 显示全部楼层
转发了
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2022-6-26 18:20:24 | 显示全部楼层
转发了
回复 支持 反对

使用道具 举报

签到天数: 2 天

[LV.1]初来乍到

发表于 2022-6-26 18:26:03 | 显示全部楼层
转发了
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则