用 Python 实现自己的智能语音助理(百度语音 + 图灵机器人)

依稀记得去年生日,对着 Google 说 "Sing me Happy Birthday" 。
她真的给我唱了英文版的生日歌,满怀深情地(我感觉……)。最后还加了一串调皮的鼓声。
我转头对着公司的前台小姐姐说,看见没有,你的 Siri 不爱我。。。

呃,不瞎扯了。
基于以上的渊源,我用 Python 写了一个还算得上智能的语音助理。

截图如下:
用 Python 实现自己的智能语音助理(百度语音 + 图灵机器人)_第1张图片
AI1

演示视频:用 Python 实现的智能语音机器人(一)

源代码

不要慌,用的现成的框架和公共 API,一百来行代码而已,权当游戏。

一、整体结构

没有做过多的设计(不懂。。。),整体就是一个简单的线性结构,顺序执行。
一次交互完毕后,从头开始重复执行。

SpeechRecognition(录音)--> 百度语音(Speech-to-Text)--> 图灵机器人(语义分析及应答)--> 百度语音(Text-to-Speech)--> PyAudio(音频播放)

二、SpeechRecognition

SpeechRecogintion 是 Python 的一个语音识别框架,已经对接了如谷歌和微软的 STT (语音转文本)服务。

本项目里的语音识别及合成用的是百度的开放服务,所以只是需要 SpeechRecogintion 的录音功能。
它可以检测语音中的停顿自动终止录音并保存,比 PyAudio 更人性化(代码写起来也更简单)。

安装依赖库
Windows

安装 SpeechRecognition 需要提前装好 Python 的 PyAudio 框架。PyAudio 貌似需要编译安装,Windows 系统上估计会有点麻烦。

我用的是 Anaconda 软件,Windows 系统上用它管理 Python 包很方便。
嫌这个软件太大的话,也有简化版的 Miniconda 。
装好以后直接执行下面的命令即可(当然也可以在 conda 的虚拟环境里安装,不赘述):
conda install pyaudio

PyAudio 装好以后,直接使用 Python 的包管理工具 pip 安装 SpeechRecognition 即可:
pip install SpeechRecognition

Linux

Linux 系统下就显得省事一点了。可以直接使用系统自带的包管理器安装 PyAudio (如 Ubuntu 和 Raspbian 系统的 apt-get
$ sudo apt-get install python3-pyaudio

当然也可以使用 pip 命令安装,不过需要提前装好编译用的依赖库 portaudio19

$ sudo apt-get install portaudio19-dev
$ pip install pyaudio

同样的,PyAudio 装好以后,安装 SpeechRecognition :
pip install SpeechRecognition

录音代码
import speech_recognition as sr

def rec(rate=16000):
    r = sr.Recognizer()
    with sr.Microphone(sample_rate=rate) as source:
        print("please say something")
        audio = r.listen(source)

    with open("recording.wav", "wb") as f:
        f.write(audio.get_wav_data())

rec()

从系统麦克风拾取音频数据,采样率为 16000(貌似百度语音 API 最高就支持到 16k 的采样率)。
之后把采集到的音频数据以 wav 格式保存在当前目录下的 recording.wav 文件中,供后面的程序使用。

录音完成后,可以找到录好的音频文件试听一下效果。

三、百度语音(STT)

创建应用

百度语音是百度云 AI 开放平台提供的支持语音识别和语音合成的服务,注册以后就可以直接访问它的 REST API 了,并且有向普通用户提供免费的调用额度。

注册成功以后,进入语音服务的控制台创建一个新的应用,记下自己的 AppIDAPI KeySecret Key

用 Python 实现自己的智能语音助理(百度语音 + 图灵机器人)_第2张图片
key

语音识别代码

百度 AI 有提供面向 Python 的框架 baidu-aip ,感觉就相当于重新打包以后的 requests 库,用来访问 REST API。这里简单起见,直接使用该框架。
安装:
pip install baidu-aip

语音识别代码如下(代码中的 Key 替换成自己的):

from aip import AipSpeech

APP_ID = 'Your AppID'
API_KEY = 'Your API Key'
SECRET_KEY = 'Your Secret Key'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def listen():
    with open('recording.wav', 'rb') as f:
        audio_data = f.read()

    result = client.asr(audio_data, 'wav', 16000, {
        'dev_pid': 1536,
    })

    result_text = result["result"][0]

    print("you said: " + result_text)

    return result_text

listen()

简单来说,将 SpeechRecognition 录制的音频上传至百度语音的服务,返回识别后的文本结果并输出。

四、图灵机器人

图灵机器人是一个提供(一定额度内)免费的智能聊天服务的平台,注册以后就可以创建自己的聊天机器人并接入到项目中。

首先进入图灵机器人的控制台并创建一个新的聊天机器人,记下分配到的 apikey

用 Python 实现自己的智能语音助理(百度语音 + 图灵机器人)_第3张图片
apikey

该平台也提供了开放的 REST API ,但是不像百度那样有打包自己的 SDK 。所以需要使用 Python 的 requests 库访问,代码如下:

import requests
import json

TURING_KEY = "Your apikey"
URL = "http://openapi.tuling123.com/openapi/api/v2"
HEADERS = {'Content-Type': 'application/json;charset=UTF-8'}

def robot(text=""):
    data = {
        "reqType": 0,
        "perception": {
            "inputText": {
                "text": ""
            },
            "selfInfo": {
                "location": {
                    "city": "杭州",
                    "street": "网商路"
                }
            }
        },
        "userInfo": {
            "apiKey": TURING_KEY,
            "userId": "starky"
        }
    }

    data["perception"]["inputText"]["text"] = text
    response = requests.request("post", URL, json=data, headers=HEADERS)
    response_dict = json.loads(response.text)

    result = response_dict["results"][0]["values"]["text"]
    print("the AI said: " + result)
    return result

robot("你好")

简单来说就是上传一个 json 格式的请求(包含聊天内容和个人信息等),获取到回复。再从收到的对象中提取出回复的文本。

五、百度语音(TTS)

其实大部分系统都有内置的 TTS (即文本转语音)引擎,如 MacOS 的 say 命令,只不过其中有很多都显得太“机械”,呃,缺少“人情味儿”。。。

百度的 TTS 引擎语音效果听起来还是很卡哇伊(4 号选手度丫丫)的,比较超出我的预期。

测试代码如下:

from aip import AipSpeech

APP_ID = 'Your AppID'
API_KEY = 'Your API Key'
SECRET_KEY = 'Your Secret Key'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def speak(text=""):
    result = client.synthesis(text, 'zh', 1, {
        'spd': 4,
        'vol': 5,
        'per': 4,
    })

    if not isinstance(result, dict):
        with open('audio.mp3', 'wb') as f:
            f.write(result)
speak("你好啊")

就是把需要转换成语音的文本内容上传,再将返回的数据保存在本地。貌似只能生成 mp3 格式。

六、PyAudio 播放

这个我有点方。。。没找到 Python 播放 MP3 的合适的方法,所以用 os.system 调用系统中的 sox 命令将 MP3 转为 wav 格式,再用 PyAudio 播放。

sox 安装

SoX 是一个强大的跨平台的音频处理工具,Linux 系统可以直接使用包管理器安装:
$ sudo apt-get install sox libsox-fmt-mp3

Windows 系统安装的默认的 SoX 是不包含 mp3 格式支持的,所以需要自己编译(手动狗头)或者下载已经编译好的 dll 文件(libmad.dll 和 libmp3lame.dll,放置在 SoX 的安装目录下。
最后将安装目录添加至系统的 PATH 环境变量即可。

代码如下:

import pyaudio
import wave
import os
import time

def play():
    os.system('sox audio.mp3 audio.wav')
    wf = wave.open('audio.wav', 'rb')
    p = pyaudio.PyAudio()

    def callback(in_data, frame_count, time_info, status):
        data = wf.readframes(frame_count)
        return (data, pyaudio.paContinue)

    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True,
                    stream_callback=callback)

    stream.start_stream()

    while stream.is_active():
        time.sleep(0.1)

    stream.stop_stream()
    stream.close()
    wf.close()

    p.terminate()

play()

七、最终代码及视频演示

整合后的最终代码我就不再贴一遍了,100 行左右,已上传至 Github 。
第二个视频:用 Python 实现的智能语音机器人(二)

聊天截图:
用 Python 实现自己的智能语音助理(百度语音 + 图灵机器人)_第4张图片
ai2

对了,这个是支持树莓派的。不过需要额外装一个USB音频驱动作为录音设备。参考树莓派3 音频配置及其应用场景(录音、VoIP 电话等)

参考资料

SpeechRecognition
百度语音
图灵机器人
PyAudio
SoX

你可能感兴趣的:(用 Python 实现自己的智能语音助理(百度语音 + 图灵机器人))