Python3 语音合成——pyttsx3 从文本到语音

pyttsx3是一款非常简单的文本到语音的转换库,可以脱机工作,支持多种TTS引擎(sapi5、nsss、espeak),通过这个库可以非常方便的将文字转换成语音;

安装pyttsx3:

pip install pyttsx3

首先看下pyttsx3最简单的应用:

import pyttsx3

say = pyttsx3.init()        # 创建pyttsx对象,并初始化对象

msg = '''今天的天气真好,出去打球吧'''    # 需要合成的文字

say.say(msg)        # 合成并播放语音
say.runAndWait()    # 等待语音播放完

是不是非常的简单,但是现在所有的参数都是默认的,或许我们希望他的语速快一点、音量响一点,或者是女声,那么这就需要我们对参数进行配置,接下来我们一个一个来看:

  1. 我们先来看下在创建pyttsx3实例对象的时候都做了什么:
    Python3 语音合成——pyttsx3 从文本到语音_第1张图片
    通过函数运行的介绍和分析,我们可以知道,init()构造一个新的TTS引擎实例;
    它有两个参数:
        1)driverName:这个参数就是说,当前程序在什么设备上运行的,指定语音驱动的名字;如果为None,则选择操作系统的默认驱动程序;一般来讲我们使用默认的就好,可以保证代码的可移植性;
            sapi5 : 在Windows平台上使用
            nsss: 在Mac OS平台上使用
            espeak: 其他平台
        2)debug:这个就非常简单了,就是指要不要以调试模式输出,建议在进行开发的时候开启;
  2. 接下来我们来看看几个方法的使用:
    1)say() :就是将我们需要合成的文字添加到事件队列中
    Python3 语音合成——pyttsx3 从文本到语音_第2张图片
    我们可以看见有两个参数:
        text : 就是我们需要合成的文字
        name : 这个参数就是来标识这段文字的,在后面的事件监听再详细讲
    2)runAndWait() : 它的作用就是运行事件循环,直到事件队列中没有内容
    Python3 语音合成——pyttsx3 从文本到语音_第3张图片

接下来我们通过实例一步一步讲解其他的属性和方法:

  1. 我想要控制它的语速该怎么办:
    import pyttsx3
    
    say = pyttsx3.init()
    
    rate = say.getProperty('rate')          # 获取当前语速属性的值
    say.setProperty('rate', rate-20)        # 设置语速属性为当前语速减20
    
    msg = '''今天天气不错,出去打篮球吧!'''
    
    say.say(msg)
    say.runAndWait()
    现在新出现了两个方法:getProperty()和setProperty(),从字面上看,这两个一个是获取属性值,一个是设置属性值,我们来看下他的函数原型是什么:
    Python3 语音合成——pyttsx3 从文本到语音_第4张图片
    从上面我们可以看出getProperty()方法可以得到:
        voices:pyttsx3.voice.Voice支持的对象描述列表(个人理解相当于给我们提供和很多合成器,默认选择的是第一个合成器),里面存放了语音合成的所有属性;
        voice:当前正在使用的合成器的ID
        rate:当前的语速
        volume:当前的音量(音量应为[0.0 - 1.0])
    import pyttsx3
    
    say = pyttsx3.init()
    
    volume = say.getProperty('volume')    # 最开始以为这个是用来获取当前属性值的,但是发现将属性值修改了再获取,并没有发生变化
    print('默认的音量是:',volume)
    
    rate = say.getProperty('rate')
    print('默认的语速是:',rate)
    
    voice = say.getProperty('voice')
    print('默认使用的合成器ID:',voice)
    
    voices = say.getProperty('voices')
    print('合成器列表:',voices)
    
    for i in voices:
        print(i)
    
    # 输出结果:
    # 当前的音量是: 1.0
    # 当前的语速是: 200
    # 当前使用的合成器ID: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_ZH-CN_HUIHUI_11.0
    # 合成器列表: [, ]
    # 
    # 
    通过上面的程序,大概可以猜出setProperty()的用法:
    Python3 语音合成——pyttsx3 从文本到语音_第5张图片
    其实非常简单,我们可以想象成键值对,一共有两个参数,第一个是键名,第二个就是值;

    从上面我们知道,当前一共有两种合成器,也就相当于有两种音色,那如何切换两种音色呢?
    import pyttsx3
    
    say = pyttsx3.init()
    
    voices = say.getProperty('voices')
    say.setProperty('voice',voices[1].id)    # 注意,voice这个属性接收的是id
    
    say.say('How are you!')
    say.runAndWait()
    之前在播放中文的时候,第一种可以正常播放,第二种就直接罢工了,后面合成英文的句子,两个都可以播放,并且可以听到很明显的差别,这个有兴趣可以好好研究下;(好像看见其他文章有说可以下载合成器什么的,后面就找不到了,后面再补充)
  2. 接下来我们我们来看一下事件的监听:
    Python3 语音合成——pyttsx3 从文本到语音_第6张图片
    import pyttsx3
    
    def Start(name):
        print('starting', name)
    def onWord(name, location, length):
        print('word', name, location, length)
        if location > 20:
            engine.stop()
    def onEnd(name, completed):
        print('finishing', name, completed)
    def onError(name, exception):
        print('error:', name, exception)
    
    engine = pyttsx3.init()
    
    engine.connect('started-word', onWord)
    engine.connect('started-utterance', Start)
    engine.connect('finished-utterance', onEnd)
    engine.connect('error', onError)
    
    engine.say('The quick brown fox jumped over the lazy dog.','test')
    engine.runAndWait()
    上面这段代码是官方给出的,大致的用法是:
        1、connect()方法分别绑定三种状态,相应的状态执行对应的回调函数
        2、事件状态的名称是固定的:
                  started-utterance - 播放开始之前
                  started-word - 播放的时候
                  finished-utterance - 播放完成之后
                  error - 即为产生异常的时候
        3、我们从上面可以看见有四个回调函数,下面就是四个回调函数调用的状态:
    Python3 语音合成——pyttsx3 从文本到语音_第7张图片
    所有的回调函数都有一个共同的参数 -- name,这个就是用来标识现在正在播放那一段文字的;
        4、onWord() - location 表示播放的位置
                                length 表示当前播放的长度
              onEnd() - completed 表示是否全部输出,如果全部播放即为True,反之为False
              onError() - exception表示返回的异常信息
              我们可以灵活的运用回调的参数,对播放的状态进行监听,比如播放完毕判断是否全部播放完毕,不然如何处理;
  3. 现在假设一个场景,正在播放一个故事,定时在10分钟之后停止,该怎么做呢?
    import pyttsx3
    import time
    
    def onWord(name, location, length):
        print('word', name, location, length)
        if time.time() > time.mktime((2020,1,5,0,30,0,0,0,0)):    # 在规定的时间停止
            engine.stop()    # stop()方法会停止播放并清空队列
    
    engine = pyttsx3.init()
    
    engine.connect('started-word', onWord)
    
    story = '''兔子的胆小是出了名的,经常受到的惊吓总是像石头一样压在它们的心上。
      有一次,众多兔子聚集在一起,为自己的胆小无能而难过,悲叹自己的生活中充满了危险和恐惧。
      它们越谈越伤心,就好像已经有许多不幸发生在自己身上,而这也就是它们之所以成为兔子的原因。到了这种地步,负面的想像便无止境地涌现出来。它们怨叹自己天生不幸,既没有力气和翅膀,也没有牙齿,日子只能在东怕西怕中度过,就连想要抛弃一切大睡一觉,也有什么都听得见的长耳朵的阻扰,赤红的眼睛也就变得更加鲜红了。
      它们觉得自己的这种生活是毫无意义的,这又成了它们自我厌恶的根源。它们都觉得,与其一生心惊胆战,还不如一死了之好。
      于是,它们一致决定从山崖上跳下去了结自己的生命,结束一切烦恼。就这样决定了,于是它们一齐奔向山崖,想要投河自尽。这时,一些青蛙正围在湖边蹲着,听到急促的脚步声,如临大敌,立刻跳到深水里逃命去了。
      这是兔子每次到池塘边都会看到的情景,但是今天,有一只兔子突然明白了什么,它大声地说:“快停下来,我们不必吓得去寻死寻活了,因为我们现在可以看见,还有比我们更胆小的动物呢!”
      这么一说,兔子们的心情奇妙地豁然开朗起来了,好像有一股勇气喷涌而出,于是它们欢天喜地回家去了。
      【大道理】不要为我们现在的遭遇就埋怨命运的不公,实际上,世界上还有很多比我们更不幸的人,想想那些更不幸的人仍旧坚强地活着,我们又为什么不能呢?'''
    
    engine.say(story)
    engine.runAndWait()

pyttsx3这个库还没有完全研究完,比如:
Python3 语音合成——pyttsx3 从文本到语音_第8张图片
Python3 语音合成——pyttsx3 从文本到语音_第9张图片

你可能感兴趣的:(Python,#,Python,人工智能,Python3,语音合成)