0

0

Python语音合成小工具的实现方法

WBOY

WBOY

发布时间:2023-05-08 15:46:07

|

2129人浏览过

|

来源于亿速云

转载

    TTS简介

    tts(text to speech)是一种语音合成技术,可以让机器将输入文本以语音的方式播放出来,实现机器说话的效果。

    TTS分成语音处理及语音合成,先由机器识别输入的文字,再根据语音库进行语音合成。现在有很多可供调用的TTS接口,比如百度智能云的语音合成接口。微软在Windows系统中也提供了TTS的接口,可以调用此接口实现离线的TTS语音合成功能。

    本文将使用pyttsx3库作为示范,编写一个语音合成小工具。

    安装需要的包

    安装PyQt5及其GUI设计工具

    # 安装PyQt5
    pip install PyQt5
     
    # 安装PyQt5设计器
    pip install PyQt5Designer

    本文使用的编辑器是VSCode,不是PyCharm,使用PyQt5的方式可能存在差异,具体使用时可以根据实际情况进行配置。 

    立即学习Python免费学习笔记(深入)”;

    安装pyttsx3

    pip install pyttsx3

    UI界面 

    可参考下图设计简单的GUI界面,由于本文主要为功能实例,故不考虑界面美观问题。

    Python如何实现语音合成小工具

    界面应有一个文本输入框,用以输入将要转化为语音的文本,同时需要一个播放按钮,用以触发语音播放的方法。语速、音量和语言可以按需选择。 

    极限网络办公Office Automation
    极限网络办公Office Automation

    专为中小型企业定制的网络办公软件,富有竞争力的十大特性: 1、独创 web服务器、数据库和应用程序全部自动傻瓜安装,建立企业信息中枢 只需3分钟。 2、客户机无需安装专用软件,使用浏览器即可实现全球办公。 3、集成Internet邮件管理组件,提供web方式的远程邮件服务。 4、集成语音会议组件,节省长途话费开支。 5、集成手机短信组件,重要信息可直接发送到员工手机。 6、集成网络硬

    下载

    使用PyQt5的设计工具,可以根据以上配置的GUI界面生成以下UI(XML)代码:

    
    
     Form
     
      
       
        0
        0
        313
        284
       
      
      
       语音合成器
      
      
       
        voice.icovoice.ico
      
      
       
        
         10
         10
         291
         261
        
       
       
        
         20
        
        
         
          
           
            
             播报文本
            
            
             Qt::AlignJustify|Qt::AlignTop
            
           
          
          
           
          
         
        
        
         
          
           
            
             语速
            
           
          
          
           
            
             300
            
            
             Qt::Horizontal
            
           
          
          
           
            
             
              30
              0
             
            
            
             0
            
            
             Qt::AlignCenter
            
           
          
         
        
        
         
          
           
            
             音量
            
           
          
          
           
            
             100
            
            
             Qt::Horizontal
            
           
          
          
           
            
             
              30
              0
             
            
            
             0
            
            
             Qt::AlignCenter
            
           
          
         
        
        
         
          
           
            
             选择语言
            
           
          
          
           
            
             中文
            
            
             true
            
           
          
          
           
            
             英文
            
           
          
         
        
        
         
          
           
            
             
              60
              0
             
            
            
             
            
           
          
          
           
            
             
              0
              30
             
            
            
             播放
            
           
          
         
        
       
      
     
     
     
    

    最后再使用PyQt5的界面工具,可以根据以上UI的代码,生成以下的窗体类:

    # -*- coding: utf-8 -*-
     
    # Form implementation generated from reading ui file 'd:\Program\VSCode\Python\TTS_PyQT\tts_form.ui'
    #
    # Created by: PyQt5 UI code generator 5.15.7
    #
    # WARNING: Any manual changes made to this file will be lost when pyuic5 is
    # run again.  Do not edit this file unless you know what you are doing.
     
    from PyQt5 import QtCore, QtGui, QtWidgets
     
     
    class Ui_Form(object):
     
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(313, 284)
            icon = QtGui.QIcon()
            icon.addPixmap(
                QtGui.QPixmap("./voice.ico"),
                QtGui.QIcon.Normal, QtGui.QIcon.Off)
            Form.setWindowIcon(icon)
            self.verticalLayoutWidget = QtWidgets.QWidget(Form)
            self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 291, 261))
            self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
            self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
            self.verticalLayout.setContentsMargins(0, 0, 0, 0)
            self.verticalLayout.setSpacing(20)
            self.verticalLayout.setObjectName("verticalLayout")
            self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
            self.horizontalLayout_2.setObjectName("horizontalLayout_2")
            self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
            self.label.setAlignment(QtCore.Qt.AlignJustify | QtCore.Qt.AlignTop)
            self.label.setObjectName("label")
            self.horizontalLayout_2.addWidget(self.label)
            self.tbx_text = QtWidgets.QTextEdit(self.verticalLayoutWidget)
            self.tbx_text.setObjectName("tbx_text")
            self.horizontalLayout_2.addWidget(self.tbx_text)
            self.verticalLayout.addLayout(self.horizontalLayout_2)
            self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
            self.horizontalLayout_4.setObjectName("horizontalLayout_4")
            self.label_3 = QtWidgets.QLabel(self.verticalLayoutWidget)
            self.label_3.setObjectName("label_3")
            self.horizontalLayout_4.addWidget(self.label_3)
            self.slider_rate = QtWidgets.QSlider(self.verticalLayoutWidget)
            self.slider_rate.setMaximum(300)
            self.slider_rate.setOrientation(QtCore.Qt.Horizontal)
            self.slider_rate.setObjectName("slider_rate")
            self.horizontalLayout_4.addWidget(self.slider_rate)
            self.label_rate = QtWidgets.QLabel(self.verticalLayoutWidget)
            self.label_rate.setMinimumSize(QtCore.QSize(30, 0))
            self.label_rate.setAlignment(QtCore.Qt.AlignCenter)
            self.label_rate.setObjectName("label_rate")
            self.horizontalLayout_4.addWidget(self.label_rate)
            self.verticalLayout.addLayout(self.horizontalLayout_4)
            self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
            self.horizontalLayout_3.setObjectName("horizontalLayout_3")
            self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget)
            self.label_2.setObjectName("label_2")
            self.horizontalLayout_3.addWidget(self.label_2)
            self.slider_volumn = QtWidgets.QSlider(self.verticalLayoutWidget)
            self.slider_volumn.setMaximum(100)
            self.slider_volumn.setOrientation(QtCore.Qt.Horizontal)
            self.slider_volumn.setObjectName("slider_volumn")
            self.horizontalLayout_3.addWidget(self.slider_volumn)
            self.label_volumn = QtWidgets.QLabel(self.verticalLayoutWidget)
            self.label_volumn.setMinimumSize(QtCore.QSize(30, 0))
            self.label_volumn.setAlignment(QtCore.Qt.AlignCenter)
            self.label_volumn.setObjectName("label_volumn")
            self.horizontalLayout_3.addWidget(self.label_volumn)
            self.verticalLayout.addLayout(self.horizontalLayout_3)
            self.horizontalLayout = QtWidgets.QHBoxLayout()
            self.horizontalLayout.setObjectName("horizontalLayout")
            self.label_4 = QtWidgets.QLabel(self.verticalLayoutWidget)
            self.label_4.setObjectName("label_4")
            self.horizontalLayout.addWidget(self.label_4)
            self.rbtn_zh = QtWidgets.QRadioButton(self.verticalLayoutWidget)
            self.rbtn_zh.setChecked(True)
            self.rbtn_zh.setObjectName("rbtn_zh")
            self.horizontalLayout.addWidget(self.rbtn_zh)
            self.rbtn_en = QtWidgets.QRadioButton(self.verticalLayoutWidget)
            self.rbtn_en.setObjectName("rbtn_en")
            self.horizontalLayout.addWidget(self.rbtn_en)
            self.verticalLayout.addLayout(self.horizontalLayout)
            self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
            self.horizontalLayout_5.setObjectName("horizontalLayout_5")
            self.label_5 = QtWidgets.QLabel(self.verticalLayoutWidget)
            self.label_5.setMinimumSize(QtCore.QSize(60, 0))
            self.label_5.setText("")
            self.label_5.setObjectName("label_5")
            self.horizontalLayout_5.addWidget(self.label_5)
            self.btn_play = QtWidgets.QPushButton(self.verticalLayoutWidget)
            self.btn_play.setMinimumSize(QtCore.QSize(0, 30))
            self.btn_play.setObjectName("btn_play")
            self.horizontalLayout_5.addWidget(self.btn_play)
            self.verticalLayout.addLayout(self.horizontalLayout_5)
     
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
     
        def retranslateUi(self, Form):
            _translate = QtCore.QCoreApplication.translate
            Form.setWindowTitle(_translate("Form", "语音合成器"))
            self.label.setText(_translate("Form", "播报文本"))
            self.label_3.setText(_translate("Form", "语速"))
            self.label_rate.setText(_translate("Form", "0"))
            self.label_2.setText(_translate("Form", "音量"))
            self.label_volumn.setText(_translate("Form", "0"))
            self.label_4.setText(_translate("Form", "选择语言"))
            self.rbtn_zh.setText(_translate("Form", "中文"))
            self.rbtn_en.setText(_translate("Form", "英文"))
            self.btn_play.setText(_translate("Form", "播放"))

    如果直接复制此代码,可能会出现图标丢失的问题。这个需要根据实际情况修改icon的配置,并添加要使用的ico图标文件。 

    功能代码

    语音工具类

    首先我们需要初始化并获取语音合成用的语音引擎对象。

    # tts对象
    engine = pyttsx3.init()

    我们可以通过该对象的setProperty方法,对语音合成的对象的属性进行修改:

    属性名 解释
    rate 以每分钟字数表示的整数语速
    volume 音量,取值范围为[0.0, 1.0]
    voices 语音的字符串标识符

    语音工具类代码如下,代码含义可参考注释:

    import pyttsx3
     
     
    class VoiceEngine():
        '''
        tts 语音工具类
        '''
     
        def __init__(self):
            '''
            初始化
            '''
            # tts对象
            self.__engine = pyttsx3.init()
            # 语速
            self.__rate = 150
            # 音量
            self.__volume = 100
            # 语音ID,0为中文,1为英文
            self.__voice = 0
     
        @property
        def Rate(self):
            '''
            语速属性
            '''
            return self.__rate
     
        @Rate.setter
        def Rate(self, value):
            self.__rate = value
     
        @property
        def Volume(self):
            '''
            音量属性
            '''
            return self.__volume
     
        @Volume.setter
        def Volume(self, value):
            self.__volume = value
     
        @property
        def VoiceID(self):
            '''
            语音ID:0 -- 中文;1 -- 英文
            '''
     
            return self.__voice
     
        @VoiceID.setter
        def VoiceID(self, value):
            self.__voice = value
     
        def Say(self, text):
            '''
            播放语音
            '''
            self.__engine.setProperty('rate', self.__rate)
            self.__engine.setProperty('volume', self.__volume)
     
            # 获取可用语音列表,并设置语音
            voices = self.__engine.getProperty('voices')
            self.__engine.setProperty('voice', voices[self.__voice].id)
     
            # 保存语音文件
            # self.__engine.save_to_file(text, 'test.mp3')
     
            self.__engine.say(text)
            self.__engine.runAndWait()
            self.__engine.stop()

    窗体类

    我们可以创建一个继承于我们刚刚创建的PyQt5的窗体类,并为窗体的拖拽事件和点击事件注册回调函数,同时创建一个语音工具类的实例,用以实现指定事件触发时需要执行的语音操作。

    import sys
    import _thread as th
    from PyQt5.QtWidgets import QMainWindow, QApplication
    from Ui_tts_form import Ui_Form
     
    class MainWindow(QMainWindow, Ui_Form):
        '''
        窗体类
        '''
     
        def __init__(self, parent=None):
            '''
            初始化窗体
            '''
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
     
            # 获取tts工具类实例
            self.engine = VoiceEngine()
            self.__isPlaying = False
     
            # 设置初始文本
            self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')
     
            # 进度条数据绑定到label中显示
            self.slider_rate.valueChanged.connect(self.setRateTextValue)
            self.slider_volumn.valueChanged.connect(self.setVolumnTextValue)
     
            # 设置进度条初始值
            self.slider_rate.setValue(self.engine.Rate)
            self.slider_volumn.setValue(self.engine.Volume)
     
            # RadioButton选择事件
            self.rbtn_zh.toggled.connect(self.onSelectVoice_zh)
            self.rbtn_en.toggled.connect(self.onSelectVoice_en)
     
            # 播放按钮点击事件
            self.btn_play.clicked.connect(self.onPlayButtonClick)
     
        def setRateTextValue(self):
            '''
            修改语速label文本值
            '''
            value = self.slider_rate.value()
            self.label_rate.setText(str(value))
            self.engine.Rate = value
     
        def setVolumnTextValue(self):
            '''
            修改音量label文本值
            '''
            value = self.slider_volumn.value()
            self.label_volumn.setText(str(value / 100))
            self.engine.Volume = value
     
        def onSelectVoice_zh(self):
            '''
            修改中文的语音配置及默认播放文本
            '''
            self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')
            self.engine.VoiceID = 0
     
        def onSelectVoice_en(self):
            '''
            修改英文的语音配置及默认的播放文本
            '''
            self.tbx_text.setText('Hello World')
            self.engine.VoiceID = 1
     
        def playVoice(self):
            '''
            播放
            '''
     
            if self.__isPlaying is not True:
                self.__isPlaying = True
                text = self.tbx_text.toPlainText()
                self.engine.Say(text)
                self.__isPlaying = False
     
        def onPlayButtonClick(self):
            '''
            播放按钮点击事件
            开启线程新线程播放语音,避免窗体因为语音播放而假卡死
            '''
            th.start_new_thread(self.playVoice, ())

    完整代码

    import sys
    import _thread as th
    from PyQt5.QtWidgets import QMainWindow, QApplication
    from Ui_tts_form import Ui_Form
    import pyttsx3
     
     
    class VoiceEngine():
        '''
        tts 语音工具类
        '''
     
        def __init__(self):
            '''
            初始化
            '''
            # tts对象
            self.__engine = pyttsx3.init()
            # 语速
            self.__rate = 150
            # 音量
            self.__volume = 100
            # 语音ID,0为中文,1为英文
            self.__voice = 0
     
        @property
        def Rate(self):
            '''
            语速属性
            '''
            return self.__rate
     
        @Rate.setter
        def Rate(self, value):
            self.__rate = value
     
        @property
        def Volume(self):
            '''
            音量属性
            '''
            return self.__volume
     
        @Volume.setter
        def Volume(self, value):
            self.__volume = value
     
        @property
        def VoiceID(self):
            '''
            语音ID:0 -- 中文;1 -- 英文
            '''
     
            return self.__voice
     
        @VoiceID.setter
        def VoiceID(self, value):
            self.__voice = value
     
        def Say(self, text):
            '''
            播放语音
            '''
            self.__engine.setProperty('rate', self.__rate)
            self.__engine.setProperty('volume', self.__volume)
            voices = self.__engine.getProperty('voices')
            self.__engine.setProperty('voice', voices[self.__voice])
     
            # 保存语音文件
            # self.__engine.save_to_file(text, 'test.mp3')
     
            self.__engine.say(text)
            self.__engine.runAndWait()
            self.__engine.stop()
     
     
    class MainWindow(QMainWindow, Ui_Form):
        '''
        窗体类
        '''
     
        def __init__(self, parent=None):
            '''
            初始化窗体
            '''
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
     
            # 获取tts工具类实例
            self.engine = VoiceEngine()
            self.__isPlaying = False
     
            # 设置初始文本
            self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')
     
            # 进度条数据绑定到label中显示
            self.slider_rate.valueChanged.connect(self.setRateTextValue)
            self.slider_volumn.valueChanged.connect(self.setVolumnTextValue)
     
            # 设置进度条初始值
            self.slider_rate.setValue(self.engine.Rate)
            self.slider_volumn.setValue(self.engine.Volume)
     
            # RadioButton选择事件
            self.rbtn_zh.toggled.connect(self.onSelectVoice_zh)
            self.rbtn_en.toggled.connect(self.onSelectVoice_en)
     
            # 播放按钮点击事件
            self.btn_play.clicked.connect(self.onPlayButtonClick)
     
        def setRateTextValue(self):
            '''
            修改语速label文本值
            '''
            value = self.slider_rate.value()
            self.label_rate.setText(str(value))
            self.engine.Rate = value
     
        def setVolumnTextValue(self):
            '''
            修改音量label文本值
            '''
            value = self.slider_volumn.value()
            self.label_volumn.setText(str(value / 100))
            self.engine.Volume = value
     
        def onSelectVoice_zh(self):
            '''
            修改中文的语音配置及默认播放文本
            '''
            self.tbx_text.setText('床前明月光,疑似地上霜。\n举头望明月,低头思故乡。')
            self.engine.VoiceID = 0
     
        def onSelectVoice_en(self):
            '''
            修改英文的语音配置及默认的播放文本
            '''
            self.tbx_text.setText('Hello World')
            self.engine.VoiceID = 1
     
        def playVoice(self):
            '''
            播放
            '''
     
            if self.__isPlaying is not True:
                self.__isPlaying = True
                text = self.tbx_text.toPlainText()
                self.engine.Say(text)
                self.__isPlaying = False
     
        def onPlayButtonClick(self):
            '''
            修改语速label文本值
            '''
            th.start_new_thread(self.playVoice, ())
     
     
    if __name__ == "__main__":
        '''
        主函数
        '''
        app = QApplication(sys.argv)
        form = MainWindow()
        form.show()
        sys.exit(app.exec_())

    相关文章

    python速学教程(入门到精通)
    python速学教程(入门到精通)

    python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载

    相关标签:

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    相关专题

    更多
    php源码安装教程大全
    php源码安装教程大全

    本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

    7

    2025.12.31

    php网站源码教程大全
    php网站源码教程大全

    本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

    4

    2025.12.31

    视频文件格式
    视频文件格式

    本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

    7

    2025.12.31

    不受国内限制的浏览器大全
    不受国内限制的浏览器大全

    想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

    7

    2025.12.31

    出现404解决方法大全
    出现404解决方法大全

    本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

    42

    2025.12.31

    html5怎么播放视频
    html5怎么播放视频

    想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

    4

    2025.12.31

    关闭win10系统自动更新教程大全
    关闭win10系统自动更新教程大全

    本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

    3

    2025.12.31

    阻止电脑自动安装软件教程
    阻止电脑自动安装软件教程

    本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

    3

    2025.12.31

    html5怎么使用
    html5怎么使用

    想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

    2

    2025.12.31

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    最新Python教程 从入门到精通
    最新Python教程 从入门到精通

    共4课时 | 0.6万人学习

    Django 教程
    Django 教程

    共28课时 | 2.6万人学习

    SciPy 教程
    SciPy 教程

    共10课时 | 1.0万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号