利用Python打造一个语音合成系统
背景
一直对语音合成系统比较感兴趣,总想能给自己合成一点内容,比如说合成小说,把我下载的电子书播报给我听等等。
语音合成系统
其实就是一个基于语音合成的工具,但是这个东西由于很多厂家都提供了API的形式,因此开发难度大大降低,只需要调用几个API即可实现属于自己的语音合成工具。麻雀虽小,五脏俱全,一个小工具而已。往大了说,这就是一个小型的语音合成系统。
准备工作
首先我们电脑上需要安装
- Miniconda,可以到官网下载Miniconda;另外可以使用的是北师大的源,可以参考这篇文章,《ubuntu、conda、pip 换北外源(北京外国语大学开源软件镜像站)》
- Python 3.7以上,Miniconda自带,最新的已经到3.8版本(2021年2月)。
- visual studio code,代码编辑器,官网下载;当然也可以选用强大的Pycharm的社区版本,这个版本免费使用。
接入步骤
这里我们选用讯飞开放平台的WebAPI接口,以下是接口文档。
语音合成(流式版)WebAPI 文档
以上文档你不想看也没问题,因为这个文档后面提供了Python的demo,适合直接先一把梭哈,跑起来再说。不过还是建议回过头来多看几遍文档,毕竟怎么接入文档说了算。
很多朋友有疑问,那语音合成接口是不是免费的?那是当然的,白piao肯定是可以的!!!
对于个人而言:有两种礼包:礼包一是免费测试包,5万次(90天时间);还有新用户礼包,这个需要个人认证,5万次(1年时间)。对于我们练手来说,完全够用了!
以下是对应的领取地址:

对于企业而言,认证为企业之后,送的服务量那就更多了,50万次,1年的使用时间,够够的了!
关于企业方面的免费套餐,可以从这里进入企业免费套餐。

接下来,我们正式进入使用,首先我们到控制台创建一个应用:
创建好了之后,点击该应用进入,有该应用的详细栏目。(我这里创建了一个名为myaibot的应用)
点击左侧的语音合成,再到下一级在线语音合成(流式版)
在右上侧,能够看到我们需要拿到3个东西:
- APPID
- APISecret
- APIKey
有了这3个关键信息,我们就可以开始使用讯飞在线语音合成来打造我们的系统了。
代码实现
图形界面交互实现
首先,我们来梳理一下我们的语音合成工具的代码流程,总体来说就是四个步骤,因此代码实现起来还是非常容易的,流程图如下:

好了,接下来终于到了代码实现环节了。首先安装我们需要的两个库,一个库是websocket-client
是用来和讯飞的服务器建立连接,合成过程是基于websocket
协议来交互的;另外一个库是playsound
,合成好了音频,用来播放声音的,这样我们能立即体验合成的效果。
pip install websocket-client
pip install playsound
还有tkinter
,选择这个库是因为Python
自带不用再单独安装,同时我们的界面也不是很复杂,tkinter
少量代码就能实现我们的界面功能,不用我们花费太多心思在界面上,从而专注本身的语音合成功能。
接下来我们定义一个类TtsPlay
,包含4个函数
class TtsPlay:
def __init__(self): #初始化函数
def play_sound(self):#播放音频函数
def select_vcn(self,*arg):#选择下拉框设置发音人
def xfyun_tts(self):#进行语音合成
我们首先来实现初始化函数,初始化函数定义了类TtsPlay
的内部变量,同时启动了图形化界面窗口。
- 设置内部变量,大家需要填上刚才从讯飞开放平台控制台获取到的
appid
、apikey
以及apisecret
。 - 图形化编程,我们使用
tkinter
来绘图,从而显示界面
def __init__(self):
self.vcn = 'xiaoyan'
self.APP_ID = 'xxx' # 请填上自己的appid
self.API_KEY = 'xxx' # 请填上自己的appkey
self.SECRET_KEY = 'xxx' # 请填上自己的appsecret
self.fname = ""
self.root = tk.Tk() # 初始化窗口
self.root.title("语音合成系统") # 窗口名称
self.root.geometry("600x550") # 设置窗口大小
self.root.resizable(0, 0) # 为了方便固定窗口大小
self.tk_lb = tk.Label(self.root, text='请选择语音发音人') # 标签
self.tk_text = tk.Text(self.root, width=77, height=30) # 多行文本框
self.tk_cb_vcn = ttk.Combobox(self.root, width=12) # 下拉列表框
# 设置下拉列表框的内容
self.tk_cb_vcn['values'] = ("甜美女声-小燕", "亲切男声-许久", "知性女声-小萍", "可爱童声-许小宝", "亲切女声-小婧")
self.tk_cb_vcn.current(0) # 将当前选择状态置为0,也就是第一项
self.tk_cb_vcn.bind("<<ComboboxSelected>>", self