python实现类似Siri的AI语音聊天机器人(需要图灵机器人和百度语音合成的API) 您所在的位置:网站首页 聊天app机器人 python实现类似Siri的AI语音聊天机器人(需要图灵机器人和百度语音合成的API)

python实现类似Siri的AI语音聊天机器人(需要图灵机器人和百度语音合成的API)

2023-09-16 05:30| 来源: 网络整理| 查看: 265

程序简介:模仿Siri,参考微信公众号:学习python的正确姿势,在语音播放和搜索的基础上,增加了语音输入和打开常用软件功能。

一、配置 Windows10系统python3.7pycharm

(其实这些都不重要)

二、主要体系框架 (1)图灵机器人API

自己做一个生动的能聊天的机器人太麻烦了,不过图灵机器人已经帮我们做好了,而且提供了开放的接口,我们注册一个,使用它的接口就可以轻松实现,链接在下方:

图灵机器人官网

注册登录后,如下图所示创建机器人创建机器人

创建好后你就拥有了这样一个语音聊天机器人: 机器人API

你还可以在“人物设置”栏里设置它的名字,性别,年龄之类的 还挺别致。。 人物设置 这个不重要,我们看看它的API使用文档,了解一下怎么用的 图灵文档 嗯,好像很简单的亚子! 不管了,赶紧来试一下。。

import requests import json urls = 'http://openapi.tuling123.com/openapi/api/v2' # 图灵接口的url api_key = "!!!这里要用你自己的api密钥!!!" prologue = "主人您好,我是Niubility,爱你哦~" # 定义开场白 count = 1 # 用来计数输入的次数 # 回复 def respond(data): data_dict = { "reqType":0, "perception": { "inputText": { "text": data }, }, "userInfo": { "apiKey": api_key, "userId": "584403" } } result = requests.post(urls, json=data_dict) content = (result.content).decode('utf-8') # print(content) ans = json.loads(content) text = ans['results'][0]['values']['text'] print('Niubility:',text) # 机器人取名就叫Niubility if __name__ == "__main__": print("Niubility:", prologue) while True: data = input('{}//你:'.format(count)) # 输入对话内容 respond(data) count += 1

运行一下: 在这里插入图片描述 阔以阔以!!! 第一步,图灵机器人API就这样解决了,下一步! (图灵未认证用户一天只能聊三句话,认证之后一天可以聊100句,我们只要学习它的用法就可以了)

(2)百度语音合成API

同样百度提供了开放的语音合成API,我们也注册一个吧,很简单,网址:

百度智能云官网

方法和上面图灵机器人差不多 注册完成之后是这样的: 在这里插入图片描述 查阅官方文档,用法差不多,有语音合成和语音识别两种,我们这里先完成语音合成吧,官方文档整理的很好: 百度语音合成api1 百度语音合成api2 试一下

首先要下载它的库:

pip3 install baidu-api

然后我们给他定义成方法,传入参数text为要语音合成的文字

import os import playsound # 播放音频的库 from aip import AipSpeech # 百度语音的api """ 你的 APPID AK SK """ APP_ID = '!!!你的 App ID!!!' API_KEY = '!!!你的 Api Key!!!' SECRET_KEY = '!!!你的 Secret Key!!!' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) # 语音合成 def speak_(text): result = client.synthesis(text, 'zh', 1, { 'vol': 5, 'per': 0, 'spd': 5, 'pit': 5 }) # 识别正确返回语音二进制 错误则返回dict 参照下面错误码 if not isinstance(result, dict): with open('audio.mp3', 'wb') as f: f.write(result) playsound.playsound('audio.mp3') # 播放 os.remove('audio.mp3') # 放完后删除音频文件,否则第二次会无法写入

再在respond(data)方法最后一行调用speak_(text)即可播放语音

(3)键盘监听+录音+保存wav文件

语音输入这部分我想实现的目标功能是:按一下键盘空格键开始录音,再按一下空格键录音结束,然后保存为一个.wav文件

1. 键盘监听

键盘监听我用的是pynput库 基本用法:

from pynput.keyboard import Listener def check_input(): with Listener(on_press=press) as listener: listener.join() def press(key): # print(key.char) # 按下键盘的操作,例如打印出按下的字符 pass 2. 录音

录音我用的是pyaudio库

基本用法:

import pyaudio """pyaudio参数""" CHUNK = 1024 # 数据包或者数据片段 FORMAT = pyaudio.paInt16 # pyaudio.paInt16表示我们使用量化位数 16位来进行录音 CHANNELS = 1 # 声道,1为单声道,2为双声道 RATE = 16000 # 采样率,每秒钟16000次 # RECORD_SECONDS = 5 # 录音时间 def recoder(): _frames = [] p = pyaudio.PyAudio() stream = p.open(channels=CHANNELS, format=FORMAT, rate=RATE, input=True, frames_per_buffer=CHUNK) while 1: data = stream.read(CHUNK) _frames.append(data) stream.stop_stream() stream.close() p.terminate()

需要注意的是,后面用到的百度语音识别双声道识别效果很差,设置单声道后就很好了,所以设置CHANNELS=1

还有后面用到的百度语音识别只支持16000采样率,所以RATE设置为16000

3. 保存.wav文件

用到wave库 结合pyaudio,基本用法:

import wave import pyaudio """pyaudio参数""" CHUNK = 1024 # 数据包或者数据片段 FORMAT = pyaudio.paInt16 # pyaudio.paInt16表示我们使用量化位数 16位来进行录音 CHANNELS = 1 # 声道,1为单声道,2为双声道 RATE = 16000 # 采样率,每秒钟16000次 # RECORD_SECONDS = 5 # 录音时间 def recoder(): _frames = [] p = pyaudio.PyAudio() stream = p.open(channels=CHANNELS, format=FORMAT, rate=RATE, input=True, frames_per_buffer=CHUNK) while 1: data = stream.read(CHUNK) _frames.append(data) stream.stop_stream() stream.close() p.terminate() # 保存wav文件 wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(_frames)) wf.close() # print("Saved") (4)百度语音识别API

有了使用语音合成API的基础,用语音识别API就很easy 前面是一样的,所以我把他写在方法外,可以公用:

from aip import AipSpeech """ 你的 APPID AK SK """ APP_ID = '你的 App ID' API_KEY = '你的 Api Key' SECRET_KEY = '你的 Secret Key' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

后面就是语音识别,传入的参数是音频文件的二进制码,文件格式(我们用的是wav),采样率(只能用16000,所以前面的录音必须设置RATE为16000),语言类别(默认1537,普通话)。

# 读取文件 def get_file_content(filePath): with open(filePath, 'rb') as fp: return fp.read() # 识别本地文件 client.asr(get_file_content(WAVE_OUTPUT_FILENAME), 'wav', 16000, { 'dev_pid': 1537, })

WAVE_OUTPUT_FILENAME就是我们刚才录音保存的文件名。

(5)浏览器搜索 + 打开常用软件功能 1. 浏览器搜索

打开浏览器,我们需要用到:webbrowser库, 没有的话自己pip安装一下 基本用法:

url = "www.baidu.com" webbrowser.get().open(url)

我们前面已经能通过语音得到我们说的话text,当我们说的话text中有“搜索”两个字时,打开百度并搜索我们要搜的内容,实现代码:

if '搜索' in text: _, keywords = text.split('搜索') url = 'https://www.baidu.com/s?wd=' + keywords webbrowser.get().open(url) else: ... 2. 打开常用软件

windows打开软件有很多方法,参考:Python中四种运行其他程序的方式 我用的是win32api库,基本用法: ShellExecute(hwnd, op, file, args, dir, show)

hwnd: 父窗口的句柄,如果没有父窗口,则为0op : 要运行的操作,为open,print或者为空file: 要运行的程序,或者打开的脚本args: 要向程序传递的参数,如果打开的是文件则为空dir : 程序初始化的目录show: 是否显示窗口

盘他:

if '搜索' in data: ... elif '打开' in data: _, name = data.split('打开') # print(name) if '网易云' in name: win32api.ShellExecute(0, 'open', 'D:\App\CloudMusic\cloudmusic.exe', '', '', 1) # 打开网易云, elif 'QQ' in name or 'qq' in name: win32api.ShellExecute(0, 'open', r'D:\App\QQ\Bin\QQScLauncher.exe', '', '', 1) # 打开QQ elif '微信' in name: win32api.ShellExecute(0, 'open', r'D:\App\WeChat\WeChat.exe', '', '', 1) # 打开微信 三、综合实现:

为了实现目标功能,还涉及到多线程,将键盘监听单独占用一个线程,设置run,初始值为False,当按下空格时,run变为True,再次按下时,run变为False,以此类推,当run为True时,开始录音,run为False时,录音结束。 运行效果图:(语音输入,语音输出) 运行效果图

全部完整代码: (代码中api_key之类的要用你自己的噢)

import webbrowser import requests import json import playsound import os import win32api import pyaudio import wave import threading from aip import AipSpeech from pynput.keyboard import Listener prologue = '主人您好,我是Niubility,爱你哦~' # 开场白 """图灵机器人API""" urls = 'http://openapi.tuling123.com/openapi/api/v2' key = '**********' api_key = '********************' count = 1 # 计数 run = False """pyaudio参数""" CHUNK = 1024 # 数据包或者数据片段 FORMAT = pyaudio.paInt16 # pyaudio.paInt16表示我们使用量化位数 16位来进行录音 CHANNELS = 1 # 声道,1为单声道,2为双声道 RATE = 16000 # 采样率,每秒钟16000次 # RECORD_SECONDS = 5 # 录音时间 WAVE_OUTPUT_FILENAME = "output.wav" # 保存录音文件名 """ 你的 APPID AK SK """ APP_ID = '**********' API_KEY = '********************' SECRET_KEY = '********************' client = AipSpeech(APP_ID, API_KEY, SECRET_KEY) # 百度语音接口 def recoder(): _frames = [] global run p = pyaudio.PyAudio() stream = p.open(channels=CHANNELS, format=FORMAT, rate=RATE, input=True, frames_per_buffer=CHUNK) while run: data = stream.read(CHUNK) _frames.append(data) stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(_frames)) wf.close() # print("Saved") # 按键按下空格时控制录音功能开关 def press(key): global run try: # print(str(key)) if str(key) == 'Key.space': run = not run # print(run) except AttributeError as e1: print(e1) pass # 监听键盘 def check_input(): with Listener(on_press=press) as listener: listener.join() # 读取录音文件字节码 def get_file_content(filePath): with open(filePath, 'rb') as fp: return fp.read() # 识别录音,语音转文字 def lic(): res = client.asr(get_file_content(WAVE_OUTPUT_FILENAME), 'wav', 16000, { 'dev_pid': 1537, }) text = res['result'][0] # print(text) return text # 语音合成 def speak_(text): result = client.synthesis(text, 'zh', 1, { 'vol': 5, 'per': 0, 'spd': 5, 'pit': 5 }) # 识别正确返回语音二进制 错误则返回dict 参照下面错误码 if not isinstance(result, dict): with open('audio.mp3', 'wb') as f: f.write(result) playsound.playsound('audio.mp3') os.remove('audio.mp3') # 第一层判别 def respond(data): if '歌' in data: douban_rul = 'https://douban.fm/' webbrowser.get().open(douban_rul) elif '搜索' in data: _, keywords = data.split('搜索') baidu_url = 'https://www.baidu.com/s?wd=' + keywords webbrowser.get().open(baidu_url) elif '打开' in data: _, name = data.split('打开') # print(name) if '网易云' in name: win32api.ShellExecute(0, 'open', 'D:\App\CloudMusic\cloudmusic.exe', '', '', 1) # 打开网易云 elif 'QQ' in name or 'qq' in name: win32api.ShellExecute(0, 'open', r'D:\App\QQ\Bin\QQScLauncher.exe', '', '', 1) # 打开QQ elif '微信' in name: win32api.ShellExecute(0, 'open', r'D:\App\WeChat\WeChat.exe', '', '', 1) # 打开微信 else: data_dict = { "reqType":0, "perception": { "inputText": { "text": data }, }, "userInfo": { "apiKey": api_key, "userId": "!!!你自己的userId!!! " } } result = requests.post(urls, json=data_dict) content = (result.content).decode('utf-8') # print(content) ans = json.loads(content) text = ans['results'][0]['values']['text'] print('Niubility:',text) speak_(text) if __name__ == '__main__': print('Niubility:', prologue) speak_(prologue) print('{}//你:按 空格 键开始说话...'.format(count), end=' ') t1 = threading.Thread(target=check_input,args=()) # 监听键盘 t1.start() while 1: if run is True: print('\r{}//你:正在听呢,说完了请再按 空格 键...'.format(count), end=' ') recoder() text2 = lic() print('\r{}//你:'.format(count),text2) respond(text2) count += 1 print('{}//你:按 空格 键开始说话...'.format(count), end=' ')


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有