Ich möchte wissen, wie ich die Google Text-to-Speech-API in meinem .NET-Projekt verwenden kann. Ich denke, ich muss eine URL aufrufen, um den Webdienst zu nutzen, aber die Idee für mich ist nicht klar. Kann jemand helfen?
Ich möchte wissen, wie ich die Google Text-to-Speech-API in meinem .NET-Projekt verwenden kann. Ich denke, ich muss eine URL aufrufen, um den Webdienst zu nutzen, aber die Idee für mich ist nicht klar. Kann jemand helfen?
Antworten:
Alte Antwort:
Versuchen Sie es mit dieser URL: http://translate.google.com/translate_tts?tl=de&q=Hello%20World Es wird automatisch eine WAV-Datei generiert, die Sie mit einer HTTP-Anfrage über eine beliebige .net-Programmierung problemlos erhalten können.
Bearbeiten:
Ohh Google, Sie dachten, Sie könnten verhindern, dass Leute Ihren wunderbaren Service mit einer schwachen http-Header-Überprüfung nutzen.
Hier ist eine Lösung, um eine Antwort in mehreren Sprachen zu erhalten (ich werde versuchen, im Laufe der Zeit weitere hinzuzufügen):
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
Beachten Sie, dass die Header auf dem Beispiel von @Chris Cirefice basieren. Wenn sie irgendwann nicht mehr funktionieren, werde ich versuchen, die Bedingungen für die Funktionsweise dieses Codes neu zu erstellen. Alle Credits für die aktuellen Header gehen an ihn und das wunderbare Tool WireShark. (auch danke an Google, dass dies nicht gepatcht wurde)
In einem Update der Antwort von Schahriar SaffarShargh hat Google kürzlich eine Funktion zum Missbrauch von Google implementiert, die es unmöglich macht, nur ein normales altes HTTP-GET an eine URL wie die folgende zu senden:
http://translate.google.com/translate_tts?tl=de&q=Hello%20World
was vorher ganz gut und gut funktioniert hat. Wenn Sie nun einem solchen Link folgen, erhalten Sie ein CAPTCHA. Dies wirkt sich auch auf HTTP-GET-Anforderungen außerhalb des Browsers aus (z. B. bei cURL), da die Verwendung dieser URL eine Weiterleitung zur Missbrauchsschutzseite (CAPTCHA) ermöglicht.
Zu Beginn müssen Sie den Abfrageparameter client
zur Anforderungs-URL hinzufügen :
http://translate.google.com/translate_tts?tl=en&q=Hello%20World&client=t
Google Translate sendet &client=t
, also sollten Sie auch.
Stellen Sie vor dem Ausführen dieser HTTP-Anforderung sicher, dass Sie den Referer
Header festgelegt haben:
Referer: http://translate.google.com/
Offensichtlich ist der User-Agent
Header auch erforderlich, aber interessanterweise kann er leer sein:
User-Agent:
Bearbeiten : HINWEIS - Bei einigen Benutzeragenten, z. B. Android 4.X, wird der benutzerdefinierte User-Agent
Header nicht gesendet. Dies bedeutet, dass Google die Anforderung nicht bearbeitet . Um dieses Problem zu lösen, setze ich einfach das User-Agent
auf ein gültiges, wie z stagefright/1.2 (Linux;Android 5.0)
. Verwenden Sie Wireshark , um Anfragen zu debuggen (wie ich), wenn die Server von Google nicht antworten, und stellen Sie sicher, dass diese Header im GET
! Google antwortet mit einem, 503 Service Unavailable
wenn die Anfrage fehlschlägt, gefolgt von einer Weiterleitung zur CAPTCHA-Seite.
Diese Lösung ist etwas spröde; Es ist durchaus möglich, dass Google in Zukunft die Art und Weise ändert, in der diese Anfragen verarbeitet werden. Daher würde ich am Ende empfehlen, Google zu bitten, einen echten API-Endpunkt (kostenlos oder kostenpflichtig) zu erstellen, den wir verwenden können, ohne uns beim Fälschen von HTTP-Headern schmutzig zu fühlen.
Bearbeiten 2 : Für Interessenten sollte dieser cURL-Befehl einwandfrei funktionieren, um eine MP3-Datei von Hello in Englisch herunterzuladen :
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
Wie Sie vielleicht bemerken, habe ich sowohl die Referer
als auch die User-Agent
Header in der Anfrage gesetzt und den client=t
Parameter zum Querystring hinzugefügt. Sie können https
stattdessen http
Ihre Wahl verwenden!
Bearbeiten 3 : Google benötigt jetzt ein Token für jede GET-Anforderung (gekennzeichnet durch tk
im Querystring). Unten finden Sie den überarbeiteten Befehl cURL, mit dem ein TTS-MP3 korrekt heruntergeladen wird:
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
Beachten Sie das & tk = 995126.592330 im Querystring; Dies ist das neue Token. Ich habe dieses Token erhalten, indem ich das Lautsprechersymbol gedrückt translate.google.com
und die GET-Anfrage angesehen habe. Ich habe diesen Querystring-Parameter einfach zum vorherigen cURL-Befehl hinzugefügt, und er funktioniert.
HINWEIS : Offensichtlich ist diese Lösung sehr zerbrechlich und bricht nach Lust und Laune der Architekten bei Google ab, die neue Dinge wie Token einführen, die für die Anforderungen erforderlich sind. Dieses Token funktioniert möglicherweise morgen nicht (obwohl ich es überprüfen und zurückmelden werde). Der Punkt ist, dass es nicht ratsam ist, sich auf diese Methode zu verlassen. Stattdessen sollte man sich einer kommerziellen TTS-Lösung zuwenden, insbesondere wenn TTS in der Produktion verwendet wird.
Weitere Erklärungen zur Token-Generierung und was Sie möglicherweise dagegen tun können, finden Sie in der Antwort von Boude .
Wenn diese Lösung in Zukunft nicht mehr funktioniert, hinterlassen Sie bitte einen Kommentar zu dieser Antwort, damit wir versuchen können, eine Lösung dafür zu finden!
Referer
... Nun, ein zusätzlicher Header 'nur für den Fall' wird jetzt nicht schaden, oder;)
q=XXXX
und -Teile zu ersetzen tl=XX
(was bevorzugt wird). Beachten Sie, dass die gesamte Zeichenfolge URL-codiert sein muss , da sonst Leerzeichen in der Textabfrage zu Zeitüberschreitungen führen. So q=Hello world
muss codiert werden q=Hello%20world
.
Erweitern Sie Chris 'Antwort . Ich habe es geschafft, den Prozess der Token-Generierung zurückzuentwickeln.
Das Token für die Anforderung basiert auf dem Text und einer globalen TKK-Variablen, die im Seitenskript festgelegt sind. Diese werden in JavaScript gehasht, was zum tk-Parameter führt.
Irgendwo im Seitenskript finden Sie so etwas:
TKK='403413';
Dies ist die Anzahl der Stunden, die seit der Epoche vergangen sind.
Der Text wird in der folgenden Funktion gepumpt (etwas deobfuscated):
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);
Ich habe es geschafft, dies in meiner gTTS-Verzweigung erfolgreich auf Python zu portieren , daher weiß ich, dass dies funktioniert.
Bearbeiten: Inzwischen wurde der von gTTS verwendete Token-Generierungscode in gTTS-Token verschoben .
Bearbeiten 2: Google hat die API geändert (irgendwo um den 10.05.2016). Diese Methode erfordert einige Änderungen. Ich arbeite gerade daran. In der Zwischenzeit scheint es zu funktionieren, den Client auf tw-ob zu ändern.
Edit 3:
Die Änderungen sind geringfügig, aber gelinde gesagt ärgerlich. Das TKK besteht nun aus zwei Teilen. Sieht so etwas aus 406986.2817744745
. Wie Sie sehen, ist der erste Teil gleich geblieben. Der zweite Teil ist die Summe zweier scheinbar zufälliger Zahlen. TKK=eval('((function(){var a\x3d2680116022;var b\x3d137628723;return 406986+\x27.\x27+(a+b)})())');
Hier \x3d
bedeutet =
und \x27
ist '
. Sowohl a als auch b ändern sich jede UTC-Minute. Bei einem der letzten Schritte im Algorithmus wird das Token durch den zweiten Teil XOR-verknüpft.
Der neue Code zur Token-Generierung lautet:
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");
Natürlich kann ich keine gültige URL mehr generieren, da ich nicht weiß, wie a und b generiert werden.
Eine weitere Alternative ist: responsivevoice.org ein einfaches Beispiel JsFiddle is Here
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/ -->
});
});
Externe Ressource:
Sie können die Voice mit Wget: D herunterladen
wget -q -U Mozilla "http://translate.google.com/translate_tts?tl=en&q=Hello"
Speichern Sie die Ausgabe in einer MP3-Datei:
wget -q -U Mozilla "http://translate.google.com/translate_tts?tl=en&q=Hello" -O hello.mp3
Genießen !!
Also gut, Google hat Token eingeführt (siehe den Parameter tk in der neuen URL) und die alte Lösung scheint nicht zu funktionieren. Ich habe eine Alternative gefunden - die meiner Meinung nach besser klingt und mehr Stimmen hat! Der Befehl ist nicht schön, aber er funktioniert. Bitte beachten Sie, dass dies nur zu Testzwecken dient (ich verwende es für ein kleines Domotica-Projekt) und verwenden Sie die echte Version von acapella-group, wenn Sie diese kommerziell verwenden möchten.
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
Einige der unterstützten Stimmen sind;
Es unterstützt auch mehrere Sprachen und mehr Stimmen - dafür verweise ich Sie auf deren Website; http://www.acapela-group.com/
Ich habe dies wie folgt erstellt: q = Urlencode & tl = Sprachname
Versuchen Sie einfach Folgendes:
Google Text zu Sprache
<!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>
Verwenden Sie http://www.translate.google.com/translate_tts?tl=de&q=Hello%20World
Beachten Sie die www.translate.google.com
Der offizielle Text-to-Speech-Dienst von Google ist ab sofort unter https://cloud.google.com/text-to-speech/ verfügbar.
Es ist kostenlos für die ersten 4 Millionen Zeichen.
Ich habe die URL wie oben verwendet: http://translate.google.com/translate_tts?tl=de&q=Hello%20World
Und mit Python-Bibliothek angefordert .. wie auch immer ich bekomme HTTP 403 FORBIDDEN
Am Ende musste ich den User-Agent
Header mit dem des Browsers verspotten, um erfolgreich zu sein.
Gehen Sie zum console.developer.google.com
Login und holen Sie sich einen API-Schlüssel oder verwenden Sie die API von Microsoft Bing
https://msdn.microsoft.com/en-us/library/?f=255&MSPPError=-2147217396
oder noch besser die Sprach-API von AT & T developer.att.com
(kostenpflichtig)
für die Spracherkennung
Public Class Voice_recognition
Public Function convertTotext(ByVal path As String, ByVal output As String) As String
Dim request As HttpWebRequest = DirectCast(HttpWebRequest.Create("https://www.google.com/speech-api/v1/recognize?xjerr=1&client=speech2text&lang=en-US&maxresults=10"), HttpWebRequest)
'path = Application.StartupPath & "curinputtmp.mp3"
request.Timeout = 60000
request.Method = "POST"
request.KeepAlive = True
request.ContentType = "audio/x-flac; rate=8000"
request.UserAgent = "speech2text"
Dim fInfo As New FileInfo(path)
Dim numBytes As Long = fInfo.Length
Dim data As Byte()
Using fStream As New FileStream(path, FileMode.Open, FileAccess.Read)
data = New Byte(CInt(fStream.Length - 1)) {}
fStream.Read(data, 0, CInt(fStream.Length))
fStream.Close()
End Using
Using wrStream As Stream = request.GetRequestStream()
wrStream.Write(data, 0, data.Length)
End Using
Try
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
Dim resp = response.GetResponseStream()
If resp IsNot Nothing Then
Dim sr As New StreamReader(resp)
MessageBox.Show(sr.ReadToEnd())
resp.Close()
resp.Dispose()
End If
Catch ex As System.Exception
MessageBox.Show(ex.Message)
End Try
Return 0
End Function
End Class
Und für Text zu Sprache: Verwenden Sie diese .
Ich denke, Sie werden das verstehen,
wenn Sie dann nicht den Konverter vbscript to vb / C # verwenden.
habe mich dann immer noch nicht kontaktiert.
Ich habe das schon einmal gemacht, kann den Code jetzt nicht finden, deshalb gebe ich dir den Code nicht direkt.
Da es hier im Chat auftauchte und die erste Seite zum Googeln diese war, beschloss ich, meine Erkenntnisse über das Googeln von XD zu vertiefen
Sie müssen wirklich keine Länge mehr gehen, damit es funktioniert. Stellen Sie sich einfach auf die Schultern der Riesen:
https://dvcs.w3.org/hg/speech-api/raw-file/tip/webspeechapi.html
http://html5-examples.craic.com/google_chrome_text_to_speech.html
Zumindest für Ihre Webprojekte sollte dies funktionieren (zB asp.net)
#! /usr/bin/python2
# -*- coding: utf-8 -*-
def run(cmd):
import os
import sys
from subprocess import Popen, PIPE
print(cmd)
proc=Popen(cmd, stdin=None, stdout=PIPE, stderr=None, shell=True)
while True:
data = proc.stdout.readline() # Alternatively proc.stdout.read(1024)
if len(data) == 0:
print("Finished process")
break
sys.stdout.write(data)
import urllib
msg='Hello preety world'
msg=urllib.quote_plus(msg)
# -v verbosity
cmd='curl '+ \
'--output tts_responsivevoice.mp2 '+ \
"\""+'https://code.responsivevoice.org/develop/getvoice.php?t='+msg+'&tl=en-US&sv=g2&vn=&pitch=0.5&rate=0.5&vol=1'+"\""+ \
' -H '+"\""+'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0'+"\""+ \
' -H '+"\""+'Accept: audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5'+"\""+ \
' -H '+"\""+'Accept-Language: pl,en-US;q=0.7,en;q=0.3'+"\""+ \
' -H '+"\""+'Range: bytes=0-'+"\""+ \
' -H '+"\""+'Referer: http://code.responsivevoice.org/develop/examples/example2.html'+"\""+ \
' -H '+"\""+'Cookie: __cfduid=ac862i73b6a61bf50b66713fdb4d9f62c1454856476; _ga=GA1.2.2126195996.1454856480; _gat=1'+"\""+ \
' -H '+"\""+'Connection: keep-alive'+"\""+ \
''
print('***************************')
print(cmd)
print('***************************')
run(cmd)
Linie:
/getvoice.php?t='+msg+'&tl=en-US&sv=g2&vn=&pitch=0.5&rate=0.5&vol=1'+"\""+ \
ist verantwortlich für die Sprache.
tl=en-US
Es gibt eine weitere interessante Seite mit tts-Motoren, die auf diese Weise verwendet werden können.
Ersetzen Sie null durch null iv0na.c0m
Einen schönen Tag noch