Sprachausgabe per Google?

thorsten.gehrig

Mitglied
Mitglied seit
14 Jun 2004
Beiträge
490
Punkte für Reaktionen
0
Punkte
0
Hi,
ich bin heute - irgendwie - über die Google-Translate-Funktion gestolpert und habe dabei herausgefunden das die Sprachausgabe von Google ansich eine gute Ton/Sprachqualität bietet.
Man kann bei Google-Translate sich auch den un-übersetzen Text sich aussprechen lassen.
Beispiel: http://translate.google.de/translate_t?text=Garage+wird+geschlossen&sl=de&tl=de#
Einfach mal auf den Anhören klicken.

Meine Idee: könnte man das per Linux-Script mit Wunschtext starten und ein wav (o.ä.) zurückbekommen wäre das recht universell z.B. im AGI Einsetzbar.
(Bisher habe ich eine rießige Sammlung an WAV-Files...).

Leider bin ich unfähig die Sprachausgabe abzufangen und in ein .wav zu speichern...
Ist hier jemand der sowas hinkriegt???

Gruß
Thorsten


PS: auf meinem Windows Rechner funktioniert z.B.
http://translate.google.de/translate_tts?ie=UTF-8&q=Hallo Thorsten, wie geht es dir

In lynx kriege ich auch was:
lynx "http://translate.google.de/translate_tts?ie=UTF-8&q=Hallo%20Thorsten,%20wie%20geht%20es%20dir" -accept_all_cookies
... aber ich bin noch nicht da wo ich hin will...

Ich red mal mit mir selbst:
So gehts :)
wget "http://translate.google.de/translate_tts?ie=UTF-8&q=Dies ist eine Testausgabe" --keep-session-cookies --user-agent=sag_ich_nicht -O test22.mp3
jetzt muss ich das nur noch verfeinern :-D
 
Zuletzt bearbeitet:

himpierre

Mitglied
Mitglied seit
18 Apr 2007
Beiträge
316
Punkte für Reaktionen
0
Punkte
0
Hm. Eigentlich ganz schick. Müsste man mal ein agi ala swift.agi draus bauen.
 

thorsten.gehrig

Mitglied
Mitglied seit
14 Jun 2004
Beiträge
490
Punkte für Reaktionen
0
Punkte
0
Hi,
Was ist der swift.agi?
Ich hab das ganze nochmal im KNX (Hausautomatisierung) gepostet - weil ich es in diesem Zusammenhang einsetze. Link -> http://knx-user-forum.de/sonstiges-verwaltung-archiv/14410-sprachausgabe-per-google.html#post160489
Mittlerweile habe ich auch ein AGI - ich werf das hier mal kompakt rein:

Ich nutze das ganze für Durchsagen (Intercom) per asterisk-call-files - z.B.
Code:
Channel: SIP/buero
Callerid: Durchsage
Context: AnsagenTTS
Extension: Dies ist eine Test-Ansage.
RetryTime: 2
MaxRetries: 30
"SIP/buero" ist eine das Ausgabedevice,
"Dies ist eine Test-Ansage." ist der Text der Gesprochen werden soll

Der Asterisk-Kontext sieht so aus:
Code:
[AnsagenTTS]
exten => _.,1,noop(${EXTEN})
exten => _.,2,AGI(speech.agi,${EXTEN})
exten => _.,3,playback(${EXTEN})
exten => _.,4,hangup()
exten => _.,5,congestion()

exten => h,1,hangup()
und das speech.agi hat folgenden Inhalt:
Code:
#!/bin/sh
#

#pfad zum cachefile
CACHE="/var/spool/asterisk/speech-cache"

#pfad um das tempfile anzulegen
LOG="/var/log/asterisk/speech_log"

echo "Umwandlung: $1" >>$LOG

if [ -e "/var/spool/asterisk/speech-cache/$1.gsm" ]; then
    echo "Bereits vorhanden" >>$LOG
else
    echo "wget \"http://translate.google.de/translate_tts?ie=UTF-8&q=$1\" --keep-session-cookies --user-agent=sag_ich_nicht -O \"/var/spool/asterisk/speech-cache/$1.mp3\"" >>$LOG
    wget "http://translate.google.de/translate_tts?ie=UTF-8&q=$1" --keep-session-cookies --user-agent=sag_ich_nicht -O "/var/spool/asterisk/speech-cache/$1.mp3"
    echo "sox \"/var/spool/asterisk/speech-cache/$1.mp3\" -r 8000 -c 1 \"/var/spool/asterisk/speech-cache/$1.gsm\"" >>$LOG
    sox "/var/spool/asterisk/speech-cache/$1.mp3" -r 8000 -c 1 "/var/spool/asterisk/speech-cache/$1.gsm"
fi

echo "Setze Link" >>$LOG
ln -s "/var/spool/asterisk/speech-cache/$1.gsm" "/var/lib/asterisk/sounds/$1.gsm"
echo "==============================================" >>$LOG
echo 'SET VARIABLE SPEECH '"\"$1\"" >/dev/stdout
read in

exit 0
Soweit das "Framework".

Nur der Vollständigkeit halber: wenn ich Texte z.B. für ein Asterisk-IVR brauche (Sprachmenü - z.B. "Drücken Sie 1 für ...., 2 für...) mache ich das so:
Code:
exten => 123,n,AGI(speech.agi,'Es ist schon sehr spaet.')
exten => 123,n,playback(${SPEECH})
exten => 123,n,AGI(speech.agi,'Du solltest nun Feierabend machen.')
exten => 123,n,playback(${SPEECH})
Die Variable SPEECH habe ich vorher definiert - und wird vom AGI mit den sound-dateinamen gefüllt.

Gruß
Thorsten
 

Chatty

Aktives Mitglied
Mitglied seit
13 Mrz 2006
Beiträge
1,748
Punkte für Reaktionen
30
Punkte
48
Man, die Sprachsynthese klingt echt gut. Respekt.
 

himpierre

Mitglied
Mitglied seit
18 Apr 2007
Beiträge
316
Punkte für Reaktionen
0
Punkte
0
swift.agi=agi für die voices von cepstral

Und danke für speech.agi. Nette Spielerei.
 

chaos2000

Aktives Mitglied
Mitglied seit
22 Aug 2004
Beiträge
2,028
Punkte für Reaktionen
0
Punkte
36
hallo Thorsten,

sehr gute Lösung. Ich hab die noch mal angepasst, weil mir die Lösung mit dem symlink nicht so gut gefällt.
Im gleichen Atemzug habe ich noch die language mit eingebunden.

Code:
#!/bin/sh
#

#pfad zum cachefile
CACHE="/var/spool/asterisk/speech-cache"

#pfad um das tempfile anzulegen
LOG="/var/log/asterisk/speech_log"
TEXT=$1
LANGUAGE="de"
FILE=`echo "$1" | md5sum | awk '{ print $1}'`


# Consume all variables sent by Asterisk
while read -e ARG && [ "$ARG" ] ; do
	array=(` echo $ARG | sed -e 's/://'`)
	export ${array[0]}=${array[1]}
done

if [ -n "$agi_language" ] 
then
	echo "AGI Language: $agi_language" >>$LOG
	LANGUAGE=$agi_language
fi

echo "Umwandlung: $1" >>$LOG
FILE=`echo "${LANGUAGE}${TEXT}" | md5sum | awk '{ print $1}'`

if [ -e "$CACHE/$FILE.gsm" ]; then
    echo "Bereits vorhanden" >>$LOG
else
    #wget "http://translate.google.de/translate_tts?ie=UTF-8&q=${TEXT}&tl=$LANGUAGE" --keep-session-cookies --user-agent=sag_ich_nicht -O "$CACHE/$FILE.mp3"
    #sox "$CACHE/$FILE.mp3" -r 8000 -c 1 "$CACHE/$FILE.gsm"
    wget "http://translate.google.de/translate_tts?ie=UTF-8&q=${TEXT}&tl=$LANGUAGE" --keep-session-cookies --user-agent=sag_ich_nicht -O - | sox -t mp3 - -r 8000 -c 1 "$CACHE/$FILE.gsm" 
fi

#echo "Setze Link" >>$LOG
#ln -s "/var/spool/asterisk/speech-cache/$FILE.gsm" "/var/lib/asterisk/sounds/$FILE.gsm"
echo "==============================================" >>$LOG
#echo 'SET VARIABLE SPEECH '"\"$FILE\"" >/dev/stdout
echo 'SET VARIABLE SPEECH '"\"$CACHE/$FILE\"" >/dev/stdout
read in


exit 0
 

IEEE

Mitglied
Mitglied seit
23 Jul 2005
Beiträge
297
Punkte für Reaktionen
1
Punkte
18
Das funktioniert großartig. Vielen Dank.
 

blauerpeti

Mitglied
Mitglied seit
28 Jun 2005
Beiträge
723
Punkte für Reaktionen
0
Punkte
0
--2011-06-03 16:25:08-- http://translate.google.de/translate_tts?ie=UTF-8&q=
Auflösen des Hostnamen »translate.google.de«.... 209.85.148.113
Verbindungsaufbau zu translate.google.de|209.85.148.113|:80... verbunden.
HTTP Anforderung gesendet, warte auf Antwort... 404 Not Found
2011-06-03 16:25:08 FEHLER 404: Not Found.

sox soxio: Can't open input file `/var/spool/asterisk/speech-cache/.mp3': unknown file type `mp3'

Bekomme diese Fehlermeldung wenn ich das von Thorsten nehme. Was mach ich falsch
 

chaos2000

Aktives Mitglied
Mitglied seit
22 Aug 2004
Beiträge
2,028
Punkte für Reaktionen
0
Punkte
36
du solltest auch einen text eingeben
 

himpierre

Mitglied
Mitglied seit
18 Apr 2007
Beiträge
316
Punkte für Reaktionen
0
Punkte
0
Hola.

@chaos2000: Wo setzt Du denn die Variable $agi_language?

cheers
 

chaos2000

Aktives Mitglied
Mitglied seit
22 Aug 2004
Beiträge
2,028
Punkte für Reaktionen
0
Punkte
36
Ganz normal im Dialplan
Set(CHANNEL(language)=en)
 

thorsten.gehrig

Mitglied
Mitglied seit
14 Jun 2004
Beiträge
490
Punkte für Reaktionen
0
Punkte
0
Hi,
@Chaos: ja, die Symlink-implementierung ist geschmackssache. Ich brauche die Dateien auch außerhalb des Asterisk (für mein "Haus" - das Redet z.B. per Badradio (Squeezebox) mit mir. Danke fürs verhübschen meines QuickHacks :)

@Himpierre: dieses swift.agi habe ich nicht gefunden. Gibt es da eine bezahlbare Kauflösung - oder wird da auch die Website misbraucht?
Es könnte sein das es ende des Jahres Probleme mit der Google seite gibt. Wegen massiven "abuse" wird die Translate-API1 und API2 eingestellt..... (keine Ahnung ob das auch die Webseite & damit das Script beeinflusst)

Gruß
Thorsten
 

kokoloris

Neuer User
Mitglied seit
1 Mrz 2006
Beiträge
38
Punkte für Reaktionen
0
Punkte
0
Habe das nochmal anders per macro und bash-script mit einer cache-funktion implementiert...

bash-skript erstellen: /var/lib/asterisk/agi-bin/gtts
Code:
#!/bin/bash

FOLDER="/var/lib/asterisk/sounds/"
TL=$1
FILE=$2
TEXT=$3

if [ -f $FOLDER$TL/gtts/$FILE.wav ]
then
    echo testfile exists!
else
    wget -U Mozilla -O $FOLDER$TL/gtts/$FILE.mp3 "http://translate.google.com/translate_tts?tl=$TL&ie=UTF-8&q=$TEXT"
    madplay $FOLDER$TL/gtts/$FILE.mp3 -o $FOLDER$TL/gtts/$FILE.wav --mono -R 8000
    rm $FOLDER$TL/gtts/$FILE.mp3
fi
Ordner erstellen, madplay installieren und ggf. Rechte zuweisen:
Code:
mkdir /var/lib/asterisk/sounds/de/gtts
mkdir /var/lib/asterisk/sounds/en/gtts
apt-get install madplay
chmod 777 /var/lib/asterisk/agi-bin/gtts
macro erstellen und verwenden: extensions.ael
Code:
macro gtts(text) {
    Set(hash=${MD5(${text})});
    System(/var/lib/asterisk/agi-bin/gtts ${CHANNEL(language)} ${hash} "${text}");
    Playback(gtts/${hash});
    return;
}

context incoming {
  s=> {
    Answer();
    Wait(2);
    &gtts(Es funktioniert);
    Hangup();
  }
}
Viel Spaß damit!
 

himpierre

Mitglied
Mitglied seit
18 Apr 2007
Beiträge
316
Punkte für Reaktionen
0
Punkte
0
@Himpierre: dieses swift.agi habe ich nicht gefunden. Gibt es da eine bezahlbare Kauflösung - oder wird da auch die Website misbraucht?
swift.agi benutzt ganz normal eine installierte Cepstral Engine. Die ist nun aber nicht sooo teuer.

cheers
t.
 

SteffenBaier

Neuer User
Mitglied seit
13 Aug 2010
Beiträge
3
Punkte für Reaktionen
0
Punkte
0
Hi,

also wenn ich den Code von Thorsten hier verwende dann bekomme ich auf meine 1.6 Asterisk:

techlab-OptiPlex-320*CLI>
== Using SIP RTP CoS mark 5
== Using SIP VRTP CoS mark 6
-- Executing [[email protected]:1] AGI("SIP/3000-0000001c", "speech1.agi,'Es ist schon sehr spaet.'") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/speech1.agi
-- <SIP/3000-0000001c>AGI Script speech1.agi completed, returning 0
-- Executing [[email protected]:2] Playback("SIP/3000-0000001c", "'Es ist schon sehr spaet.'") in new stack
[Oct 20 16:47:15] WARNING[10571]: file.c:650 ast_openstream_full: File 'Es ist schon sehr spaet.' does not exist in any format
[Oct 20 16:47:15] WARNING[10571]: file.c:956 ast_streamfile: Unable to open 'Es ist schon sehr spaet.' (format 0x4 (ulaw)): No such file or directory
[Oct 20 16:47:15] WARNING[10571]: app_playback.c:471 playback_exec: ast_streamfile failed on SIP/3000-0000001c for 'Es ist schon sehr spaet.'
-- Executing [[email protected]:3] AGI("SIP/3000-0000001c", "speech1.agi,'Du solltest nun Feierabend machen.'") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/speech1.agi
-- <SIP/3000-0000001c>AGI Script speech1.agi completed, returning 0
-- Executing [[email protected]:4] Playback("SIP/3000-0000001c", "'Du solltest nun Feierabend machen.'") in new stack
[Oct 20 16:47:16] WARNING[10571]: file.c:650 ast_openstream_full: File 'Du solltest nun Feierabend machen.' does not exist in any format
[Oct 20 16:47:16] WARNING[10571]: file.c:956 ast_streamfile: Unable to open 'Du solltest nun Feierabend machen.' (format 0x4 (ulaw)): No such file or directory
[Oct 20 16:47:16] WARNING[10571]: app_playback.c:471 playback_exec: ast_streamfile failed on SIP/3000-0000001c for 'Du solltest nun Feierabend machen.'
-- Auto fallthrough, channel 'SIP/3000-0000001c' status is 'UNKNOWN'
die ,n option scheint bei meinem Asterisk nicht zu funktionieren. 123 ist bei mir schon fuer Zeitansage (UK) verwendet und das Thorsten agi habe ich speech1.agi genannt.

Muessen die exten => 123 Beispiele denn schon existieren oder sollte der Text an Goolge Translate uebergeben werden?

Mit Chaos2000 kommt:

== Using SIP RTP CoS mark 5
== Using SIP VRTP CoS mark 6
-- Executing [[email protected]:1] AGI("SIP/3000-0000001d", "speech.agi,'Es ist schon sehr spaet.'") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/speech.agi
-- <SIP/3000-0000001d>AGI Script speech.agi completed, returning 0
-- Executing [[email protected]:2] Playback("SIP/3000-0000001d", "") in new stack
[Oct 20 16:50:15] WARNING[10579]: app_playback.c:433 playback_exec: Playback requires an argument (filename)
== Spawn extension (local, 121, 2) exited non-zero on 'SIP/3000-0000001d'
hatte die gleiche exten => 123,n,AGI(speech.agi,'Es ist schon sehr spaet.') als Beispiel verwendet ...

Mit Kokoloris war ich mir nicht sicher ob ich das gezeigte Macro ans ende der /etc/asterisk/extensions.ael hinzufuegen sollte und wie ich es dann ueberhaupt in den Dialplan (extensions.conf) einbinde.

Ich hatte es aber manuell umgepflueckt um das Bash Script einfach mit meinem Text aufzurufen und dann wenigstens via WGET die wav file bekomme.

Danke

Steff
 

chaos2000

Aktives Mitglied
Mitglied seit
22 Aug 2004
Beiträge
2,028
Punkte für Reaktionen
0
Punkte
36
und wie hast du das file abgespielt?
 

SteffenBaier

Neuer User
Mitglied seit
13 Aug 2010
Beiträge
3
Punkte für Reaktionen
0
Punkte
0
@Chaos2000

via
Code:
exten => 123,n,AGI(speech.agi,'Es ist schon sehr spaet.')
exten => 123,n,playback(${SPEECH})
Ich dachte ich kann das original konzept anwenden ..
 

chaos2000

Aktives Mitglied
Mitglied seit
22 Aug 2004
Beiträge
2,028
Punkte für Reaktionen
0
Punkte
36
das ist richtig, dann solltest du mal schaun ob das script funktioniert
 

SteffenBaier

Neuer User
Mitglied seit
13 Aug 2010
Beiträge
3
Punkte für Reaktionen
0
Punkte
0
@Chaos,

sollte ich das speech.agi via eines Argumentes aufrufen koennen ?

z.B.:
Code:
./speech.agi test
./speech.agi: 16: Syntax error: "(" unexpected (expecting "done")
Koennte einer von euch eventuell deren Agi mal als Anhang dran haengen?

Danke

Steffen
 

Chatty

Aktives Mitglied
Mitglied seit
13 Mrz 2006
Beiträge
1,748
Punkte für Reaktionen
30
Punkte
48
Hat jemand schon mal eine "dictate_and_control.agi" untersucht? Immerhin bietet Google ja auch eine mächtige Spracherkennungs-API an, die dann ähnlich wie unter Android funktionieren könnte ("Rufe meine Tante mobil an!", "Soll Frieda Schmid auf dem Handy angerufen werden?", "Ja! Verdammt nochmal!", "Tuuut.").