Google Text-To-Speech API - PullRequest
       88

Google Text-To-Speech API

70 голосов
/ 27 марта 2012

Я хочу знать, как я могу использовать Google Text-to-Speech API в моем проекте .NET.Я думаю, что мне нужно позвонить по URL, чтобы использовать веб-сервис, но идея для меня не ясна.Кто-нибудь может помочь?

Ответы [ 14 ]

60 голосов
/ 07 апреля 2012

Старый ответ:

Попробуйте использовать этот URL: http://translate.google.com/translate_tts?tl=en&q=Hello%20World Он автоматически сгенерирует wav-файл, который вы можете легко получить с помощью HTTP-запроса через любое .net-программирование.

Редактировать:

Ооо, Google, вы думали, что могли бы запретить людям использовать ваш замечательный сервис с хрупкой проверкой заголовка http.

Вот решение, чтобы получить ответ внесколько языков (я постараюсь добавить больше по ходу дела):

NodeJS

// npm install `request`
const fs = require('fs');
const request = require('request');
const text = 'Hello World';

const options = {
    url: `https://translate.google.com/translate_tts?ie=UTF-8&q=${encodeURIComponent(text)}&tl=en&client=tw-ob`,
    headers: {
        'Referer': 'http://translate.google.com/',
        'User-Agent': 'stagefright/1.2 (Linux;Android 5.0)'
    }
}

request(options)
    .pipe(fs.createWriteStream('tts.mp3'))

Curl

curl 'https://translate.google.com/translate_tts?ie=UTF-8&q=Hello%20Everyone&tl=en&client=tw-ob' -H 'Referer: http://translate.google.com/' -H 'User-Agent: stagefright/1.2 (Linux;Android 5.0)' > google_tts.mp3

Обратите внимание, что заголовки основаны на примере @Chris Cirefice, если в какой-то момент они перестанут работать, я попытаюсь воссоздать условия для работы этого кода.Все кредиты за текущие заголовки идут к нему и замечательному инструменту WireShark.(также спасибо Google за то, что не исправили это)

46 голосов
/ 03 августа 2015

В обновлении до Ответ Schahriar SaffarShargh , Google недавно внедрила функцию «злоупотребления Google», что делает невозможным отправку любого обычного старого HTTP GET на URL, такой как:

http://translate.google.com/translate_tts?tl=en&q=Hello%20World

, которая раньше работала просто отлично.Теперь, перейдя по такой ссылке, вы получите CAPTCHA.Это также влияет на запросы HTTP GET вне браузера (например, с помощью cURL), поскольку использование этого URL дает перенаправление на страницу защиты от злоупотреблений (CAPTCHA).

Для начала необходимо добавить запросПараметр client на URL запроса:

http://translate.google.com/translate_tts?tl=en&q=Hello%20World&client=t

Переводчик Google отправляет &client=t, так что вы тоже должны.

Перед выполнением этого запроса HTTP сделайтеубедитесь, что вы установили заголовок Referer:

Referer: http://translate.google.com/

Очевидно, заголовок User-Agent также необходим, но, что интересно, он может быть пустым:

User-Agent:

Редактировать : NOTE - на некоторых пользовательских агентах, таких как Android 4.X, custom *Заголовок 1038 * User-Agent равен не отправлено , что означает, что Google не будет обслуживать запрос.Чтобы решить эту проблему, я просто установил User-Agent на правильный, такой как stagefright/1.2 (Linux;Android 5.0).Используйте Wireshark для отладки запросов (как я сделал), если серверы Google не отвечают, и убедитесь, что эти заголовки установлены правильно в GET!В случае сбоя запроса Google ответит 503 Service Unavailable, после чего будет перенаправлено на страницу CAPTCHA.

Это решение немного хрупкое;Вполне возможно, что Google в будущем изменит способ обработки этих запросов, поэтому в конце я бы предложил попросить Google создать конечную точку API real (бесплатную или платную), которую мы могли бы использовать, не чувствуягрязный из-за фальсификации заголовков HTTP.


Edit 2 : Для тех, кому интересно, эта команда cURL должна прекрасно работать для загрузки mp3 Hello на английском языке:

curl 'http://translate.google.com/translate_tts?ie=UTF-8&q=Hello&tl=en&client=t' -H 'Referer: http://translate.google.com/' -H 'User-Agent: stagefright/1.2 (Linux;Android 5.0)' > google_tts.mp3

Как вы можете заметить, в запросе я установил заголовки Referer и User-Agent, а также добавил параметр client=t в строку запроса.Вы можете использовать https вместо http, ваш выбор!


Редактировать 3 : Google теперь требует токен для каждого запроса GET (отмечен tk вСтрока запроса).Ниже приведена исправленная команда cURL, которая будет правильно загружать TTS mp3:

curl 'https://translate.google.com/translate_tts?ie=UTF-8&q=hello&tl=en&tk=995126.592330&client=t' -H 'user-agent: stagefright/1.2 (Linux;Android 5.0)' -H 'referer: https://translate.google.com/' > google_tts.mp3

Обратите внимание на & tk = 995126.592330 в строке запроса;это новый токен.Я получил этот токен, нажав значок динамика на translate.google.com и посмотрев запрос GET.Я просто добавил этот параметр строки запроса к предыдущей команде cURL, и он работает.

NOTE : очевидно, что это решение очень слабое и нарушает прихотьархитекторы Google, которые представляют новые вещи, такие как токены, необходимые для запросов.Этот токен может не сработать завтра (хотя я проверю и сообщу) ... дело в том, что не стоит полагаться на этот метод;вместо этого следует обратиться к коммерческому решению TTS, особенно если вы используете TTS в производстве.

Для получения дополнительной информации о генерации токенов и возможных действиях см. Ответ Боуде .


Если это решение не работает в любое время, пожалуйста, оставьте комментарий к этому ответу, чтобы мы могли попытаться найти исправление для него!

17 голосов
/ 09 января 2016

Расширение на Ответ Криса .Мне удалось выполнить обратный инжиниринг процесса генерации токена.

Токен для запроса основан на тексте и глобальной переменной TKK, заданной в скрипте страницы.Они хэшируются в JavaScript, что приводит к параметру tk.

Где-то в скрипте страницы вы найдете что-то вроде этого:

TKK='403413';

Это суммачасов, прошедших с начала эпохи.

Текст прокачивается в следующей функции (несколько лишенной размышлений):

var query = "Hello person";
var cM = function(a) {
    return function() {
        return a
    }
};
var of = "=";
var dM = function(a, b) {
    for (var c = 0; c < b.length - 2; c += 3) {
        var d = b.charAt(c + 2),
            d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
            d = b.charAt(c + 1) == Tb ? a >>> d : a << d;
        a = b.charAt(c) == Tb ? a + d & 4294967295 : a ^ d
    }
    return a
};

var eM = null;
var cb = 0;
var k = "";
var Vb = "+-a^+6";
var Ub = "+-3^+b+-f";
var t = "a";
var Tb = "+";
var dd = ".";
var hoursBetween = Math.floor(Date.now() / 3600000);
window.TKK = hoursBetween.toString();

fM = function(a) {
    var b;
    if (null === eM) {
        var c = cM(String.fromCharCode(84)); // char 84 is T
        b = cM(String.fromCharCode(75)); // char 75 is K
        c = [c(), c()];
        c[1] = b();
        // So basically we're getting window.TKK
        eM = Number(window[c.join(b())]) || 0
    }
    b = eM;

    // This piece of code is used to convert d into the utf-8 encoding of a
    var d = cM(String.fromCharCode(116)),
        c = cM(String.fromCharCode(107)),
        d = [d(), d()];
    d[1] = c();
    for (var c = cb + d.join(k) +
            of, d = [], e = 0, f = 0; f < a.length; f++) {
        var g = a.charCodeAt(f);

        128 > g ? d[e++] = g : (2048 > g ? d[e++] = g >> 6 | 192 : (55296 == (g & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ? (g = 65536 + ((g & 1023) << 10) + (a.charCodeAt(++f) & 1023), d[e++] = g >> 18 | 240, d[e++] = g >> 12 & 63 | 128) : d[e++] = g >> 12 | 224, d[e++] = g >> 6 & 63 | 128), d[e++] = g & 63 | 128)
    }


    a = b || 0;
    for (e = 0; e < d.length; e++) a += d[e], a = dM(a, Vb);
    a = dM(a, Ub);
    0 > a && (a = (a & 2147483647) + 2147483648);
    a %= 1E6;
    return a.toString() + dd + (a ^ b)
};

var token = fM(query);
var url = "https://translate.google.com/translate_tts?ie=UTF-8&q="  + encodeURI(query) + "&tl=en&total=1&idx=0&textlen=12&tk=" + token + "&client=t";
document.write(url);

Мне удалось успешно перенести это на python в моей форке gTTS , поэтому я знаю, что это работает.

Редактировать: К настоящему времени код генерации токенов, используемый gTTS, был перемещен в gTTS-токен .

Редактировать 2: Google изменил API (где-то в 2016-05-10), этот метод требует некоторой модификации.Я сейчас работаю над этим. Между тем, похоже, что смена клиента на tw-ob работает.

Редактировать 3:

Изменения незначительны, но, по меньшей мере, раздражают.ТКК теперь состоит из двух частей.Выглядит примерно как 406986.2817744745.Как видите, первая часть осталась прежней.Вторая часть представляет собой сумму двух, казалось бы, случайных чисел.TKK=eval('((function(){var a\x3d2680116022;var b\x3d137628723;return 406986+\x27.\x27+(a+b)})())'); Здесь \x3d означает =, а \x27 равно '.И a, и b меняются каждую минуту UTC.На одном из последних шагов в алгоритме токен XORed второй частью.

Новый код генерации токена:

var xr = function(a) {
    return function() {
        return a
    }
};
var yr = function(a, b) {
    for (var c = 0; c < b.length - 2; c += 3) {
        var d = b.charAt(c + 2)
          , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d)
          , d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
        a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
    }
    return a
};
var zr = null;
var Ar = function(a) {
    var b;
    if (null  !== zr)
        b = zr;
    else {
        b = xr(String.fromCharCode(84));
        var c = xr(String.fromCharCode(75));
        b = [b(), b()];
        b[1] = c();
        b = (zr = window[b.join(c())] || "") || ""
    }
    var d = xr(String.fromCharCode(116))
      , c = xr(String.fromCharCode(107))
      , d = [d(), d()];
    d[1] = c();
    c = "&" + d.join("") + 
    "=";
    d = b.split(".");
    b = Number(d[0]) || 0;
    for (var e = [], f = 0, g = 0; g < a.length; g++) {
        var l = a.charCodeAt(g);
        128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
        e[f++] = l >> 18 | 240,
        e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
        e[f++] = l >> 6 & 63 | 128),
        e[f++] = l & 63 | 128)
    }
    a = b;
    for (f = 0; f < e.length; f++)
        a += e[f],
        a = yr(a, "+-a^+6");
    a = yr(a, "+-3^+b+-f");
    a ^= Number(d[1]) || 0;
    0 > a && (a = (a & 2147483647) + 2147483648);
    a %= 1E6;
    return c + (a.toString() + "." + (a ^ b))
}
;
Ar("test");

Конечно, я больше не могу генерировать действительный URL, так как я не знаю, как генерируются a и b.

12 голосов
/ 08 января 2016

Дополнительная альтернатива: responseivevoice.org простой пример JsFiddle: Здесь

HTML

<div id="container">
<input type="text" name="text">
<button id="gspeech" class="say">Say It</button>
<audio id="player1" src="" class="speech" hidden></audio>
</div>

JQuery

$(document).ready(function(){

 $('#gspeech').on('click', function(){

        var text = $('input[name="text"]').val();
        responsiveVoice.speak("" + text +"");
        <!--  http://responsivevoice.org/ -->
    });

});

Внешний ресурс:

https://code.responsivevoice.org/responsivevoice.js

4 голосов
/ 30 декабря 2015

Хорошо, поэтому Google ввел токены (см. Параметр tk в новом URL), и старое решение, похоже, не работает. Я нашел альтернативу - которая, я думаю, звучит лучше и имеет больше голосов! Команда не красивая, но она работает. Обратите внимание, что это только для целей тестирования (я использую его для небольшого проекта по домотике) и реальную версию от acapella-group, если вы планируете использовать это в коммерческих целях.

curl $(curl --data 'MyLanguages=sonid10&MySelectedVoice=Sharon&MyTextForTTS=Hello%20World&t=1&SendToVaaS=' 'http://www.acapela-group.com/demo-tts/DemoHTML5Form_V2.php' | grep -o "http.*mp3") > tts_output.mp3

Некоторые из поддерживаемых голосов:

  • Шарон
  • Элла (настоящий детский голос)
  • EmilioEnglish (настоящий детский голос)
  • Джош (подлинный детский голос)
  • Karen
  • Кенни (искусственный детский голос)
  • Laura
  • Миха
  • Nelly (искусственный детский голос)
  • Rod
  • Ryan
  • Saul
  • Скотт (подлинный голос подростка)
  • Tracy
  • ValeriaEnglish (подлинный детский голос)
  • Будет
  • WillBadGuy (эмоциональный голос)
  • WillFromAfar (эмоциональный голос)
  • WillHappy (эмоциональный голос)
  • WillLittleCreature (эмоциональный голос)
  • WillOldMan (эмоциональный голос)
  • WillSad (эмоциональный голос)
  • WillUpClose (эмоциональный голос)

Он также поддерживает несколько языков и больше голосов - для этого я отсылаю вас на их сайт; http://www.acapela -group.com /

4 голосов
/ 28 апреля 2015

Google текст в речь

<!DOCTYPE html>
<html>
    <head>
        <script>
            function play(id){
            var text = document.getElementById(id).value;
            var url = 'http://translate.google.com/translate_tts?tl=en&q='+text;
            var a = new Audio(url);
                a.play();
            }
        </script>
    </head>
    <body>
        <input type="text" id="text" />
        <button onclick="play('text');"> Speak it </button>
    </body>
</html>
4 голосов
/ 16 ноября 2014

Вы можете загрузить Голос, используя Wget: D

wget -q -U Mozilla "http://translate.google.com/translate_tts?tl=en&q=Hello"

Сохранить вывод в файл mp3:

wget -q -U Mozilla "http://translate.google.com/translate_tts?tl=en&q=Hello" -O hello.mp3

Наслаждайтесь !!

3 голосов
/ 09 мая 2018
2 голосов
/ 28 марта 2018

На данный момент официальный сервис Google Text-to-Speech доступен по номеру https://cloud.google.com/text-to-speech/

Бесплатно для первых 4 миллионов символов.

2 голосов
/ 01 марта 2013

Использование http://www.translate.google.com/translate_tts?tl=en&q=Hello%20World

обратите внимание на www.translate.google.com

...