Статьи

Эксклюзивная Халява: Утилита Text-To-Speech

Первый месяц (более или менее) и, следовательно, время для другой эксклюзивной халявы! В этом месяце автор FlashDanctuary ActiveDen предлагает интересный инструмент, использующий Google Text-To-Speech API. Проверьте это после скачка!


Не так давно Google добавил новую замечательную функцию в систему Google Translate, которая называется функцией преобразования текста в речь. Это не официальный API, но любой может воспользоваться услугой. Все, что вам нужно сделать, это получить доступ к URL, который генерирует mp3-файл. Этот файл может быть воспроизведен во флэш-памяти, как любой mp3-файл.


Первым шагом является создание класса преобразования текста в речь. Откройте flash и выберите меню «Файл», новое подменю и новый файл сценария действия. Затем сохраните этот файл на жестком диске в нужной вам упаковке. Давайте назовем этот класс и файл Text2Speech.as .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
package com.flashanctuary.text2speech
{
    // flash imports
    import flash.events.Event;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundTransform;
    import flash.net.URLRequest;
     
    /**
     * Text2Speech Main class
     */
    public class Text2Speech
    {
        public function Text2Speech() : void
        {
 
        }
    }
}

Во-первых, нам нужна постоянная ссылка на API Google. Еще одна объявленная константа касается ограничения API Google: она не может воспроизводить строку длиной более 100 символов. Конечно, мой флэш-файл воспроизводит фразы длиннее 100 символов, я объясню, как позже.

Другие переменные, которые нам нужны, включают в себя: текст для воспроизведения, массив, содержащий фразы длиной не более 100 символов из текста, текущую позицию предложения, которая будет воспроизводиться в один момент, язык, на котором будет воспроизводиться текст. Нам также нужны три переменные для воспроизведения звука: переменная Sound, переменная SoundChannel и переменная SoundTransform.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
// google api link
private static const url : String = «http://translate.google.com/translate_tts?»;
         
// maximum number of characters supported by google api
private static const noOfMaxChars : Number = 100;
 
//
private var _text : String;
private var _sentences : Array;
private var _sentencePosition : int;
 
//
private var sound : Sound;
private var soundChannel : SoundChannel;
private var sTransform : SoundTransform;
 
//
private var _volume : Number = 0.5;
private var _currentPosition : Number = 0;
 
//
private var _language : String;

Теперь нам понадобится публичная функция для инициализации этого класса: она будет содержать текст, который мы хотим воспроизвести, и язык.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public function init(language : String, text : String) : void
{
    // set language
    _language = language;
     
    // if the number of chars is longer than the maximum number of chars supported
    // the the text will be split
    if (text.length <= noOfMaxChars)
    {
        initSound(url + «tl=» + language + «&q=» + text);
    }
    else
    {
        _sentences = new Array();
         
        // split text
        divideText(text);
        _sentencePosition = 0;
         
        // begin palying the first part of the text
        initSound(url + «tl=» + language + «&q=» + _sentences[_sentencePosition]);
    }
}

Если длина нашего текста превышает поддерживаемое количество символов, мы должны разделить его на предложения, содержащие не более 100 символов. Для этого мы создаем рекурсивную функцию, которая просматривает весь текст и вставляет предложения максимум в 100 символов в массив.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private function divideText(str : String) : void
{
    var substr : String;
    if (str.length >= noOfMaxChars)
    {
        substr = str.substring(0, noOfMaxChars + 1);
    }
    else
    {
        substr = str;
    }
     
    if (substr.charAt(substr.length — 1) != » » && str.length >= noOfMaxChars)
    {
        var index : int = substr.lastIndexOf(» «);
        substr = str.substring(0, index);
    }
     
    _sentences.push(substr);
     
    if (str.substring(substr.length + 1, str.length).length > 0)
    {
        divideText(str.substring(substr.length + 1, str.length));
    }
}

Отныне процесс похож на создание mp3-плеера. Во-первых, мы инициализируем звуковые переменные, о которых я говорил в первом случае, и после этого мы начинаем воспроизводить первое предложение из целого массива предложений.

Когда это предложение закончится, мы идем и воспроизводим следующее (когда происходит событие SOUND_COMPLETE). И так далее, и так далее, пока не будут воспроизведены все максимально 100 символов предложения из нашего исходного текста.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public function initSound(path : String) : void
{
    // reset sounds chanels, sound and sound transform if they are not null
    if (soundChannel != null)
    {
        stopSound();
        soundChannel = null;
    }
     
    if (sound != null)
    {
        sound = null;
    }
     
    if (sTransform != null)
    {
        sTransform = null;
    }
     
    _currentPosition = 0;
     
    // create the new sound and begin playing
    sound = new Sound(new URLRequest(path));
    soundChannel = new SoundChannel();
    sTransform = new SoundTransform(_volume);
    playSound();
}
 
public function playSound() : void
{
    soundChannel = sound.play(_currentPosition);
    soundChannel.addEventListener(Event.SOUND_COMPLETE, soundComplete);
    soundChannel.soundTransform = sTransform;
}
 
public function stopSound() : void
{
    _currentPosition = soundChannel.position;
    if (soundChannel.hasEventListener(Event.SOUND_COMPLETE))
    {
        soundChannel.removeEventListener(Event.SOUND_COMPLETE, soundComplete);
    }
    soundChannel.stop();
}
 
private function soundComplete(evt : Event) : void
{
    stopSound();
     
    // when the current sound is complete go to the next group of charcters and play that part
    if (_sentences != null)
    {
        if (_sentencePosition < _sentences.length — 1)
        {
            _sentencePosition++;
            initSound(url + «tl=» + _language + «&q=» + _sentences[_sentencePosition]);
        }
    }
}

Теперь вы, вероятно, спросите, как этот класс можно использовать в одном из ваших проектов. Ну, это очень просто: вам просто нужно создать один экземпляр
этого класса и инициализировать его с желаемым языком и текстом. Все поддерживаемые языки перечислены и могут быть найдены на http://translate.google.com .

1
2
3
4
5
// create the new text to speech variable
var t2s : Text2Speech = new Text2Speech();
 
// initialize the text to speech class instance with the language desired and the text
t2s.init(language_abbreviation, text_to_play);

Возможно, вы уже заметили в предварительном просмотре, что иногда обрыв появляется, когда заканчивается звук, а начинается другой. Эту проблему легко решить, загрузив все звуки перед их воспроизведением. Этот метод подразумевает более длительное время загрузки, особенно когда выбранный текст для воспроизведения очень длинный. Лучшее решение на данный момент, кажется, выше, но если у кого-то есть лучшее, вы можете оставить комментарий!


Я потратил много времени, пытаясь найти решение этой проблемы преобразования текста в речь, чтобы использовать ее во Flash. Кажется, Google решил это, и решение в наши дни легко и доступно для всех разработчиков.

Это мой первый вклад в Activetuts +, я надеюсь, что вы узнали что-то полезное, наслаждайтесь файлом и спасибо за чтение!