语音聊天

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 前言环境本机环境所需包各大模块百度语音接口图灵机器人接口音频处理本地朗读模块GUI 模块演示文本语音总结前言这几天看了点PyQt相关的知识,感觉可以结合之前得一些内容做出点什么好玩的东西。

前言

这几天看了点PyQt相关的知识,感觉可以结合之前得一些内容做出点什么好玩的东西。

之前做过文本转语音的聊天机器人,昨天又恰好做了关于音频处理的。借此机会,整合一下,来做个有界面的语音文本聊天机器人好了。

先来看看最终的效果图。
文本语音聊天机器人效果图

对这些基础内容不是很了解的可以参考我之前的文章。

环境

环境搭建是个坑,之前一直在用的pyttsx语音引擎竟然不支持Python36,只能在Python27版本使用。所以无奈只能选用微软的提供的win32com.client了。

本机环境

本机环境如下

  • Windows10 64位
  • Python36
  • PyCharm pro

所需包

所需包一开始我是手动统计的,但是后来觉得版本这块最好还是精确一下,于是使用了pip的一个freeze命令。

pip freeze > requirements.txt

得到了下面的这些所需的库文件(我删除了一些没用到的)。

PyAudio==0.2.11
PyQt5==5.8.2
pyttsx==1.1
pywin32==221
requests==2.13.0
sip==4.19.2

各大模块

下面开始针对各大模块简要的介绍一下。

百度语音接口

百度语音接口是用来处理本地音频到文本内容转换而使用的。需要用到标准库中的wave库,来处理.wav音频文件。

# coding: utf8

# @Author: 郭 璞
# @File: baiduyuyin.py                                                                 
# @Time: 2017/5/11                                   
# @Contact: 1064319632@qq.com
# @blog: http://blog.csdn.net/marksinoberg
# @Description: 借助百度语音识别接口实现本地语音解析

import pyaudio
import wave
import requests
import json

class BaiDuYuYin(object):

    def __init__(self):
        # get the token
        self.token = self.gettoken()

    def gettoken(self):
        try:
            apiKey = "Ll0c嘿嘿2ZSGAU"
            secretKey = "44c8a这个不能说34936227d4a19dc2"

            auth_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey
            response = requests.get(url=auth_url)
            jsondata = response.text
            return json.loads(jsondata)['access_token']
        except Exception as e:
            raise Exception("Cannot get the token, the reason is {}".format(e))

    def parse(self, wavefile='local.wav'):
        """
        返回音频文件对应的文本内容。
        注意返回的是列表类型的数据,待会处理的时候要格外的小心。
        :param wavefile:
        :return:
        """
        try:
            fp = wave.open(wavefile, 'rb')
            # 已经录好音的音频片段内容
            nframes = fp.getnframes()
            filelength = nframes * 2
            audiodata = fp.readframes(nframes)

            # 百度语音接口的产品ID
            cuid = '7519663'
            server_url = 'http://vop.baidu.com/server_api' + '?cuid={}&token={}'.format(cuid, self.token)
            headers = {
                'Content-Type': 'audio/pcm; rete=8000',
                'Content-Length': '{}'.format(filelength),
            }

            response = requests.post(url=server_url, headers=headers, data=audiodata)
            print(response.text)
            data = json.loads(response.text)
            if data['err_msg'] == 'success.':
                return data['result']
            else:
                return '你说的啥啊,听不清听不清!'
        except Exception as e:
            raise Exception("Parsing wave file failed. The reason is {}".format(e))

if __name__ == '__main__':
    yuyinclient = BaiDuYuYin()
    result = yuyinclient.parse(wavefile='local.wav')
    print(result)

图灵机器人接口

然后是图灵机器人接口,这个用于处理文本对话。免费版其实已经够用了。有需要的自己去申请吧。

# coding: utf8

# @Author: 郭 璞
# @File: turing.py
# @Time: 2017/5/11                                   
# @Contact: 1064319632@qq.com
# @blog: http://blog.csdn.net/marksinoberg
# @Description: 文字对话接口实现
import requests
import json

class TuringRobot(object):

    def __init__(self):
        self.apikey = '2a220b3哟哟哟b74c54'
        self.userid = '产品ID不能说'
        self.url = 'http://www.tuling123.com/openapi/api'

    def talk(self, text):
        payload = {
            'key': self.apikey,
            'userid': self.userid,
            'info': text
        }

        response = requests.post(url=self.url, data=payload)
        return json.loads(response.text)['text']


if __name__ == '__main__':
    turing = TuringRobot()
    answer = turing.talk('你好吗,我是小黄鸡!')
    print(answer)

音频处理

昨天对于音频处理这块做了一点点的研究,今天还是那个套路。默认录音五秒,保存为同一级目录下的local.wav文件。

# coding: utf8

# @Author: 郭 璞
# @File: recorder.py                                                                 
# @Time: 2017/5/11                                   
# @Contact: 1064319632@qq.com
# @blog: http://blog.csdn.net/marksinoberg
# @Description: 记录本地录音,默认保存为local.wav, 留作解析引擎备用。
import pyaudio
import wave

class Recorder(object):

    def __init__(self):
        self.CHUNK = 1024
        self.FORMAT = pyaudio.paInt16
        self.CHANNELS = 2
        self.RATE = 44100
        self.RECORD_SECONDS = 5
        self.WAVE_OUTPUT_FILENAME = 'local.wav'

        self.engine = pyaudio.PyAudio()

    def record(self):
        try:
            # 提示语句可以使用一下语音方式,这里先打印算了。
            print("Begin Recoding ...")

            stream = self.engine.open(format=self.FORMAT,
                                      channels=self.CHANNELS,
                                      rate=self.RATE,
                                      input=True,
                                      frames_per_buffer=self.CHUNK)
            # 记录到的音频总数据帧
            frames = []
            for i in range(0, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
                data = stream.read(self.CHUNK)
                frames.append(data)

            # 音频记录完毕
            print('Recording Over!')
            # 释放资源,接触阻塞监听。
            stream.stop_stream()
            stream.close()
            self.engine.terminate()

            # 并将音频数据保存到本地音频文件中
            wf = wave.open(self.WAVE_OUTPUT_FILENAME, 'wb')
            wf.setnchannels(self.CHANNELS)
            wf.setsampwidth(self.engine.get_sample_size(self.FORMAT))
            wf.setframerate(self.RATE)
            wf.writeframes(b''.join(frames))
            wf.close()
        except Exception as e:
            raise Exception("Recording failed. The reason is {}".format(e))


if __name__ == '__main__':
    recorder = Recorder()
    recorder.record()

本地朗读模块

本地语音朗读相当于是一个加分项,之前一直在用的pyttsx这下尴尬了,无奈只能试用第二个方式,不过使用pyttsx的代码我还是留出来吧。万一哪天它支持了Python36,就有更多可选项的丰富功能了。

# coding: utf8

# @Author: 郭 璞
# @File: localvoicer.py                                                                 
# @Time: 2017/5/11                                   
# @Contact: 1064319632@qq.com
# @blog: http://blog.csdn.net/marksinoberg
# @Description: 本地语音朗读实现。
import win32com.client

class Reader(object):
    """
    尴尬的是pyttsx不支持Python36,要不然还可以有更多可选项。
    """

    def __init__(self):
        import pyttsx
        self.engine = pyttsx.init()
        # optional property
        self.rate = self.engine.getProperty('rate')
        self.voices = self.engine.getProperty('voices')
        self.volume = self.engine.getProperty('volume')

    def read(self, text="", rate=200, voices="", volume=""):
        self.engine.say(text)
        self.engine.runAndWait()


class Speaker(object):
    def __init__(self):
        self.engine = win32com.client.Dispatch("SAPI.SpVoice")

    def speak(self, text):
        self.engine.Speak(text)



if __name__ == '__main__':
    # reader = Reader()
    # reader.read(text='Hello World!')
    speaker = Speaker()
    speaker.speak("hello world! 你好世界")

GUI 模块

做完了前面的部分,就差界面了。测试完毕之后发现,各大模块均能正常工作,虽然音频解析那块特别地依赖于网速,校园网这网速我也是醉了。

下面简单的写个界面来“打包美化”一下吧。

# coding: utf8

# @Author: 郭 璞
# @File: audioui.py                                                                 
# @Time: 2017/5/11                                   
# @Contact: 1064319632@qq.com
# @blog: http://blog.csdn.net/marksinoberg
# @Description: 外部界面
from PyQt5 import QtCore, QtGui, QtWidgets
from audiorobot.dispatcher import Dispatcher
from audiorobot.baiduyuyin import BaiDuYuYin
from audiorobot.turing import TuringRobot
from audiorobot.localvoicer import Speaker

class ClientUI(QtWidgets.QWidget):

    def __init__(self):
        super(ClientUI, self).__init__()
        self.dispatcher = Dispatcher()
        self.baiduyuyin = BaiDuYuYin()
        self.turingrobot = TuringRobot()
        self.speaker = Speaker()
        self.initui()


    def initui(self):
        self.setWindowTitle("图灵·聊天室")
        self.setGeometry(20, 20, 400, 500)

        # 顶部布局
        toplayout = QtWidgets.QHBoxLayout()
        self.textarea = QtWidgets.QTextBrowser()
        toplayout.addWidget(self.textarea)
        # 中间布局
        centerlayut = QtWidgets.QHBoxLayout()
        self.editline = QtWidgets.QLineEdit()
        self.voicebutton = QtWidgets.QPushButton("发语音")
        self.textbutton = QtWidgets.QPushButton("发文字")
        centerlayut.addWidget(self.editline)
        centerlayut.addWidget(self.voicebutton)
        centerlayut.addWidget(self.textbutton)

        mainlayout = QtWidgets.QVBoxLayout()
        mainlayout.addLayout(toplayout)
        mainlayout.addLayout(centerlayut)

        self.setLayout(mainlayout)
        # 关于事件处理,交给handler来处理即可
        self.eventhandler()

    def eventhandler(self):
        self.voicebutton.clicked.connect(self.pushvoice)
        self.textbutton.clicked.connect(self.pushtext)

    def pushvoice(self):
        print('voice')
        # 先保存到本地,再调用语音接口上传
        self.dispatcher.record()
        response = self.baiduyuyin.parse()
        print('百度语音接口解析到的数据为:{}'.format(response))
        self.speaker.speak(text=response)
        # 更新一下窗体文本域的内容
        text = self.textarea.toPlainText()+"\n"+"<<< "+"上传音频中..."
        self.textarea.setText(text)
        text =  text +"\n>>> " +response
        self.textarea.setText(text)


    def pushtext(self):
        inputtext = self.editline.text()
        print(inputtext)
        trans = self.turingrobot.talk(text=inputtext)
        self.speaker.speak(text=trans)
        # 更新文本域内容
        text = self.textarea.toPlainText() + "\n<<<"+inputtext
        self.textarea.setText(text)
        text = self.textarea.toPlainText() + "\n>>> " + trans
        self.textarea.setText(text)
        self.editline.clear()


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ui = ClientUI()
    ui.show()
    sys.exit(app.exec_())

演示

好了,大功告成。运行代码的时候仅仅需要下面的这个命令就可以了。

Python audioui.py

文本

先来看看对于文本的处理,这其实跟之前的聊天机器人没啥区别。仅仅是带了语音朗读罢了。
文本测试

语音

然后是语音测试,我本人在图书馆。所以为了不打扰别人,录音的时候只能假装咳嗽来掩盖测试录音的事实,所以效果不是很好。但是如果是标准的普通话,测试的结果还是差强人意的。
音频处理


总结

最后还是来总结一下。

本次也算是整合的比较多的内容了。模块内测试都是用的

if __name__ == "__main__":
    # testing code
    pass

看起来还算不错,单元测试倒是没什么必要,毕竟代码量还很少。集成测试也算是马马虎虎,功能这块倒是还能满足需求,但是以后如果代码量大了的话,还是要好好测测的,以防万一。

已知的缺点就是界面这块。录音的时候要是能加一个statusBar实时提醒录音进度就好了,而且录音的时候是阻塞线程的,不是很优雅。

目录
相关文章
|
6月前
|
机器学习/深度学习 人工智能 视频直播
AI直播手机APP震撼发布!3大场景直播,60秒一键开播!
🎉 青否数字人AI直播APP发布!🚀 在抖音等平台60秒一键开播,简化直播流程。💡 3种AI直播模式,融合6大AIGC技术,助力新手轻松直播带货且避免违规。💪 AI主播、声音克隆,实时话术改写,智能互动与讲品同步,提升转化。📊 实景与视频直播结合,适应多种场景。🌐 独立部署,自定义版权,1年免费升级,专业售后支持。🚀 (直播: zhibo175) #青否数字人 #AI直播
AI直播手机APP震撼发布!3大场景直播,60秒一键开播!
语音社交源码知识语音房间功能的实现
就像我说的一样,语音社交源码技术语音房间功能对于开发语音社交平台也是至关重要的,当然,开发语音社交平台还有很多功能,在以后我会为大家一一讲解,如果大家还有什么不懂的可以问我。
语音社交源码知识语音房间功能的实现
|
编解码 视频直播
直播平台源码开发提高直播质量的关键:视频编码和解码技术
在开发直播平台源码过程中,哪个技术可以去保持、提高视频、直播的质量的,这个技术就是我们今天要讲的知识:直播平台源码开发提高质量的关键:视频编码和解码技术!
直播平台源码开发提高直播质量的关键:视频编码和解码技术
|
开发工具
语音聊天室源码技术美颜滤镜功能的配置
美颜滤镜功能从现身以来一直受到人们的火爆追捧,所以为了顺应市场的需求,开发语音聊天室源码平台也必须要有美颜滤镜功能,今天我就将语音聊天室源码技术美颜滤镜功能的配置知识分享给大家。
语音聊天室源码技术美颜滤镜功能的配置
|
编解码
相亲app开发,关注延时问题优化连麦互动体验
相亲app开发,关注延时问题优化连麦互动体验
|
算法 语音技术
相亲源码开发语音连麦功能,语音连麦质量优化实践
相亲源码开发语音连麦功能,语音连麦质量优化实践
|
编解码 缓存 搜索推荐
Instagram:如何提升音乐音频质量?
Ins tagram始终以高质量的体验为目标开发和优化应用程序,而优化Instagram体验的其中一种方式就是提高音频质量。
364 0
Instagram:如何提升音乐音频质量?
|
视频直播 5G UED
独特的直播形式——一对一语音聊天独特的直播形式——一对一语音聊天
4G技术的发展给移动直播带来了巨大的商机,全民直播的新时代,音视频结合的一对多直播形式在直播市场中占据着各大主流媒体。然而随着直播市场逐渐饱和,单一的一对多视频直播已经不能满足观众的需求,更能贴近人们需求的一对一直播逐渐发展起来。一对一语音聊天更是有着普通的一对多视频直播无法媲美的优越性。
独特的直播形式——一对一语音聊天独特的直播形式——一对一语音聊天
|
安全 视频直播
一对一直播开发,语音聊天的路还能走多久
一对一直播开发从问世到现在已经经历了多次洗礼,在直播、短视频热度趋于平稳后,一对一直播的关注量和入驻流量变得越来越多。
390 0
|
开发工具 UED
一对一直播系统源码,以语音聊天为核心的玩法
一对一直播系统源码,以语音聊天为核心的玩法
1272 0

热门文章

最新文章