使用百度大脑构建一个闲聊机器人

使用百度大脑构建一个闲聊机器人

    • 使用的库
    • 录下你所说的内容
    • 调用百度语音识别系统将录音文件转化为文字
    • 调用百度UINIT进行回答
    • 在主函数中检测键盘输入

代码上传到了Github
主要参考了这篇博客

使用的库

from aip import AipSpeech
import json
import win32com.client
import urllib.request
import pyaudio
import threading
import wave
from pynput import keyboard
import time

录下你所说的内容

class Recorder():
    def __init__(self, chunk=1024, channels=1, rate=16000):
        self.CHUNK = chunk
        self.FORMAT = pyaudio.paInt16
        self.CHANNELS = channels
        self.RATE = rate
        self._running = True
        self._frames = []

    def start(self):
        threading._start_new_thread(self.__recording, ())

    def __recording(self):
        self._running = True
        # self._frames = []
        p = pyaudio.PyAudio()
        stream = p.open(format=self.FORMAT,
                        channels=self.CHANNELS,
                        rate=self.RATE,
                        input=True,
                        frames_per_buffer=self.CHUNK)
        while (self._running):
            data = stream.read(self.CHUNK)
            self._frames.append(data)

        stream.stop_stream()
        stream.close()
        p.terminate()

    def stop(self):
        self._running = False
        time.sleep(0.1)
        # sleep是为了保证def stop结束前录音线程也结束

    def save(self, filename):

        p = pyaudio.PyAudio()
        if not filename.endswith('.wav'):
            filename = filename + '.wav'
        wf = wave.open(filename, 'wb')
        wf.setnchannels(self.CHANNELS)
        wf.setsampwidth(p.get_sample_size(self.FORMAT))
        wf.setframerate(self.RATE)
        wf.writeframes(b''.join(self._frames))
        wf.close()
        self._frames.clear()

采样频率rate过高或者过低都会产生KeyError(无法识别所说的内容),在这里我们设置为16000。

调用百度语音识别系统将录音文件转化为文字

# 音频文件转文字:采用百度的语音识别python-SDK。网址:https://ai.baidu.com/tech/speech
# 百度语音识别API配置参数
APP_ID = 'your AppId'
API_KEY = 'your ApiKey'
SECRET_KEY = 'your SecretKey'
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
path = 'voices/myvoices.wav


# 将语音转文本
def listen():
    # 读取录音文件
    with open(path, 'rb') as fp:
        voices = fp.read()
    try:
        # 参数dev_pid表示识别的语种
        result = client.asr(voices, 'wav', 16000, {'dev_pid': 1537, })
        result_text = result['result'][0]
        global num
        num = num + 1
        print('Round {}:'.format(num))
        print('you said:', result_text)
        return result_text
    except KeyError:
        print('KeyError')
        speaker.Speak('我没有听清楚,请再说一遍...')
        return False

App Key、Secret Key等数据的获取参考这篇博客

调用百度UINIT进行回答

# 调用百度UNIT智能对话系统,网址:https://ai.baidu.com/unit/
# API配置参数
headers = {'Content-Type': 'application/json'}
access_token = 'your token'
url = 'https://aip.baidubce.com/rpc/2.0/unit/bot/chat?access_token=' + access_token


def baidu_unit(text_words):
    post_data = "{\"bot_session\":\"\",\"log_id\":\"7758521\",\"request\":{\"bernard_level\":1, " \
                "\"client_session\":\"{\\\"client_results\\\":\\\"\\\", \\\"candidate_options\\\":[]}\"," \
                "\"query\":\"" + text_words + "\",\"query_info\":{\"asr_candidates\":[],\"source\":\"KEYBOARD\"," \
                                              "\"type\":\"TEXT\"},\"updates\":\"\",\"user_id\":\"UNIT_DEV_你的百度账号昵称\"}," \
                                              "\"bot_id\":\"71625\",\"version\":\"2.0\"}"

    request = urllib.request.Request(url, data=post_data.encode('utf-8'), headers=headers)
    response = urllib.request.urlopen(request)
    content = response.read().decode("utf-8")
    content = json.loads(content)
    resp = content['result']['response']['action_list'][0]['say']
    print('robot said:', resp)
    return resp

上述代码的post_data中需要更改的就是user_id,这里采用“UNIT_DEV_”+“你的百度账号昵称”的形式,除此之外便是bot_id,是你所要使用的技能ID,71625代表了闲聊技能,其他技能的编号可以通过访问百度UNIT——新建机器人——添加技能的方式来查询。
使用百度大脑构建一个闲聊机器人_第1张图片
access_token则需要专门获取:

import urllib.request
import json

# client_id 为官网获取的AK, client_secret 为官网获取的SK
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=your AK&client_secret=your SK'
request = urllib.request.Request(host)
request.add_header('Content-Type', 'application/json; charset=UTF-8')
response = urllib.request.urlopen(request)
content = response.read()
content = json.loads(content)
if (content):
    print(content['access_token'])

注意这里的SK和AK与上面的不同,需要点击你刚才新建的机器人,选择“发布上线”——“获取Api Key/Secret Key”——创建应用,这里的AK和SK才是我们获取token所需要的。

在主函数中检测键盘输入

if __name__ == '__main__':
    num = 0
    rec = Recorder()
    print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
    print('Press \'t\' to start the record, and press \'p\' to stop.\n'
          'After that you only need to wait for the robot\'s response\n'
          'You can quit at any time by pressing esc.')
    print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n')
    with keyboard.Listener(on_press=on_press) as listener:
        listener.join()

函数on_press:

# 按下按键后的响应
def on_press(key):
    try:
        if key.char == 't':
            if not len(rec._frames) == 0:
                print('\nThe record has been going on, please check your command!')
            else:
                rec.start()
                print('\nRecording......')
        elif key.char == 'p':
            if len(rec._frames) == 0:
                print('\nThere is no data,please check your command!')
            else:
                rec.stop()
                rec.save('voices/myvoices.wav')
                print('\nWaiting for response......')
                rep_text = listen()
                if (rep_text):
                    res_text = baidu_unit(rep_text)
                    speaker.Speak(res_text)
                else:
                    print('There is something wrong with the server, you can wait for a moment and try again.')
    except AttributeError:
        if key == keyboard.Key.esc:
            return False
        # return false 则with ... as ... 结构结束

运行效果:

D:\PycharmProjects\voiceDetect\venv\Scripts\python.exe D:/PycharmProjects/voiceDetect/main.py
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Press 't' to start the record, and press 'p' to stop.
After that you only need to wait for the robot's response
You can quit at any time by pressing esc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

t
Recording......
t
The record has been going on, please check your command!
p
Waiting for response......
Round 2:
you said: 嗨,你好。
robot said: 你好啵啵啵
p
There is no data,please check your command!
t
Recording......
p
Waiting for response......
Round 3:
you said: 你叫什么名字?
robot said: 我怎么能说名字呢?

There is no data,please check your command!
pt
Recording......
p
Waiting for response......
Round 4:
you said: 那你能说什么?
robot said: 不知道
t
Recording......
p
Waiting for response......
Round 5:
you said: 你是男是女?
robot said: 男。我的id让人错觉女
t
Recording......
p
Waiting for response......
Round 6:
you said: 你的ID是啥?
robot said: 啥意思
t
Recording......
p
Waiting for response......
Round 7:
you said: 我问你,你的ID是什么?
robot said: 我不知道。
t
Recording......
p
Waiting for response......
Round 8:
you said: 你是不是有病?
robot said: 绝对不是病
t
Recording......
p
Waiting for response......
Round 9:
you said: 那你就是知道。
robot said: 知道知道
t
Recording......
p
Waiting for response......
Round 10:
you said: 我说那你就是智障。
robot said: 打错了智商
t
Recording......
p
Waiting for response......
Round 11:
you said: 不是智商,是智障。
robot said: 不关智商问题
t
Recording......
p
Waiting for response......
Round 12:
you said: 你就是有病。
robot said: 请注意文明用语
t
Recording......
p
Waiting for response......
Round 13:
you said: 你有病,你有病,你有病。
robot said: 我又不是没病!

Recording......
tp
Waiting for response......
Round 14:
you said: 你有什么病?
robot said: 没病啊
t
Recording......
p
Waiting for response......
Round 15:
you said: 说话前后矛盾,我看你就是知道。
robot said: 矛盾?
t
Recording......
p
Waiting for response......
Round 16:
you said: 你绝对是个真。
robot said: 必须真
t
Recording......
p
Waiting for response......
Round 17:
you said: 垃圾百度。
robot said: 百度尽全力变得更完美,希望你多多指教
t
Recording......
p
Waiting for response......
Round 18:
you said: 李彦宏去死吧!
robot said: 喂,你别乱说哦,小心警察蜀黍请你喝茶
t
Recording......
p
Waiting for response......
Round 19:
you said: 你绝对是百度的亲儿子。
robot said: 是亲儿子阿

Process finished with exit code 0

你可能感兴趣的:(人工智能,python)