[Patch] text2speech: Funktion zur Umwandlung ohne Audio-Ausgabe

Begonnen von prodigy7, 14 Januar 2018, 16:16:17

Vorheriges Thema - Nächstes Thema

prodigy7

Hallo zusammen,

im Zusammenhang mit dem Modul 96_SIP verwende ich TTS um Text zur Ausgabe zu erzeugen. Soweit, so nett, mir fehlte aber die Möglichkeit Text in Audio umzuwandeln ohne dass eine Ausgabe erfolgt. Ich habe eine Fuktion "ttsFile" implementiert, die genau das macht:

--- 98_Text2Speech.pm.bak       2017-05-20 10:45:19.000000000 +0200
+++ 98_Text2Speech.pm   2018-01-14 16:13:41.676901884 +0100
@@ -35,6 +35,7 @@
# SetParamName -> Anzahl Paramter
my %sets = (
   "tts"    => "1",
+  "ttsFile"    => "1",
   "volume" => "1"
);

@@ -219,6 +220,7 @@
   BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));
   delete($hash->{helper}{RUNNING_PID});

+  $hash->{PLAY} = 1;
   $hash->{STATE} = "Initialized";

   return undef;
@@ -447,7 +449,7 @@
     return $r;
   }

-  if($cmd ne "tts") {
+  if($cmd ne "tts" && $cmd ne "ttsFile") {
     return "$cmd needs $sets{$cmd} parameter(s)" if(@a-$sets{$cmd} != 0);
   }

@@ -459,6 +461,16 @@
     if($hash->{MODE} eq "DIRECT" || $hash->{MODE} eq "SERVER") {
       readingsSingleUpdate($hash, "playing", "1", 1);
       Text2Speech_PrepareSpeech($hash, join(" ", @a));
+      $hash->{helper}{PLAY} = 1;
+      $hash->{helper}{RUNNING_PID} = BlockingCall("Text2Speech_DoIt", $hash, "Text2Speech_Done", $TTS_TimeOut, "Text2Speech_AbortFn", $hash) unless(exists($hash->{helper}{RUNNING_PID}));
+    } elsif ($hash->{MODE} eq "REMOTE") {
+      Text2Speech_Write($hash, "tts " . join(" ", @a));
+    } else {return undef;}
+  } elsif($cmd eq "ttsFile") {
+    if($hash->{MODE} eq "DIRECT" || $hash->{MODE} eq "SERVER") {
+      readingsSingleUpdate($hash, "playing", "1", 1);
+      Text2Speech_PrepareSpeech($hash, join(" ", @a));
+      $hash->{helper}{PLAY} = 0;
       $hash->{helper}{RUNNING_PID} = BlockingCall("Text2Speech_DoIt", $hash, "Text2Speech_Done", $TTS_TimeOut, "Text2Speech_AbortFn", $hash) unless(exists($hash->{helper}{RUNNING_PID}));
     } elsif ($hash->{MODE} eq "REMOTE") {
       Text2Speech_Write($hash, "tts " . join(" ", @a));
@@ -902,11 +914,15 @@
   if(-e $file && $hash->{MODE} ne "SERVER") {
     # Datei existiert jetzt
     # im Falls Server, nicht die Datei abspielen
-    $cmd = Text2Speech_BuildMplayerCmdString($hash, $file);
-    $cmd .= " >/dev/null" if($verbose < 5);
+    if($hash->{helper}{PLAY}) {
+      $cmd = Text2Speech_BuildMplayerCmdString($hash, $file);
+      $cmd .= " >/dev/null" if($verbose < 5);

-    Log3 $hash->{NAME}, 4, "Text2Speech:" .$cmd;
-    system($cmd);
+      Log3 $hash->{NAME}, 4, "Text2Speech:" .$cmd;
+      system($cmd);
+    } else {
+      Log3 $hash->{NAME}, 4, "Text2Speech: Nur erzeugen, nicht abspielen";
+    }
   }

   return $hash->{NAME}. "|".
@@ -919,6 +935,7 @@
# param1: HashName
# param2: Anzahl der abgearbeiteten Textbausteine
# param3: Dateiname der abgespielt wurde
+# param4: Gibt an, ob die Datei abgespielt werden soll
####################################################
sub Text2Speech_Done($) {
   my ($string) = @_;
@@ -1083,6 +1100,9 @@
     The files must save under the directory of given <i>TTS_FileTemplateDir</i>.
     Please note: The text doesn´t have any colons itself.
   </li>
+  <li><b>ttsFile</b>:<br>
+    Same as the function <i>tts</i> but will not playing resulting file.
+  </li>
   <li><b>volume</b>:<br>
     Setting up the volume audio response.<br>
     Notice: Only available in locally instances!
@@ -1302,6 +1322,9 @@
     und schließenden Doppelpunkten angegebenen sein. Die MP3-Dateien müssen unterhalb des Verzeichnisses <i>TTS_FileTemplateDir</i> gespeichert sein.<br>
     Der Text selbst darf deshalb selbst keine Doppelpunte beinhalten. Siehe Beispiele.
   </li>
+  <li><b>tts</b>:<br>
+    Das gleiche wie die Funktion <i>tts</i> aber spielt die erzeuge Datei nicht ab.
+  </li>
   <li><b>volume</b>:<br>
     Setzen der Ausgabe Lautst&auml;rke.<br>
     Achtung: Nur bei einem lokal definierter Text2Speech Instanz m&ouml;glich!

Würde mich über Aufnahme des Patches freuen!

Grüße, prodigy7

Wzut

define <name> Text2Speech none ist dein Freund, so wird heute keine Audioausgabe erzeugt und das gewandelte Audiofile steht im Reading lastFilename.
BTW: falscher Forenbereich , TTS gehört laut command.ref unter "Unterstuetzende Dienste"  -> https://forum.fhem.de/index.php/board,44.0.html
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

prodigy7

Gut, könnte man sich jetzt drüber streiten, ob man ein eigenes Device eigens nur dafür anlegt, Ausgaben zu erzeugen die nicht ausgegeben werden oder nicht. Ich verwende bereits ein text2speech Device zur Ausgabe auf am RPi angeschlossenen Lautsprechern und ich persönlich sehe es aktuell eigentlich sinnvoller an, das Device mitzuverwenden statt ein neues anzulegen.
Bin aber nicht den passenden Argumenten verschlossen, die dafür sprechen würden ein neues Device anzulegen wenn du die hast.

Wzut

Zitat von: prodigy7 am 14 Januar 2018, 19:29:08
Bin aber nicht den passenden Argumenten verschlossen, die dafür sprechen würden ein neues Device anzulegen wenn du die hast.
Das liegt nicht in meiner Hand, Tobias hat damals als Maintainer von TTS diese Entscheidung so getroffen. D.h. ich musste das verwenden was er geliefert hat.
Wenn er es für sinnvoll hält einen weiteren Parameter für Stille einzuführen, werde ich natürlich mit dem SIP Modul nachziehen.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Tobias

Ich bin auch nicht überzeugt eine Funktionalität einzubauen die nicht nur die KOmplexität erhöht sondern auch keinen wirklichen Mehrwert bringt.
Du kannst einfach ein 2tes TTS Modul definieren welches als Server fungieren soll.

Gerade bei multiplen, parallelen zugriffen auf ein TTS Modul wäre dieser parameter hinderlich. Query 1 will eine stille, query 2 weiß davon nix und dann kommt nix mehr aus dem LS
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

prodigy7

Zitat von: Tobias am 15 Januar 2018, 15:23:09
Ich bin auch nicht überzeugt eine Funktionalität einzubauen die nicht nur die KOmplexität erhöht sondern auch keinen wirklichen Mehrwert bringt.
Du kannst einfach ein 2tes TTS Modul definieren welches als Server fungieren soll.

Gerade bei multiplen, parallelen zugriffen auf ein TTS Modul wäre dieser parameter hinderlich. Query 1 will eine stille, query 2 weiß davon nix und dann kommt nix mehr aus dem LS
Naja, theoretisch wenn ich den Patch optimiere, sind es nur noch 4-5 Zeilen mehr, extrem mehr Komplexität ist das nicht. Aber Ja, extrem großer Unterschied ist es auch nicht. Auf der einen Seite ein paar wenige Zeilen mehr Code, auf der anderen Seite mehr Ressourcen die im Hintergrund verbraucht werden (2te Instanz). Wenn es Probleme bei multiplen Zugriffen geben kann, ist das natürlich ein Argument für eine zweite Instanz, dafür bin ich nicht wirklich in der Materie drin derzeit.