Python 文本轉(zhuǎn)語(yǔ)音

文本轉(zhuǎn)語(yǔ)音橱脸,一般會(huì)用在無(wú)障礙開(kāi)發(fā)爸业。下面介紹如何使用Python實(shí)現(xiàn)將文本文件轉(zhuǎn)換成語(yǔ)音輸出掏婶。


[toc]


準(zhǔn)備

我測(cè)試使用的Python版本為2.7.10窒盐,如果你的版本是Python3.5的話草则,這里就不太適合了。
在windows上進(jìn)行測(cè)試的話蟹漓,這里有兩種可選的方式:

使用Speech API

原理

我們的想法是借助微軟的語(yǔ)音接口,所以我們肯定是要進(jìn)行<font color="red" size="5">調(diào)用</font> 相關(guān)的接口牧牢。所以我們需要安裝pywin32來(lái)幫助我們完成這一個(gè)底層的交互看锉。

示例代碼

import win32com.client
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak("Hello, it works!")

小總結(jié)

是的,調(diào)用接口來(lái)實(shí)現(xiàn)語(yǔ)音功能就是這么簡(jiǎn)單塔鳍,但是我們不得不來(lái)聊一聊這種方式的缺點(diǎn)伯铣。

  • 對(duì)中文支持的不夠好,僅僅是這一點(diǎn)轮纫,估計(jì)在中國(guó)沒(méi)幾個(gè)用它的了腔寡。

  • 還有就是語(yǔ)速不能很好的控制,詳細(xì)的API介紹可以參照這里API參考

pyttsx方式

原理

pyttsx 是Python的一個(gè)關(guān)于文字轉(zhuǎn)語(yǔ)音方面的很不錯(cuò)的庫(kù)掌唾。我們還可以借助pyttsx來(lái)實(shí)現(xiàn)在線朗讀rfc文件或者本地文件等等放前,最為關(guān)鍵的是,它對(duì)中文支持的還是不錯(cuò)的糯彬。

示例代碼

# coding:utf-8
import sys

reload(sys)
sys.setdefaultencoding('utf8')
#    __author__ = '郭 璞'
#    __date__ = '2016/8/6'
#    __Desc__ = 文字轉(zhuǎn)語(yǔ)音輸出

import pyttsx
engine = pyttsx.init()
engine.say('hello world')
engine.say('你好凭语,郭璞')
engine.runAndWait()
# 朗讀一次
engine.endLoop()

小總結(jié)

使用pyttsx,我們可以借助其強(qiáng)大的API來(lái)實(shí)現(xiàn)我們基本的業(yè)務(wù)需求撩扒。很酷吧似扔。

pyttsx深入研究

做完上面的小實(shí)驗(yàn),你肯定會(huì)覺(jué)得怎么這么不過(guò)癮呢?
別擔(dān)心炒辉,下面我們就一起走進(jìn)pyttsx的世界豪墅,深入的研究一下其工作原理吧。

語(yǔ)音引擎工廠

類似于設(shè)計(jì)模式中的“工廠模式”黔寇,pyttsx通過(guò)初始化來(lái)獲取語(yǔ)音引擎偶器。當(dāng)我們第一次調(diào)用init操作的時(shí)候,會(huì)返回一個(gè)pyttsx的engine對(duì)象缝裤,再次調(diào)用的時(shí)候屏轰,如果存在engine對(duì)象實(shí)例,就會(huì)使用現(xiàn)有的倘是,否則再重新創(chuàng)建一個(gè)亭枷。

pyttsx.init([driverName : string, debug : bool]) → pyttsx.Engine

從方法聲明上來(lái)看袭艺,第一個(gè)參數(shù)指定的是語(yǔ)音驅(qū)動(dòng)的名稱搀崭,這個(gè)在底層適合操作系統(tǒng)密切相關(guān)的。如下:

  • drivename:由pyttsx.driver模塊根據(jù)操作系統(tǒng)類型來(lái)調(diào)用猾编,默認(rèn)使用當(dāng)前操作系統(tǒng)可以使用的最好的驅(qū)動(dòng)

    • sapi5 - SAPI5 on Windows
    • nsss - NSSpeechSynthesizer on Mac OS X
    • espeak - eSpeak on every other platform
  • debug: 這第二個(gè)參數(shù)是指定要不要以調(diào)試狀態(tài)輸出瘤睹,建議開(kāi)發(fā)階段設(shè)置為True

引擎接口

要想很好的運(yùn)用一個(gè)庫(kù),不了解其API是不行的答倡。下面來(lái)看看pyttsx轰传。engine.Engine的引擎API。

| 方法簽名| 參數(shù)列表 |返回值|簡(jiǎn)單釋義|
|---|---|---|
|connect(topic : string, cb : callable)|topic:要描述的事件名稱瘪撇;cb:回調(diào)函數(shù) |→ dict|在給定的topic上添加回調(diào)通知|
|disconnect(token : dict)|token:回調(diào)失聯(lián)的返回標(biāo)記| Void| 結(jié)束連接|
|endLoop() |None|→ None|簡(jiǎn)單來(lái)說(shuō)就是結(jié)束事件循環(huán)|
|getProperty(name : string)|name有這些枚舉值“rate, vioce,vioces,volumn| → object|獲取當(dāng)前引擎實(shí)例的屬性值|
|setProperty(name : string)|name有這些枚舉值“rate, vioce,vioces,volumn| → object|設(shè)置當(dāng)前引擎實(shí)例的屬性值|
|say(text : unicode, name : string) | text:要進(jìn)行朗讀的文本數(shù)據(jù); name: 關(guān)聯(lián)發(fā)音人获茬,一般用不到|→ None| 預(yù)設(shè)要朗讀的文本數(shù)據(jù),這也是“萬(wàn)事俱備倔既,只欠東風(fēng)”中的“萬(wàn)事俱備”|
|runAndWait() |None|→ None|這個(gè)方法就是“東風(fēng)”了恕曲。當(dāng)事件隊(duì)列中事件全部清空的時(shí)候返回|
|startLoop([useDriverLoop : bool])|useDriverLoop:是否啟用驅(qū)動(dòng)循環(huán)| → None| 開(kāi)啟事件隊(duì)列|

元數(shù)據(jù)音調(diào)

在pyttsx.voice.Voice中,處理合成器的發(fā)音渤涌。

  • age
    發(fā)音人的年齡佩谣,默認(rèn)為None

  • gender
    以字符串為類型的發(fā)音人性別: male, female, or neutral.默認(rèn)為None

  • id
    關(guān)于Voice的字符串確認(rèn)信息. 通過(guò) pyttsx.engine.Engine.setPropertyValue()來(lái)設(shè)置活動(dòng)發(fā)音簽名. 這個(gè)屬性總是被定義挑宠。

  • languages
    發(fā)音支持的語(yǔ)言列表虏劲,如果沒(méi)有,則為一個(gè)空的列表肤晓。

  • name
    發(fā)音人名稱安皱,默認(rèn)為None.

更多測(cè)試

朗讀文本

import pyttsx
engine = pyttsx.init()
engine.say('Sally sells seashells by the seashore.')
engine.say('The quick brown fox jumped over the lazy dog.')
engine.runAndWait()

事件監(jiān)聽(tīng)

import pyttsx
def onStart(name):
   print 'starting', name
def onWord(name, location, length):
   print 'word', name, location, length
def onEnd(name, completed):
   print 'finishing', name, completed
engine = pyttsx.init()
engine.say('The quick brown fox jumped over the lazy dog.')
engine.runAndWait()

打斷發(fā)音

import pyttsx
def onWord(name, location, length):
   print 'word', name, location, length
   if location > 10:
      engine.stop()
engine = pyttsx.init()
engine.say('The quick brown fox jumped over the lazy dog.')
engine.runAndWait()

更換發(fā)音人聲音

engine = pyttsx.init()
voices = engine.getProperty('voices')
for voice in voices:
   engine.setProperty('voice', voice.id)
   engine.say('The quick brown fox jumped over the lazy dog.')
engine.runAndWait()

語(yǔ)速控制

engine = pyttsx.init()
rate = engine.getProperty('rate')
engine.setProperty('rate', rate+50)
engine.say('The quick brown fox jumped over the lazy dog.')
engine.runAndWait()

音量控制

engine = pyttsx.init()
volume = engine.getProperty('volume')
engine.setProperty('volume', volume-0.25)
engine.say('The quick brown fox jumped over the lazy dog.')
engine.runAndWait()

執(zhí)行一個(gè)事件驅(qū)動(dòng)循環(huán)

engine = pyttsx.init()
def onStart(name):
   print 'starting', name
def onWord(name, location, length):
   print 'word', name, location, length
def onEnd(name, completed):
   print 'finishing', name, completed
   if name == 'fox':
      engine.say('What a lazy dog!', 'dog')
   elif name == 'dog':
      engine.endLoop()
engine = pyttsx.init()
engine.say('The quick brown fox jumped over the lazy dog.', 'fox')
engine.startLoop()

使用一個(gè)外部的驅(qū)動(dòng)循環(huán)

engine = pyttsx.init()
engine.say('The quick brown fox jumped over the lazy dog.', 'fox')
engine.startLoop(False)
# engine.iterate() must be called inside externalLoop()
externalLoop()
engine.endLoop()

總結(jié)

看完了上面的講述调鬓,是不是感覺(jué)Python實(shí)現(xiàn)文本轉(zhuǎn)語(yǔ)音還是蠻簡(jiǎn)單的?

那么酌伊,快來(lái)嘗試嘗試吧袖迎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子燕锥,更是在濱河造成了極大的恐慌辜贵,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件归形,死亡現(xiàn)場(chǎng)離奇詭異托慨,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)暇榴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門厚棵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蔼紧,你說(shuō)我怎么就攤上這事婆硬。” “怎么了奸例?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵彬犯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我查吊,道長(zhǎng)谐区,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任逻卖,我火速辦了婚禮宋列,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘评也。我一直安慰自己炼杖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布盗迟。 她就那樣靜靜地躺著坤邪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诈乒。 梳的紋絲不亂的頭發(fā)上罩扇,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音怕磨,去河邊找鬼喂饥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛肠鲫,可吹牛的內(nèi)容都是我干的员帮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼导饲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼捞高!你這毒婦竟也來(lái)了氯材?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤硝岗,失蹤者是張志新(化名)和其女友劉穎氢哮,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體型檀,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冗尤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胀溺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片裂七。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖仓坞,靈堂內(nèi)的尸體忽然破棺而出背零,到底是詐尸還是另有隱情,我是刑警寧澤无埃,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布徙瓶,位于F島的核電站,受9級(jí)特大地震影響录语,放射性物質(zhì)發(fā)生泄漏倍啥。R本人自食惡果不足惜禾乘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一澎埠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧始藕,春花似錦蒲稳、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至诉植,卻和暖如春祥国,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晾腔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工舌稀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人灼擂。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓壁查,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親剔应。 傳聞我的和親對(duì)象是個(gè)殘疾皇子睡腿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容