• Home
  • Projects
  • About
  • Contact

Google’s Text To Speech Engine in Flash

Devon O. · May 27, 2010 · Actionscript · 21 comments
5

I’m not sure how I managed to miss this, but I just happened to run across a ‘new’ (well, newish), albeit still unofficial, offering of Google today: text-to-speech. You can see what few details there are on this Techcrunch post. Basically, it just boils down to this though – you send your phrase to be spoken in a GET request like so ‘http://translate.google.com/translate_tts?tl=en&q=hello%20world’, and in return Google gives you an .mp3 formatted sound file of your phrase being spoken in some non-threatening female robot voice.

Of course loading .mp3 files into Flash is a piece of cake, so integration with the Flash platform is nothing at all. The one thing that may get you is that Flash doesn’t like to load .mp3’s across domains. A very basic serverside proxy script will get you around that easily enough though. Here’s a quick example.

This will take a String phrase and generate the URL to the Google translator for you:

ActionScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package  {
 
    public class GTextToSpeech {
        
        private var _language:String;
        
        public function GTextToSpeech(language:String = "en") {
            _language = language;
        }
        
        /**
         * Use this to get the URL of the mp3 containing the spoken words of the 'phrase' parameter
         * @param    phrase
         * @return    String    URL to Google Text to Speech engine
         */
        public function say(phrase:String):String {
            if (phrase.length > 100) throw new Error("Google currently only supports phrases less than 100 characters in length.");
            var qs:String = "tl=" + _language + "&q=";
            qs += encodeURI(phrase);
            return "http://translate.google.com/translate_tts?" + qs;
        }
    }
}

And here’s an example of a bare minimum proxy in php:

PHP
1
2
3
4
5
<?php
$url = (isset($_POST['url']) && $_POST['url']) ? $_POST['url'] : 'undefined';
 
if ($url !='undefined') echo file_get_contents($url);
?>

And put it together (using the Bit-101 MinimalComps):

ActionScript
1
2
3
4
5
6
7
8
9
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package {
    
    import com.bit101.components.HBox;
    import com.bit101.components.InputText;
    import com.bit101.components.PushButton;
    import com.bit101.components.Style;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;
    
    /**
     * quick test of Google text-to-speech tool
     * @author Devon O.
     */
 
    [SWF(width='350', height='80', backgroundColor='#FFFFFF', frameRate='12')]
    public class Main extends Sprite {
        
        private var _phrase:InputText;
        private var _goButton:PushButton;
        
        private var _speech:Sound = new Sound();
        private var _channel:SoundChannel;
        
        private var _tts:GTextToSpeech = new GTextToSpeech();
        
        public function Main():void {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            initUI();
        }
        
        private function initUI():void {
            Style.embedFonts = true;
            Style.BUTTON_FACE = 0x000000;
            var container:HBox = new HBox(this, 25, 25);
            _phrase = new InputText(container);
            _phrase.width = 200;
            _phrase.maxChars = 100;
            _goButton = new PushButton(container, 0, 0, "Speak", goHandler);
        }
        
        private function goHandler(event:MouseEvent):void {
            if (_phrase.text != "") {
                _goButton.enabled = false;
                var req:URLRequest = new URLRequest("proxy.php");
                req.method = URLRequestMethod.POST;
                var vars:URLVariables = new URLVariables();
                vars.url = _tts.say(_phrase.text);
                req.data = vars;
                _speech.load(req);
                _channel = _speech.play();
                _channel.addEventListener(Event.SOUND_COMPLETE, soundDoneHandler);
            } else {
                _phrase.text = "Type something here, dummy.";
            }
        }
        
        private function soundDoneHandler(event:Event):void {
            _goButton.enabled = true;
        }
    }
}

And that will give you this (just type something in the box, and hit the ‘Speak’ button. Of course, you’ll need your sound on):

Get Adobe Flash player

According to Techcrunch, the API is currently limited to 100 character long phrases, but I haven’t actually tested that to check it’s validity. Even if that’s the case, it’s still quite a fun little toy to play with and can add a bit of dimension and accessibility to Flash apps to come.

  Facebook   Pinterest   Twitter   Google+
googletext-to-speech
  • “Double Sided Plane” with Papervision
    January 15, 2008 · 0 comments
    2075
    2
    Read more
  • Santabot: A Unity3D Flash Game
    December 26, 2011 · 4 comments
    2125
    13
    Read more
  • Last.FM + Twitter = Warbler
    March 08, 2009 · 32 comments
    2601
    3
    Read more
21 Comments:
  1. Awesome! It looks like it does work for other languages. Here’s French: http://translate.google.com/translate_tts?tl=fr&q=je+ne+comprends+pas

    Going to have to have a play around with this…

    Paul Neave · May 27, 2010
  2. Thanks Paul. It is pretty damn fun.

    One thing I just noticed – it seems to max out at less than 100 chars though – so if anyone has problems with the example above where the button locks up and nothing plays, try refreshing the page and using a shorter phrase.

    Devon O. · May 27, 2010
  3. Hi there

    I posted a simple AS3 interface to Google’s textToSpeech API about 3 weeks ago (8 May 2010), you can read more about it and download at: http://peteshand.net/blog/index.php/actionscript-text-to-speech/

    I’ve also added the ability to convert strings greater than 100 characters in length as well by splitting the string and making multiple requests. Multilingual support is next on the to do list.

    pete shand · May 27, 2010
  4. Hey Pete. I am definitely slow on the draw. Splitting the phrases up into smaller requests is a great idea!

    Devon O. · May 27, 2010
  5. Awesome idea :)
    Anyway it should maxout at the browser’s/vendor capability for the URL Request Method ( IE supports 2083 ) other browsers support more ( 4k for opera )

    Hugo Matinho · May 27, 2010
  6. opps .. 2083 and 4k characters

    Hugo Matinho · May 27, 2010
  7. Very neat. I will definitely be giving this a try in ActionScript.

    Also, you can reduce that proxy to one single line of code. ;)
    if ($_POST[‘url’]) echo file_get_contents($_POST[‘url’]);

    REMEMBER, use file_get_contents() with care. If anyone decides to pass in the name of a PHP file (only the file name, such as “index.php” without the actual domain) it will return the PHP code for that page, which might leak sensitive information such as database passwords etc. Use with care!

    Andreas Renberg · May 28, 2010
  8. Actually that proxy is unnecessary in this case, simply *play* sound from other domain via Sound class doesn’t require the crossdomain authorization.

    Cotton · May 31, 2010
  9. forget comment the change:
    _speech.load(new URLRequest(_tts.say(_phrase.text)));

    Cotton · May 31, 2010
  10. Hi
    Is there a way to also save the mp3 on your own server for later use?

    David · August 04, 2010
  11. hey David. Good question. I suppose once you get the url to the mp3 file, you could play around with a FileReference instance to download it locally. Saving it to a different web server could be a whole other ball of fish though. May be easier to convert it to wav and save it to your own server that way.

    Devon O. · August 04, 2010
  12. Hi Devon
    I found an easy way here
    http://masnun.com/blog/2009/12/14/googles-text-to-speech-api-a-php-wrapper-class/
    so all you would have to do is pass the text from flex to this php file..simple.

    David · August 04, 2010
  13. the proxy will not allow for the correct pronunciation of special characters, i.e. “é”. so far i’ve tried the cURL and fopen functions, and now “echo file_get_contents($url);”. what is it that’s screwing up the special chars!?

    Daniel Kazmer · April 26, 2011
  14. I tried to use the same code and compile it and run it locally in Adobe Air 2.6. I got the stream error: “Error #2044: Unhandled IOErrorEvent:. text=Error #2032: Stream Error”. Anybody can point a direction to how solve it? I thought that Air is less on security checking

    al · May 06, 2011
  15. Hi Pete.

    Found this great text-to-speech of yours when I was still an AS2 freak so couldnt test it. Now I am an AS3 freak (and loving it) but cant get the downloaded code to work I get the followning errors’;

    \psUtils\examples\TextToSpeech\main.as, Line 15 1046: Type was not found or was not a compile-time constant: TextToSpeech.

    \psUtils\examples\TextToSpeech\main.as, Line 23 1180: Call to a possibly undefined method TextToSpeech.

    \psUtils\examples\TextToSpeech\main.as, Line 24 1120: Access of undefined property Language.

    \psUtils\examples\TextToSpeech\main.as, Line 6 1172: Definition ps.GText2Speech:TextToSpeech could not be found.

    \psUtils\examples\TextToSpeech\main.as, Line 7 1172: Definition ps.GTranslate:Language could not be found.

    Sorry but its quite a lot. Any pointers on how I can overcoem these ? Maybe its obvious to you !

    Thanks

    Paul

    Paul · February 26, 2012
  16. Does anyone have a fix for the AIR 2.6 stream error ?

    Paul

    Paul · February 27, 2012
  17. Killer……any idea why it doesn’t work more than once without refreshing the page? Or am I the only one having this problem?

    Elliott · March 11, 2012
  18. the reason you have to refresh the page to hear more than one word is because of a coding error: each sound instance can load, at most, one sound file.

    to remedy replace:

    private var _speech:Sound = new Sound();

    with:

    private var _speech:Sound;

    and replace:

    _speech.load(req);

    with:

    _speech = new Sound();
    _speech.load(req);

    kglad · February 13, 2013
  19. If you are looking for an offline solution to use TTS with AS3 and AIR for mobile, take a look at my ANE :

    http://fabricemontfort.com/product/ezspeech-ane-air-native-extension/

    Hope it helps.

    Fabrice Montfort · March 19, 2017

Leave a Comment! Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Devon O. Wolfgang

AIR | Unity3D | AR/VR

Unity Certified Developer

Technical Reviewer of “The Essential Guide to Flash CS4 AIR Development” and “Starling Game Development Essentials”

Reviewer of “The Starling Handbook”

Unity Engineer at Touch Press.

Categories
  • Actionscript (95)
  • AIR (16)
  • Flash (99)
  • Games (7)
  • Liberty (13)
  • Life (52)
  • Shaders (20)
  • Unity3D (19)
Recent Comments
  • onebyonedesign » Custom Post Processing with the LWRP on Unity Ripple or Shock Wave Effect
  • Devon O. on Unity Ripple or Shock Wave Effect
  • Elias on Unity Ripple or Shock Wave Effect
  • math games on Particle Editor for Starling Framework
  • Sean on Unity Ripple or Shock Wave Effect
Archives
  • September 2019 (1)
  • February 2019 (2)
  • December 2018 (1)
  • July 2018 (1)
  • June 2018 (1)
  • May 2018 (2)
  • January 2018 (1)
  • December 2017 (2)
  • October 2017 (1)
  • September 2017 (2)
  • January 2017 (1)
  • July 2016 (1)
  • December 2015 (2)
  • March 2015 (1)
  • September 2014 (1)
  • January 2014 (1)
  • August 2013 (1)
  • July 2013 (1)
  • May 2013 (1)
  • March 2013 (2)
  • December 2012 (1)
  • November 2012 (1)
  • September 2012 (3)
  • June 2012 (2)
  • May 2012 (1)
  • April 2012 (1)
  • December 2011 (2)
  • October 2011 (3)
  • September 2011 (1)
  • August 2011 (1)
  • July 2011 (1)
  • May 2011 (2)
  • April 2011 (2)
  • March 2011 (1)
  • February 2011 (1)
  • January 2011 (2)
  • December 2010 (3)
  • October 2010 (5)
  • September 2010 (1)
  • July 2010 (2)
  • May 2010 (5)
  • April 2010 (2)
  • March 2010 (7)
  • February 2010 (5)
  • January 2010 (5)
  • December 2009 (3)
  • November 2009 (1)
  • October 2009 (5)
  • September 2009 (5)
  • August 2009 (1)
  • July 2009 (1)
  • June 2009 (2)
  • May 2009 (6)
  • April 2009 (4)
  • March 2009 (2)
  • February 2009 (4)
  • January 2009 (1)
  • December 2008 (5)
  • November 2008 (2)
  • September 2008 (1)
  • August 2008 (6)
  • July 2008 (6)
  • June 2008 (9)
  • May 2008 (4)
  • April 2008 (3)
  • March 2008 (4)
  • February 2008 (9)
  • January 2008 (7)
  • December 2007 (6)
Copyright © 2017 Devon O. Wolfgang