Seite 1 von 1
Konsole unterdrücken
Verfasst: Mittwoch 1. September 2010, 22:18
von raorao
Hoi mitenand!
Bin kurz vor der Fertigstellung einer Lernsoftware und wollte nun noch eine Sprachausgabe der Abfragen einbauen. Über die üblichen Microsoft Stimmen führt dies wie gewünscht zum Erfolg, allerdings sind diese recht unverständlich, deshalb habe ich mir eSpeak installiert, funktioniert deutlich verständlicher. Beim Versuch, eine Ausgabe via
Code: Alles auswählen
os.system("C:\\Programme\\eSpeak\\command_line\\espeak 'hello'")
zu erreichen, entsteht aber die Unschönheit, dass für kurze Zeit (nämlich während der gesamten Sprechzeit) ein schwarzes Konsolenfenster im Vordergrund sichtbar wird. Gibt es eine Möglichkeit, dieses zu unterdrücken oder aber einen ganz anderen Ansatz eSpeak zum sprechen zu zwingen?
Herzlichen Dank für eure Mithilfe!
raorao
Re: Konsole unterdrücken
Verfasst: Mittwoch 1. September 2010, 23:27
von Hyperion
Vergiss, dass es os.system() gibt und nutze das subprocess-Modul. Beispiele gibt es in der Doku (gaaanz unten) und auch zu Hauf hier im Forum
Vermutlich liegt das Konsolenfenster an diesem "espeak"-Tool. Ich denke nicht, dass man das unterdrücken kann.
Re: Konsole unterdrücken
Verfasst: Mittwoch 1. September 2010, 23:33
von fhoech
Das Konsolenfenster sollte sich mit dem startupinfo-Schlüsselwortargument unterdrücken lassen.
Code: Alles auswählen
import subprocess
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
subprocess.call(["C:\\Programme\\eSpeak\\command_line\\espeak", "hello"], startupinfo=startupinfo)
Re: Konsole unterdrücken
Verfasst: Donnerstag 2. September 2010, 00:43
von raorao
Suuuuuuper, herzlichen Dank! Funktioniert super, habe folgendes Modul geschrieben, welches bei Ausführung als __main__ die bessere der beiden installierten Varianten ausgibt. Der Pfad in der Klasse TTS_eSpeak muss natürlich je nach Speicherort und Betriebssystem angepasst werden.
Code: Alles auswählen
import sys, subprocess
sys.path.append(r"C:\Python26\Lib\site-packages\win32\lib")
sys.path.append(r"C:\Python26\Lib\site-packages\win32")
import win32com.client
class TTS_Sapi(object):
def __init__(self, text):
self.text = text
self.sprechen()
def sprechen(self):
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak(self.text)
class TTS_eSpeak(object):
def __init__(self, text):
self.text = text
self.sprechen()
def sprechen(self):
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
subprocess.call(["C:\\Programme\\eSpeak\\command_line\\espeak",\
"%s" % self.text], startupinfo=startupinfo)
if __name__ == "__main__":
try:
TTS_eSpeak("Speaking espeak")
except:
TTS_Sapi("Speaking Microsoft")
Re: Konsole unterdrücken
Verfasst: Donnerstag 2. September 2010, 08:38
von BlackJack
@raorao: Das ist aber heftiger Missbrauch von Klassen. Das wären doch einfach nur zwei einfache Funktionen, warum machst Du das so unnötig kompliziert!?
Re: Konsole unterdrücken
Verfasst: Donnerstag 2. September 2010, 09:16
von raorao
Na weil da jemand wohl deutlich zu wenig Ahnung von objektorientierter Programmierung hat...
Habs nun daher nochmals überarbeitet, danke:
Code: Alles auswählen
import sys, subprocess
sys.path.append(r"C:\Python26\Lib\site-packages\win32\lib")
sys.path.append(r"C:\Python26\Lib\site-packages\win32")
import win32com.client
def sapi(text):
speaker = win32com.client.Dispatch("SAPI.SpVoice")
speaker.Speak(text)
def espeak(text):
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
subprocess.call(["C:\\Programme\\eSpeak\\command_line\\espeak",\
"%s" % text], startupinfo=startupinfo)
if __name__ == "__main__":
try:
espeak("Speaking espeak")
except:
sapi("Speaking Microsoft")
Re: Konsole unterdrücken
Verfasst: Donnerstag 2. September 2010, 09:56
von cofi
Das blanke `except` solltest du mir der tatsaechlichen Exception erweitern, bei der du `sapi` noch nutzen kannst. Momentan wird das auch ausgefuehrt, wenn jemand `Ctrl-C` waehrend `espeak` drueckt oder wenn waehrend dessen bspw ein `MemoryError` passiert. Schlechte Idee.
Re: Konsole unterdrücken
Verfasst: Donnerstag 2. September 2010, 15:33
von micnic
Statt den Pfad zum Programm hart reinzuschreiben, könnte man auch versuchen, ihn aus der Registry auszulesen:
Code: Alles auswählen
import _winreg
...
root = _winreg.HKEY_LOCAL_MACHINE
hKey = _winreg.OpenKey (root, 'SOFTWARE\Microsoft\Speech\Voices\Tokens\eSpeak', 0, _winreg.KEY_READ)
program_path, _ = _winreg.QueryValueEx (hKey, 'Path')
Grüße,
micnic
Re: Konsole unterdrücken
Verfasst: Donnerstag 2. September 2010, 17:20
von Hyperion
fhoech hat geschrieben:Das Konsolenfenster sollte sich mit dem startupinfo-Schlüsselwortargument unterdrücken lassen.
Cool - war mir noch nicht bekannt. Wieder was gelernt

Re: Konsole unterdrücken
Verfasst: Freitag 3. September 2010, 23:16
von raorao
@micnic: Sehr interessante Lösung, funktioniert natürlich hervorragend. Soweit ich der Doku entnehmen konnte, funktioniert _winreg jedoch nur für Windows. Gibts dassselbe vielleicht sogar noch Plattformunabhängig?
@cofi: Danke, hab ich vergessen mittlerweile aber brav durch if os.path.isfile(pfad):... else: ersetzt, so gehts gleich ganz ohne try and error bzw. try and except...
Re: Konsole unterdrücken
Verfasst: Samstag 4. September 2010, 07:19
von BlackJack
@raorao: Ausnahmebehandlung wird einem Test in Python aber oft vorgezogen. Also Ausnahmen "brav" durch Tests ersetzen ist vielleicht gar nicht so brav.

Re: Konsole unterdrücken
Verfasst: Samstag 4. September 2010, 17:29
von Leonidas
raorao hat geschrieben:@micnic: Sehr interessante Lösung, funktioniert natürlich hervorragend. Soweit ich der Doku entnehmen konnte, funktioniert _winreg jedoch nur für Windows. Gibts dassselbe vielleicht sogar noch Plattformunabhängig?
Ähm, die anderen Platformen haben keine solche Registry, also nein, da es sowas eigentlich nur auf Windows gibt. Das was am nächsten da rankommt ist gconf unter GNOME, aber dort stehen keine Pfade zu Binaries drin, weil Binaries sinnigerweise direkt im $PATH auffindbar sind. Somit reicht es auf Unices einfach den Namen des Programms zu kennen um es aufzurufen.
Re: Konsole unterdrücken
Verfasst: Samstag 4. September 2010, 17:33
von DasIch
raorao hat geschrieben:@cofi: Danke, hab ich vergessen mittlerweile aber brav durch if os.path.isfile(pfad):... else: ersetzt, so gehts gleich ganz ohne try and error bzw. try and except...
Nein so geht es nicht ohne try und except. Nach dem os.path.isfile aufruf und bevor du die Datei aufrufst kann sie immer noch verschwinden oder du bekommst einfach keinen Zugriff darauf.