当前位置:   article > 正文

Python开发语音聊天机器人_ai语音对话编程教程

ai语音对话编程教程

知识储备:(语音识别,语音读取,人工智能)

百度AI的连接地址:https://ai.baidu.com/

1、百度AI语音识别技术:百度语音识别通过 REST API 的方式给开发者提供一个通用的 HTTP 接口。上传需要完整的录音文件,录音时长不超过60s。对于任意操作系统,任意编程语言,只要可以对百度语音服务器发起http请求的,均可以使用此接口。

首先我们学习百度给的语音识别demo:https://ai.baidu.com/docs#/ASR-Online-Python-SDK/top

第一步安装python sdk:执行 pip install baidu-aip 命令。(PyCharm直接在File-Setting中搜索baidu-aip导入即可)

第二步新建AipSpeech:AipSpeech是语音识别的Python SDK客户端,为使用语音识别的开发人员提供了一系列的交互方法。

新建AipSpeech代码如下:(APP_ID,API_KEY,SECRET_KEY均在创建应用时都会给出)

  1. from aip import AipSpeech
  2. """ 你的 APPID AK SK """
  3. APP_ID = '你的 App ID'
  4. API_KEY = '你的 Api Key'
  5. SECRET_KEY = '你的 Secret Key'
  6. client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

第三步对语音文件进行识别:client.asr('speech',‘format’,‘rate’,'dev_pid'),speech为建立包含语音内容的Buffer对象, 语音文件的格式,pcm 或者 wav 或者 amr。不区分大小写;format为音频文件格式,pcm 或者 wav 或者 amr。不区分大小写。推荐pcm文件;rate为采样率,16000,固定值;dev_pid为输入法模型(默认1537),下图为dev_pid的取样表。

dev_pid语言模型是否有标点备注
1536普通话(支持简单的英文识别)搜索模型无标点支持自定义词库
1537普通话(纯中文识别)输入法模型有标点支持自定义词库
1737英语 有标点不支持自定义词库
1637粤语 有标点不支持自定义词库
1837四川话 有标点不支持自定义词库
1936普通话远场远场模型有标点不支持

语音识别代码如下:

  1. # 读取文件
  2. def get_file_content(filePath):
  3. with open(filePath, 'rb') as fp:
  4. return fp.read()
  5. # 识别本地文件
  6. client.asr(get_file_content('audio.pcm'), 'pcm', 16000, {'dev_pid': 1536})

语音识别 返回数据参数详情:client.asr()返回的是一个字典类型(下表为返回字典对应键的名称与作用)

参数类型是否一定输出描述
err_noint错误码(0为返回成功)
err_msgint错误码描述
snint语音数据唯一标识,系统内部产生,用于 debug
resultint识别结果数组,提供1-5 个候选结果,string 类型为识别的字符串, utf-8 编码

返回成功与失败样例:(result为录音文件的识别内容,用户可通过此键来获取)

错误类型:由err_no可以推断出错误类型

错误码用户输入/服务端含义一般解决方法
3300用户输入错误输入参数不正确请仔细核对文档及参照demo,核对输入参数
3301用户输入错误音频质量过差请上传清晰的音频
3302用户输入错误鉴权失败token字段校验失败。请使用正确的API_KEY 和 SECRET_KEY生成。或QPS、调用量超出限额。或音频采样率不正确(可尝试更换为16k采样率)。
3303服务端问题语音服务器后端问题请将api返回结果反馈至论坛或者QQ群
3304用户请求超限用户的请求QPS超限请降低识别api请求频率 (qps以appId计算,移动端如果共用则累计)
3305用户请求超限用户的日pv(日请求量)超限请“申请提高配额”,如果暂未通过,请降低日请求量
3307服务端问题语音服务器后端识别出错问题目前请确保16000的采样率音频时长低于30s。如果仍有问题,请将api返回结果反馈至论坛或者QQ群
3308用户输入错误音频过长音频时长不超过60s,请将音频时长截取为60s以下
3309用户输入错误音频数据问题服务端无法将音频转为pcm格式,可能是长度问题,音频格式问题等。 请将输入的音频时长截取为60s以下,并核对下音频的编码,是否是16K, 16bits,单声道。
3310用户输入错误输入的音频文件过大语音文件共有3种输入方式: json 里的speech 参数(base64后); 直接post 二进制数据,及callback参数里url。 分别对应三种情况:json超过10M;直接post的语音文件超过10M;callback里回调url的音频文件超过10M
3311用户输入错误采样率rate参数不在选项里目前rate参数仅提供16000,填写4000即会有此错误
3312用户输入错误音频格式format参数不在选项里目前格式仅仅支持pcm,wav或amr,如填写mp3即会有此错误

 2、语音读取(目的:将用户所讲内容打印至客户端):

PyAudio的应用和使用,此第三方库可以进行录音,播放,生成wav文件等等。

第一步安装PyAudio:PyCharm直接在File-Setting中搜索PyAudio导入,同导入百度AI类似。

第二步实现对于音频文件的录制(wave库和PyAudio库的使用):

音频文件的录制:

  1. from pyaudio import PyAudio,paInt16
  2. import wave,time
  3. def SaveVoice():
  4. pa=PyAudio()
  5. wf=wave.open(r'T.wav','wb')#打开wave文件
  6. wf.setnchannels(1)#配置声道数
  7. wf.setsampwidth(2)# 采样宽度2bytes
  8. wf.setframerate(16000)#采样率
  9. stream=pa.open(format=paInt16,channels=wf.getnchannels(),rate=wf.getframerate(),input=True,frames_per_buffer=1024) #打开一个stream
  10. buff=[]#存储声音信息
  11. start=time.time()#开始运行时间戳
  12. print('say:')
  13. while time.time()<start+6:#录制6秒
  14. buff.append(stream.read(wf.getframerate()))
  15. stream.close()#关闭stream
  16. pa.terminate()
  17. wf.writeframes(b''.join(buff))
  18. wf.close()#关闭wave

或者使用第三方库SpeechRecognition :pip install SpeechRecognition即可

  1. def my_record(rate=16000):
  2. r = sr.Recognizer()
  3. with sr.Microphone(sample_rate=rate) as source:
  4. print("please say something")
  5. audio = r.listen(source)#读入声音信息
  6. with open("T.wav", "wb") as f:
  7. f.write(audio.get_wav_data())#得到wave信息写入音频文件
  8. print("录音完成!")

3、构建一个机器人(图灵机器):连接http://www.turingapi.com/

申请一个账号即可免费创建属于自己的机器人(可在官网上对其属性进行设置),普通注册用户一天可以免费调用100次。

使用说明:1、编码方式UTF-8;2、接口地址:http://openapi.tuling123.com/openapi/api/v2

3、请求方式:http post;4、参数格式:json格式;(具体属性的参数说明详见下表)

  1. {
  2. "reqType":0,#数据类型为整型,用于区分传入的数据类型,0-文本(默认)、1-图片、2-音频
  3. "perception": {#必填项,用户输入的数据
  4. "inputText": {#非必填项,用于保存文本信息
  5. "text": ""#string类型,必填项,文本内容
  6. },
  7. "inputImage": {#非必填项,用于保存图片信息
  8. "url": "imageUrl"#string类型,必填项,图片地址
  9. },
  10. "selfInfo": {#非必填项,用于识别用户信息
  11. "location": {
  12. "city": "",
  13. "province": "",
  14. "street": ""
  15. }
  16. }
  17. },
  18. "userInfo": {#必填项,识别用户信息
  19. "apiKey": "",#此处为图灵机器人的apiKey
  20. "userId": ""
  21. }
  22. }

参数说明

参数类型是否必须取值范围说明
reqTypeintN-输入类型:0-文本(默认)、1-图片、2-音频
perception-Y-输入信息
userInfo-Y-用户参数

perception

参数类型是否必须取值范围说明
inputText-N-文本信息
inputImage-N-图片信息
inputMedia-N-音频信息
selfInfo-N-客户端属性

注意:输入参数必须包含inputText或inputImage或inputMedia!(必须有一个存在

inputText

参数类型是否必须取值范围说明
textStringY1-128字符直接输入文本

inputImage

参数类型是否必须取值范围说明
urlStringY 图片地址

inputMedia

参数类型是否必须取值范围说明
urlStringY 音频地址

selfInfo

参数类型是否必须取值范围说明
location-N-地理位置信息

location

参数类型是否必须取值范围说明
cityStringY-所在城市
provinceStringN-省份
streetStringN-街道

userInfo

参数类型是否必须取值范围说明
apiKeyStringY32位机器人标识
userIdStringY长度小于等于32位用户唯一标识
groupIdStringN长度小于等于64位群聊唯一标识
userIdNameStringN长度小于等于64位群内用户昵称

 返回成功与失败的示例:

失败样例:(只返回错误提示类型)

  1. {#返回失败信息
  2. 'intent':
  3. {
  4. 'code':5000#错误码,0表示上传成功。
  5. }
  6. }
  7. 异常码 说明
  8. 5000 无解析结果
  9. 6000 暂不支持该功能
  10. 4000 请求参数格式错误
  11. 4001 加密方式错误
  12. 4002 无功能权限
  13. 4003 该apikey没有可用请求次数
  14. 4005 无功能权限
  15. 4007 apikey不合法
  16. 4100 userid获取失败
  17. 4200 上传格式错误
  18. 4300 批量操作超过限制
  19. 4400 没有上传合法userid
  20. 4500 userid申请个数超过限制
  21. 4600 输入内容为空
  22. 4602 输入文本内容超长(上限150)
  23. 7002 上传信息失败
  24. 8008 服务器错误
  25. 0 上传成功

 成功样例:以询问酒店为例

  1. {
  2. "intent": {#用于表示请求意图
  3. "code": 10005,
  4. "intentName": "",
  5. "actionName": "",
  6. "parameters": {
  7. "nearby_place": "酒店"
  8. }
  9. },
  10. "results": [#输出结果集合
  11. {
  12. "groupType": 1,
  13. "resultType": "url",
  14. "values": {
  15. "url": "http://m.elong.com/hotel/0101/nlist/#indate=2016-12-10&outdate=2016-12-11&keywords=%E4%BF%A1%E6%81%AF%E8%B7%AF"
  16. }
  17. },
  18. {
  19. "groupType": 1,
  20. "resultType": "text",
  21. "values": {#输出值
  22. "text": "亲,已帮你找到相关酒店信息"#机器反馈信息
  23. }
  24. }
  25. ]
  26. }

参数说明

参数类型是否必须取值范围说明
intent-Y-请求意图
results-N-输出结果集

intent

参数类型是否包含取值范围说明
codeintY-输出功能code
intentNameStringN-意图名称
actionNameStringN-意图动作名称
parametersMapN-功能相关参数

results

参数类型是否包含取值范围说明
resultTypeStringY文本(text);连接(url);音频(voice);视频(video);图片(image);图文(news)输出类型
values-Y-输出值
groupTypeintY-‘组’编号:0为独立输出,大于0时可能包含同组相关内容 (如:音频与文本为一组时说明内容一致)

 通过requests库的post方法将json数据和编码格式UTF-8(import requests)

  1. import requests#导入requests库,多用于网络爬虫
  2. import json#导入json库
  3. TulingUrl='http://openapi.tuling123.com/openapi/api/v2'
  4. turing_api_key = "你申请的图灵机器人id"
  5. def RobotSpeak(usersay="你好"):#默认为对话你好
  6. robot={
  7. "perception": {
  8. "inputText": {
  9. "text": usersay#用户询问内容
  10. }
  11. },
  12. "userInfo": {
  13. "apiKey": turing_api_key ,
  14. "userId": 'Dudu'#识别用户可随机书写
  15. }
  16. }
  17. response=json.loads(requests.post(TulingUrl,None,robot,headers={'Content-Type':'charset=UTF-8'}).text)
  18. print(response)
  19. if __name__=='__main__':
  20. RobotSpeak('你叫什么名字')

到此位置我们基本可以实现简单的人机交互功能,即用户说一句话机器给出相应的答复,但仅仅是文字的输入输出似乎满足不了我们的需求,我们可以在此基础上扩展新的功能,比如让机器将反馈的信息以语音的形式得以呈现。

进阶部分(语音输出反馈信息):

Python给我们提供了一个第三方库pyttsx,可以实现文字转换语音的基本功能。

  1. import pyttsx3#导入第三方库
  2. engine=pyttsx3.init()#初始化engine
  3. rate = engine.getProperty('rate')
  4. engine.setProperty('rate', rate-66)#设置语速
  5. engine.say('要说的内容')
  6. engine.runAndWait()#没有此句无声音

完整聊天机器人(代码):

  1. from aip import AipSpeech
  2. from pyaudio import PyAudio,paInt16
  3. import requests,json,wave,time,pyttsx3
  4. #百度AI,配置信息
  5. APP_ID = ''#百度ai应用id
  6. API_KEY = ''#百度ai应用的键值
  7. SECRET_KEY = ''
  8. client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
  9. #图灵机器,配置信息
  10. TulingUrl='http://openapi.tuling123.com/openapi/api/v2'
  11. turing_api_key = ""#图灵机器人api_key
  12. # 读取文件
  13. def get_file_content(filePath):
  14. with open(filePath, 'rb') as fp:
  15. return fp.read()
  16. #用户语音输入
  17. def SaveVoice():
  18. pa=PyAudio()
  19. wf=wave.open(r'T.wav','wb')#打开wave文件
  20. wf.setnchannels(1)#配置声道数
  21. wf.setsampwidth(2)# 采样宽度2bytes
  22. wf.setframerate(16000)#采样率
  23. stream=pa.open(format=paInt16,channels=wf.getnchannels(),rate=wf.getframerate(),input=True,frames_per_buffer=1024) #打开一个stream
  24. buff=[]#存储声音信息
  25. start=time.time()#开始运行时间戳
  26. print('用户说:')
  27. while time.time()<start+6:#录制6秒
  28. buff.append(stream.read(wf.getframerate()))
  29. stream.close()#关闭stream
  30. pa.terminate()
  31. wf.writeframes(b''.join(buff))
  32. wf.close()#关闭wave
  33. #接受机器人响应
  34. def RobotSpeakText(usersay="你好"):
  35. robot={
  36. "perception": {
  37. "inputText": {
  38. "text": usersay
  39. }
  40. },
  41. "userInfo": {
  42. "apiKey": turing_api_key ,
  43. "userId": 'Dudu'
  44. }
  45. }
  46. response=json.loads(requests.post(TulingUrl,None,robot,headers={'Content-Type':'charset=UTF-8'}).text)
  47. return str(response['results'][0]['values']['text'])
  48. #语音发声
  49. def RobotVoice(robotsay="我没听清,你在说一遍"):
  50. engine=pyttsx3.init()
  51. rate=engine.getProperty('rate')
  52. engine.setProperty('rate',rate-66)
  53. engine.say(robotsay)
  54. engine.runAndWait()
  55. #主函数
  56. def main():
  57. while True:
  58. try:
  59. SaveVoice()
  60. result = client.asr(get_file_content('T.wav'), 'wav', 16000, {'dev_pid': 1536}) # 识别本地文件
  61. usersay=result['result'][0]
  62. print(usersay)
  63. robotsay=RobotSpeakText(usersay)
  64. print('小嘟嘟说:')
  65. print(robotsay)
  66. RobotVoice(robotsay)
  67. except:#异常处理
  68. break
  69. if __name__=='__main__':
  70. main()

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/374629
推荐阅读
相关标签
  

闽ICP备14008679号