简易语音助手—python

需求拆分

语音助手首先要能得到人的说话的音频,然后根据内容进行回复,再将回复播放出来。这个过程也就是语音转文字,获得回复文字,再将回复转语音。看起来是一个复杂的过程,但是好在这三个过程都有对应的API接口可以用到。

API调用

一、语音转文字——百度AI开放平台

官方文档http://ai.baidu.com/docs#/ASR-API/top
调用这个接口,我们只需要上传音频文件,就会返回对应的文字。百度服务端会将非pcm格式,转为pcm格式,因此使用wav、amr、m4a会有额外的转换耗时。建议在本地转换,pcm是无压缩的二进制音频文件,因此我们利用FFmpegwav转换为pcm

用FFmpeg转换音频格式

下载链接https://github.com/BtbN/FFmpeg-Builds/releases
下载完成后将ffmpeg.exe复制到main.py目录中,或在代码里写出完整路径即可调用。
演示代码

#用ffmpeg将wav转换为pcm格式,并调用接口获得文字。
# -*- coding:utf-8 -*-
from ffmpy3 import FFmpeg
import os
from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = 'xxxxxxxx'
API_KEY = 'xxxxxxxxx'
SECRET_KEY = 'xxxxxxxxx'
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def get_file_content(filePath):
    with open(filePath, 'rb') as fp:  #读取文件
        return fp.read()
#语音转文字接口调用
def speechTOstr():
    path = '1.pcm'  # 文件路径
    if os.path.exists(path):  # 如果存在1.pcm则删除,此为上一次生成的
        os.remove(path)
    else:
        print('no such file:%s')  # 则返回文件不存在
    ff = FFmpeg(executable='C:\\Users\\86158\\Downloads\\ffmpeg-N-100493-gc720286ee3-win64-lgpl-vulkan\\bin\\ffmpeg.exe',inputs={r'1.wav':"-y"},
              outputs={r'1.pcm':"-f s16le -ar 16000 -ac 1 -acodec pcm_s16le"}) #音频格式转换ffmpeg.exe用的绝对路径
    print(ff.cmd) #输出本地运行的ffmpeg完整命令
    ff.run()

    json=client.asr(get_file_content('1.pcm'), 'pcm', 16000, {
        'dev_pid': 1537,
    }) #调用接口返回json格式
    print(json) #输出完整json返回
    speechStr=json['result'][0] #提取出文字结果
    print(speechStr)
    return speechStr

speechTOstr()

运行结果
运行结果

二、聊天接口——图灵机器人

这里我用到的是天行数据做中介,一元一万天豆,调用一次接口20天豆。
调用也很简单,只有两个参数,申请之后可以得到的key,和你想说的question
官方链接https://www.tianapi.com/
接口调用
演示代码

# -*- coding:utf-8 -*-
from urllib.request import urlopen,Request
from urllib.error import URLError
import json
from urllib.parse import urlencode
#图灵机器人接口参数
class TuringChatMode(object):
    def __init__(self):
        # API接口地址
        self.turing_url = 'http://api.tianapi.com/txapi/tuling/index?'
    def get_turing_text(self,text):
        turing_url_data = dict(
            key='xxxxxxxxxxx',
            question=text,
        )
        self.request = Request(self.turing_url + urlencode(turing_url_data))
        try:
            w_data = urlopen(self.request)
        except URLError:
            raise IndexError("No internet connection available to transfer txt data")
            # 如果发生网络错误,断言提示没有可用的网络连接来传输文本信息
        except:
            raise KeyError("Server wouldn't respond (invalid key or quota has been maxed out)")
            # 其他情况断言提示服务相应次数已经达到上限

        response_text = w_data.read().decode('utf-8')
        json_result = json.loads(response_text)
        return json_result['newslist']

turing = TuringChatMode()
reply=turing.get_turing_text("你好")
print(reply) #输出完整json
print(reply[0]['reply']) #提取出回复文字

运行结果
运行结果

三、文字转语音——讯飞开放平台

官方文档https://www.xfyun.cn/doc/tts/online_tts/API.html
讯飞文字转语音的音源比较多,但是接口调用稍微有点复杂。
官方文档
好在官方有示例代码,这个代码会报一个错误但是能正常使用,个人不是很懂websocket,所以就没管了。
代码下载链接https://xfyun-doc.cn-bj.ufileos.com/1602142890241307/tts_ws_python3_demo.zip
最终得到的还是一个pcm文件,所以还得用FFmpeg转换成wav格式播放,至此接口以及都准备好了,剩下的问题就是如何录音和播放了,需要用到pyaudio

pyaudio录音及播放

# -*- coding:utf-8 -*-
from ffmpy3 import FFmpeg
import pyaudio
import wave
import os
#录制用户音频
def get_audio():
        filepath = "1.wav"
        CHUNK = 256
        FORMAT = pyaudio.paInt16
        CHANNELS = 1                # 声道数
        RATE = 16000               # 采样率
        RECORD_SECONDS =3
        WAVE_OUTPUT_FILENAME = filepath
        p = pyaudio.PyAudio()
        stream = p.open(format=FORMAT,
                        channels=CHANNELS,
                        rate=RATE,
                        input=True,
                        frames_per_buffer=CHUNK)
        print("*"*10, "开始录音:请在3秒内输入语音")
        frames = []
        for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
            data = stream.read(CHUNK)
            frames.append(data)
        print("*"*10, "录音结束\n")
        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()
#播放讯飞文字转语音音频  pcm格式
def play():
    path = 'reply.wav'  # 文件路径
    if os.path.exists(path):  # 如果文件存在
        # 删除文件,可使用以下两种方法。
        os.remove(path)
        # os.unlink(path)
    else:
        print('no such file:%s')  # 则返回文件不存在
    ff = FFmpeg(
        executable='C:\\Users\\86158\\Downloads\\ffmpeg-N-100493-gc720286ee3-win64-lgpl-vulkan\\bin\\ffmpeg.exe',
        inputs={r'1.pcm': "-f s16le -ar 16000 -ac 1"},
        outputs={r'reply.wav': ""})
        #pcm转wav
    print(ff.cmd)
    ff.run()
    wf = wave.open("reply.wav", 'rb')
    p = pyaudio.PyAudio()
    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True)
    data = wf.readframes(1024)
    while data != b'':
        stream.write(data)
        data = wf.readframes(1024)
    stream.stop_stream()
    stream.close()
    p.terminate()

get_audio()
play()

模块整合

录音模块语音转文字图灵机器人文字转语音播放音频模块整合起来,就得到了一个简单的语音助手。不过和语音助手比还有很明显的缺陷,第一点是没有唤醒词,第二点是录音的时长固定
对于唤醒词初步想法是识别语音转文字的结果是否含有关键词,而时长固定的问题准备用FFmpeg合成录音来解决,如果新音频的分贝过小时则停下录音,如果有声音则继续合成。
还有一点,所有的接口并非免费,但是除了第二个,其他的白嫖做测试是没有问题的。

完整项目代码

git链接https://github.com/cqhong/SpeechRecognition

  • 6
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值