Search code examples
phpapitext-to-speechgoogle-text-to-speech

Google Text to speech API returns mp3 file with no sound


I tried to convert text into an mp3 file using the Google translate API, but something must be wrong because the mp3 file doesn't have any sound.

I opened the MP3 file with Notepad, and this was the result:

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://ipv4.google.com/sorry/index? 
continue=http://translate.google.com/translate_tts%3Fie%3DUTF-8%26q%3DOra%2BAscolteremo%253A%2BPovia%2Bin%2BSiamo%2BItaliani%26tl%3Den%26total%3D6%26idx%3D0%26textlen%3D40&amp;q=EgRXCPWrGMKjydYFIhkA8aeDS8BgGC4RXqJ61WyJio4ttFxmZp7GMgFy">here
</A>.
</BODY></HTML>

It looks like an error output from the API, but i couldn't figure out what was the problem.

This is my code:

HTML:

<html lang="en">
<head>
</head>
 <body>
     <div class="container">
        <form action="upload.php" method="post" enctype="multipart/form-data">
        <input type="file"  accept=".mp3,audio/*" name="uploadMP3" multiple >
        <input type="submit" name="conferma">
        </form>

    </div>
</body>

PHP:

 <?php
 include $_SERVER['DOCUMENT_ROOT'].'/Text-to-speech/text2Speech.class.php'; 
 $t2s = new PHP_Text2Speech;

 $string="Helllo";
 echo $t2s->speak($string);

 ?>

This is the text to speech class:

class PHP_Text2Speech {
/** Max text characters
 */
var $maxStrLen = 100;
/** Text len
 */
var $textLen = 0;
/** No of words
 */
var $wordCount = 0;
/** Language of text (ISO 639-1)
 */
var $lang = 'en';
/** Text to speak
 */
var $text = NULL;
/** File name format
 */
var $mp3File = "%s.mp3";
/** Directory to store audio file
 */
var $audioDir = "audio/";
/** Contents
*/
var $contents = NULL;
/** Function make request to Google translate, download file and returns audio file path
 */
function speak($text, $lang = NULL) {

    if ($lang !== NULL) {
        $this->lang = $lang;
    }

    // Create dir if not exists
    if (!is_dir($this->audioDir)) {
        mkdir($this->audioDir, 0755) or die('Could not create audio dir: ' . $this->audioDir);
    }

    // Try to set writing permissions for audio dir.
    if (!is_writable($this->audioDir)) { 
        chmod($this->audioDir, 0755) or die('Could not set appropriate permissions for audio dir: ' . $this->audioDir);
    }

    // Can not handle more than 100 characters so split text
    if (strlen($text) > $this->maxStrLen) {
        $this->text = $text;
        // Generate unique mp3 file name
        $file = sprintf($this->mp3File, $this->audioDir . md5($this->text));
        if (!file_exists($file)) {
            $texts = array();
            $words = explode(' ', $this->text);
            $i = 0;
            $texts[$i] = NULL;
            foreach ($words as $w) {
                $w = trim($w);
                if (strlen($texts[$i] . ' ' . $w) < $this->maxStrLen) {
                    $texts[$i] = $texts[$i] . ' ' . $w; 
                } else {
                    $texts[++$i] = $w;
                }
            }

            // Get get separated files contents and marge them into one
            foreach ($texts as $txt) {
                $pFile = $this->speak($txt, $this->lang);
                $this->contents .= $this->stripTags(file_get_contents($pFile));
                unlink($pFile);
            }
            unset($words, $texts);

            // Save file
            file_put_contents($file, $this->contents);
            $this->contents = NULL;
        }
    } else {

        // Generate unique mp3 file name
        $file = sprintf($this->mp3File, $this->audioDir . md5($text));

        if (!file_exists($file)) {
            // Text lenght
            $this->textLen = strlen($text);

            // Words count
            $this->wordCount = str_word_count($text);

            // Encode string
            $text = urlencode($text);

            // Download new file 
            //$this->download("http://translate.google.com/translate_tts?q=".$text);
            $this->download("http://translate.google.com/translate_tts?ie=UTF-8&q={$text}&tl={$this->lang}&total={$this->wordCount}&idx=0&textlen={$this->textLen}", $file);

        }
    }

    // Returns mp3 file path
    return $file;
}

/** Function to download and save file
 * @param   String  $url        - URL
 * @param   String  $path       - Local path
 */ 
function download($url, $path) { 
    // Is curl installed?
    if (!function_exists('curl_init')) { // use file get contents 
        $output = file_get_contents($url); 
    } else { // use curl 
        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_URL, $url); 
        curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE); 
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1"); 
        curl_setopt($ch, CURLOPT_HEADER, 0); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
        curl_setopt($ch, CURLOPT_TIMEOUT, 10); 
        $output = curl_exec($ch); 
        curl_close($ch); 
    }
    // Save file
    file_put_contents($path, $output);
}
}

Solution

  • If you open the URL in the browser you'll see the Google blocked you for unauthorized activity. Maybe you used the service too extensively.

    Overall translate API is not supposed to be used for text to speech. It was a hack that worked many years but it is not guaranteed to work. Now Google introduced official paid text to speech API, you would better use it instead.