четверг, 10 ноября 2011 г.

Учим змею разговаривать

Читая хабр, наткнулся на интересную статью, рассказывающую о том, как научить PowerShell разговаривать с помощью Microsoft`овского Speech API (там же есть ссылка на отличную замену старому доброму Сэму). Так как ставить и осваивать PowerShell только для того чтобы побаловаться, было лениво, я занялся поисками модулей с нужным мне функционалом, под python. В итоге наткнулся на отличную библиотеку под названием pyTTS. И так приступим. Для работы нам так же понадобится: Microsoft SAPI 5.0 or 5.1 redistributable win32all Python Extensions Советую так-же скачать голос Алёна, фирмы Acapela, распространяющийся по 30-ти дневной триал лицензии Начнём с простого:

import pyTTS
tts = pyTTS.Create() 
tts.Speak("Hello World") 

Кто произнесёт сакраментальную фразу, будет зависеть от установленного по умолчанию в системе голоса, для Windows XP это небезызвестный Microsoft Sam, которым я пугал детей моих друзей. Список всех установленных в системе голосов можно вывести так:
print tts.voices
Вот например, что напечаталось у меня:
{u'Alyona22k': <win32com.gen_py.Microsoft Speech Object Library.ISpeechObjectToken instance at 0x15286320>,
u'MSSam': <win32com.gen_py.Microsoft Speech Object Library.ISpeechObjectToken instance at 0x15286224>}
Видно что tts.voices это просто словарь, ключами к которому являются названия голосов. Попробуем сменить железного Сэма, на кого то с более приятным голосом:
tts.SetVoiceByName(u"Alyona22k")
tts.Speak(u"Привет мир")
Так же с помощью методов SetVolume и SetRate можно изменять громкость и скорость произношения. Поковырявшись в библиотеке, я решил написать что то, хоть мало мальски полезное, а именно, скрипт произносящий заголовки новостных лент. За основу был взят этот код. Вот что в итоге получилось:
# -*- coding: utf-8 -*-

from urllib2 import urlopen
from xml.sax import make_parser, ContentHandler
import sys
import pyTTS


class RSSHandler(ContentHandler):

    def __init__(self, tts):
        ContentHandler.__init__(self)
        self._tts = tts
        self.__initem_flag = False
        self.__intitle_flag = False


    def characters(self, data):
        if self.__intitle_flag:
            self._tts.Speak(data)
            sys.stdout.write(data.encode(sys.stdout.encoding))


    def startElement(self, tag, attrs):
        if tag == "item":
            self.__initem_flag = True

        if tag == "title" and self.__initem_flag:
            self.__intitle_flag = True


    def endElement(self, tag):
        if tag == "title" and self.__intitle_flag:
            sys.stdout.write("\n")
            self.__intitle_flag = False

        if tag == "item":
            self.__initem_flag = False


def readFeedTitle(url, tts):
    infile = urlopen(url)
    parser = make_parser()

    parser.setContentHandler(RSSHandler(tts))
    parser.parse(infile)


def main():
    tts = pyTTS.Create()

    # Если установлен голос Алёна, используем его
    # если в вашей системе есть другие русские голоса, просто поменяйте имя
    if u"Alyona22k" in tts.voices:
        tts.SetVoiceByName(u"Alyona22k")

        # прочитаем заголовки новостей с python.su на русском
        readFeedTitle("http://python.su/feeds/blog/", tts)

    # или новости с python.org голосом утстановленным по умолчанию в системе
    else:
        readFeedTitle("http://python.su/feeds/blog/", tts)


if(__name__ == '__main__'):
    main()

Комментариев нет:

Отправить комментарий