Location: PHPKode > scripts > Google Text To Speech > googleTTSphp.class.php
<?php
/*
 *   This class was created to abstract GOOGLE UNOFFICAL API FOR TEXT TO SPEECH!
 *   Can be used for help creating features to read whole websites to speech aswell as using simple tts features.
 *   This site is helpful for blinded people to use your website.
 *
 *   Copyright (C) <2010>  Petter Kjelkenes <hide@address.com>
 *   Website HTTP://PKJ.NO
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *
 * ------- REQUIREMENTS --------
 *  * PHP 5.0 and later.
 *
 *  PLEASE KEEP ALL CREDIT INTACT.
 *  Petter Kjelkenes, PKJ.NO
 *
 */

class GoogleTTS{

    public $strings;
    private $mp3folder="mp3_tts/";
    
    private $lang='en';

    /**
      * setInput Must be run.
      * @param $texts Array, string or HTML code to translate into file bits of mp3.
      * @param $html If this should be parsed as html, set this to true. If this is an array or string to translate, put false.
      *
      */
    public function setInput($texts, $html=false){

        if (is_array($texts)){
            foreach($texts as $t){
                $this->strings[] = $t;
            }
        }elseif ($html==false){
            $this->strings[] = $texts;
        }elseif ($html){
            $this->parseHTMLtoStrings($texts);
        }
        

    }
    /**
      * setLang Set the language. With 2 letter code for language.
      * @param $l Language to speech... Use forexample: 'en' 'se' 'no',
      *
      */
    public function setLang($l){
        $this->lang = $l;
    }
    
    /**
      * Sets the storage path, where this class saves and caches mp3 files.
      * @param $htmlcode A whole html page, or just bits of xml / html.
      * @todo Make it have more functionality, right now it is pretty useless.
      */
    public function parseHTMLtoStrings($htmlcode){
       /* $doc = new DOMDocument();
        $doc->loadHTML($htmlcode);
        $doc->preserveWhiteSpace = false;
        $content = $doc->getElementsByTagname('body');

        foreach ($content as $item){
             echo "\n".$item->nodeValue;
        } */
        
        $str = str_replace(array("\r","\n"),' ',strip_tags($htmlcode));
        $str = trim($str);
        $strA = $this->strSplitWordFriendly($str,100);
        $this->strings = array_merge($this->strings, $strA);
    }

    /**
      * Sets the storage path, where this class saves and caches mp3 files.
      *
      */
    public function setStorageFolder($s){
        $this->mp3folder = $s;
        return true;
    }
    
    /**
      * Downloads mp3 file(s) to storage, saves file as md5($text), caches is and if the text bit already exists it will NOT dl it, but just move on!
      * This should not be run @ level when user is waiting on the page to load, rather add ajax call to it. Let it load in background.
      */
    public function downloadMP3(){
        if (!file_exists($this->mp3folder))mkdir($this->mp3folder);
        if (!file_exists($this->mp3folder))throw new Exception("You must set the storage folder for storing mp3. Current is: ".$this->mp3folder);
        foreach($this->strings as $s){
            $strA = $this->strSplitWordFriendly($s, 100);
            foreach($strA as $str){
                $filename=md5(trim(strtoupper($str))).'.mp3';

                $filepath = $this->mp3folder.$filename;
                if (!file_exists($filepath)){
                    file_put_contents($filepath, file_get_contents("http://translate.google.com/translate_tts?tl=".$this->lang."&q=".urlencode($str).""));
                }
            }


        }
        return true;
    }

    /**
      * Gets the mp3 files from the loaded strings in array.
      *
      */
    public function getMP3s(){
        $ret = array();
        foreach($this->strings as $s){
            $strA = $this->strSplitWordFriendly($s, 100);
            foreach($strA as $str){
                $filename=md5(trim(strtoupper($str))).'.mp3';

                $filepath = $this->mp3folder.$filename;

                $ret[] = $filepath;
            }
        }
        return $ret;
    }

    /**
      * Smart str_split, does not split if in a middle of a word... Goes to next file then.
      * If words are bigger then $size it will use generic str_split.
      *
      * Created because google has 100chars limit. This makes many files, and does nice splitting when it comes to words and limit of chars.
      */
    private function strSplitWordFriendly($str, $size){
        $str = trim(strip_tags($str));
        $length = strlen($str);

        $ex = explode(' ',$str);

        $op = array();

        $newarr = '';
        foreach($ex as $word){
            if (strlen(' '.$word) > $size){
                $op[] = $newarr;
                $newarr = '';
                $splitA = str_split($word, $size);
                $op = array_merge($op, $splitA);
                echo "DASS";
            }elseif (strlen($newarr.' '.$word) <= $size && !( ($size-strlen($newarr)) > $size*0.15 && strstr($newarr,'.'))   ){
                $newarr .= ' '.$word;
            }else {
                $op[] = $newarr;
                $newarr = '';
                $newarr = $word;
            }

        }
        if ($newarr)$op[] = $newarr;
        return $op;
    }
    
    
}

/**
  *  GoogleTTSHTML
  *  This class is used if you want to include ajax loading of mp3 files when loading HTML pages.
  *  What will happen is:
  *
  *  1. User vists your site. It will load the mp3 files to disk if not already exists.
  *  2. The user will get read up the text.
  *
  *
  *
  *
  **/
class GoogleTTSHTML extends GoogleTTS{
    private $jplayerloc='jPlayer/jquery.jplayer.js';
    private $hotkeyloc='jPlayer/jquery.hotkeys-0.7.9.min.js';
    private $jqueryLocation='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js';

    private $autoplay=true;

    /**
      * Sets the path to the jPlayer javasscript.
      *
      * Empty to include it yourself...
      */
    public function setJplayerLocation($s){
        $this->jplayerloc = $s;
        return true;
    }
    /**
      * Sets the path to the HotKey plugin!
      *
      * Empty to include it yourself...
      */
    public function setJqueryHotkeyLocation($s){
        $this->hotkeyloc = $s;
        return true;
    }
    
    /**
      * Autoplays if this is set to true, does not autoplay if false.
      * @param $bool Whenever to play the song when HTML page loads, or wait. True to play, false to not autoplay.
      *
      * Empty to include it yourself...
      */
    public function setAutoPlay($bool=true){
        $this->autoplay = $bool;
        return true;
    }
    /**
      * Sets the storage path, where this class saves and caches mp3 files.
      *
      * Empty to include it yourself...
      */
    public function setJqueryLocation($s){
        $this->jqueryLocation = $s;
        return true;
    }
    
    
    
    /**
      * getCoreScriptIncludes
      * Gets the javascript to print in your <head></head> element.
      * Returns javascript for includes and setups generic functions aswell as global javascript variables needed for the instance(s).
      * Tested Valid XHTML.
      *
      */
    public function getCoreScriptIncludes(){
        return '
            '.($this->jqueryLocation ? '<script src="'.$this->jqueryLocation.'" type="text/javascript"></script>' : '').'

            '.
                ($this->jplayerloc ? '
                    <script src="'.$this->jplayerloc.'" type="text/javascript"></script>
                ' : '')
            .'

        
            '.
                ($this->hotkeyloc ? '
                    <script src="'.$this->hotkeyloc.'" type="text/javascript"></script>
                ' : '')
            .'
        <script type="text/javascript">
        <!--
        var CURRENT_AUDIO_FOR_HTML_SITE=0;
        var SONGS_FOR_HTML_SITE = new Array();
        
        '.
            ($this->hotkeyloc ? '

            $(document).ready(function(){
              $(document).bind("keypress", "1", playListPrevHtmlGoogleTTS);
              $(document).bind("keypress", "2", playListNextHtmlGoogleTTS);
            });


            ' : '')
        .'

       	function playListNextHtmlGoogleTTS() {
              $("#jquery_jplayerHtmlGoogleTTS").jPlayer("setFile", SONGS_FOR_HTML_SITE[++CURRENT_AUDIO_FOR_HTML_SITE]).jPlayer("play");
       	}

       	function playListPrevHtmlGoogleTTS() {
              $("#jquery_jplayerHtmlGoogleTTS").jPlayer("setFile", SONGS_FOR_HTML_SITE[--CURRENT_AUDIO_FOR_HTML_SITE]).jPlayer("play");
       	}

        -->
        </script>
        ';
    }
    
    /**
      * helpSoundAtStart
      * Integrates help messages when a new page is reloaded, this will give user short instructions on how to use the sound system.
      *
      */
    public function helpSoundAtStart(){
        $this->setInput(array(
        'Press 2 - to go to the next soundtrack',
        'Press 1 - to go to the previous soundtrack'
        ));
    }


    /**
      * getJavaScript
      * Gets the javascript to print in your <head></head> element.
      * Returns javascript for this instance.
      * Can be run many times (one time per instance...)
      * Tested Valid XHTML.
      *
      */
    public function getJavaScript(){


        $mp3s = $this->getMP3s();
        $songs='';
        foreach ($mp3s as $line_num => $line)
        {
            $songs .= "SONGS_FOR_HTML_SITE.push(\"$line\" );\n"; // This line updates the script array with new entry
        }

        $ret = '

        <script type="text/javascript">
        <!--
        '.$songs.'


        $(document).ready(function(){


          $("#jquery_jplayerHtmlGoogleTTS").jPlayer({
            swfPath: "jPlayer",
            ready: function () {
        			'.($this->autoplay ? 'this.element.jPlayer("setFile", SONGS_FOR_HTML_SITE[CURRENT_AUDIO_FOR_HTML_SITE]).jPlayer("play");' : '').'


        		},
        		volume: 50
        	}).jPlayer("onSoundComplete", function() {
               if (CURRENT_AUDIO_FOR_HTML_SITE <= SONGS_FOR_HTML_SITE.length-2){
                   this.element.jPlayer("setFile", SONGS_FOR_HTML_SITE[++CURRENT_AUDIO_FOR_HTML_SITE]).jPlayer("play");

               }
        	});



        });

        -->
        </script>
        ';



        return $ret;
    }
    

    
    
    

    /**
      * getPlayerDiv
      * Gets the player div, this can be invisible. It is invisible by default!
      * Run one time (NOT one time per class instance)
      * Tested Valid XHTML.
      *
      */
    public function getPlayerDiv(){
        $ret = '
        <div id="jquery_jplayerHtmlGoogleTTS"></div>
        ';
        return $ret;
    }
}





?>
Return current item: Google Text To Speech