当语音助手遇到机器人

当语音助手遇到机器人

大家都知道现在智能手机都有语音助手,Mac 有 Siri,Windows 有小冰,那么这些语音助手遇到机器人会发生哪些有趣的对话呢?这里我们请来了图灵机器人(http://www.tuling123.com/)和 Siri 语音助手完成一次有趣的对话。

使用的到技术

图灵机器人使用的是文字输入而 Siri 使用的是语音输入,需要文字转语音和 Siri 截图识别文字。下图为程序的大致流程:

使用到的技术有:

  1. 图灵机器人(http://www.tuling123.com/)的 API 接口
  2. 百度 AI开放平台的语音合成接口、OCR文字识别接口
  3. ImageGrab 截图
  4. 文件传输

导入的模块有:

1
2
3
4
from PIL import ImageGrab
import requests
import base64
from urllib.parse import quote_plus

图灵机器人 API

图灵机器人登录后创建机器人并复制 apiKey。

我们使用 API V2.0接入,接口的地址是:http://openapi.tuling123.com/openapi/api/v2,用 POST 方式请求,这里使用文本方式向机器人发送消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def tuling():
    """
    图灵机器人
    :return:
    """

    host = 'http://openapi.tuling123.com/openapi/api/v2'
    data = {
        "reqType":0,              # 输入类型:0-文本(默认)、1-图片、2-音频
        "perception": {           # 输入信息
            "inputText": {        # 文本信息
                "text": "嗨,Siri!"
            }
        },
        "userInfo": {              # 用户信息
            "apiKey": "8d78a28535c947e69c2ddbcc5efeed51",
            "userId": "1234567"
        }
    }
    response = requests.post(host, json=data)
    if response:
        return response.json()['results'][0]['values']['text']
    else:
        return '错误了!'

示例结果

1
[{'groupType': 1, 'resultType': 'text', 'values': {'text': '我的手机没有siri'}}]

语音在线合成

在百度 AI 开放平台中有一个在线语音合成,这款 API 可以将文本转换成音频,我们这里将图灵机器人返回的结果转成 MP3 格式音频。创建好百度应用之后复制 api_key 和 secret_key 获取 token。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def fetch_token():
    """
    获取token
    :return: token
    """
    access_token = ""

    api_key = 'Pd4uoyvt1cwD7n2sHtLd5Ov0'
    secret_key = '8BnaPRcv3tTNa94eaFVfFy1pW2UkmvrO'

    token_url = 'http://openapi.baidu.com/oauth/2.0/token'
    params = {'grant_type': 'client_credentials',
              'client_id': api_key,
              'client_secret': secret_key}
    response = requests.post(token_url, post_data)
    if response:
        access_token = response.json()['access_token']
    return access_token

def synthesized_speech(text, token):
    """
    合成语音
    """

    # 保存的文件路径
    mp3_path = "/Users/xx/Desktop/siri/result.mp3"
    tts_url = 'http://tsn.baidu.com/text2audio'

    tex = quote_plus(text)  # 此处TEXT需要两次urlencode
    # tok:token,tex:文本,per:发音人,spd:语速(0-15)默认 5,pit:音调(0-15)默认 5,
    # vol:音量(0-9)默认 5,aue:下载的文件格式, 3 mp3(default)、4 pcm-16k、5 pcm-8k、6 wav,
    # cuid:用户唯一标识,lan ctp 固定参数
    params = {'tok': token, 'tex': tex, 'per': 4, 'spd': 5, 'pit': 5, 'vol': 5, 'aue': 3, 'cuid': "pythonjishu", 'lan': 'zh', 'ctp': 1}

    response = requests.post(tts_url, params)
    if response:
        with open(mp3_path, 'wb') as of:
            of.write(response.content)

文件传输

在 Mac 上 Siri 和音频同时操作是行不通的,此时播放音频文件没有声音,我们必须把音频文件传输到第二台电脑上。这时在命令行输入 python3 -m http.server 把当前电脑做一个简易的服务器。

1
python3 -m http.server

在第二台电脑浏览器上输入 http://IP地址:8000/,并找到音频文件播放。

1
2
http://IP地址:8000/
http://192.168.1.102:8000/Desktop/siri/result.mp3

截图

当 Siri 听到声音后会在最后一行返回结果,我们需要将 Siri 界面截图和识别文字。

1
2
3
4
5
6
7
8
9
10
11
12
def grab_img():
    """
    截图
    :return:
    """
    
    img_path = "/Users/xx/Desktop/siri/grab.png"
    # bbbox 的参数为截取屏幕的一部分,距离左边像素,上边像素,右边像素,下边像素
    
    img = ImageGrab.grab(bbox=(2630,80,3330,1290))
    img.save(img_path)
    return img_path

文字识别

将 Siri 截图后需要识别最后一行文字,这里使用百度 AI 开放平台的 OCR(还是和上面语音合成一样创建应用后复制 api_key 和 secret_key)将这段结果传输给图灵机器人,一段对话就完成了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def fench_ocr_token():
    """
    获取ocr token
    :return: token
    """

    api_key = 'ioE84jDQmGNLG7heN6rovF9Q'
    secret_key = 'qGVyAobVtCGKdD1Ncz60IvGMdf3dP1ct'

    access_token = ""
    url = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+api_key+'&client_secret='+secret_key
    response = requests.get(url)
    if response:
        access_token = response.json()['access_token']
    return access_token


def ocr(img_path, access_token):
    """
    通用文字识别
    :return: 识别后的文字
    """
    text = ""
    request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
    # 二进制方式打开图片文件
    f = open(img_path, 'rb')
    img = base64.b64encode(f.read())
    
    params = {"image":img}
    request_url = request_url + "?access_token=" + access_token
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    response = requests.post(request_url, data=params, headers=headers)
    if response:
        words_result = response.json()['words_result']
        text = words_result[-1]['words']
    return text

示例结果

1
2
3
最后一行取最后一个words

[{'words': '股市'}, {'words': 'Apple公司的股票价格”'}, {'words': '时钟'}, {'words': '“柏林现在几点钟?”'}, {'words': '通讯录'}, {'words': '“秦葳住在哪里?”'}, {'words': '查找'}, {'words': '“我的 iPhone在哪里?'}, {'words': '备忘录'}, {'words': '“记下我午餐花了12块钱”'}, {'words': '网络搜索'}, {'words': '“上网查找北极熊”'}, {'words': '问与答'}, {'words': '公斤等于多少磅?”'}, {'words': '播客'}, {'words': '播放播客”'}, {'words': '密码'}, {'words': '“显示我的密码”'}, {'words': '嗨S'}, {'words': '嗨,Si很高兴见到你。'}]

总结

这个 Python 程序并不复杂只需要使用多个 API 接口。希望小伙伴们都可以放开思维写各种 Python 小程序练手。

示例代码:当语音助手遇到机器人

Python Geek Tech wechat
欢迎订阅 Python 技术,这里分享关于 Python 的一切。