ioBroker / ioBroker.sayit

Text to speech for ioBroker
MIT License
30 stars 25 forks source link

Log error "Cannot play file: Timeout by checking of announcement finished playing" if playing longer announcements #299

Closed neopholus closed 3 months ago

neopholus commented 8 months ago

Describe the bug
When playing a longer announcement (e.g. weather forecast) using sayit on a Google Home Mini via chromecast, there are two lines of errors in the log from the sayit adapter (not from chromecast): Error while checking if chromecast.0.Google_Home_WZ.player.announcement finished playing announcement: {"url":"http://192.168.X.YYY:ZZZZ/sayit.0/tts.mp3?ts=1705256129645","volume":20}: TIMEOUT Cannot play file: Timeout by checking of announcement finished playing.

The announcement is spoken correctly nevertheless.

To Reproduce
Steps to reproduce the behavior:

  1. Go to objects tab
  2. Go to "sayit.0.tts.text"
  3. Enter the following string: 20;<speak>Das ist eine lange Testansage, um einen Fehler im Log zu provozieren. Und da das noch nicht lange genug ist, fügen wir noch weiteren Text hinzu. Sicherheitshalber noch einen dritten sehr langen Satz, damit das Problem auch wirklich auftritt. Ich hoffe, das hat gereicht.</speak>

Expected behavior
Announcement should be spoken WITHOUT an error message in the log.

Screenshots & Logfiles
Error while checking if chromecast.0.Google_Home_WZ.player.announcement finished playing announcement: {"url":"http://192.168.3.105:8083/sayit.0/tts.mp3?ts=1705256699645","volume":20}: TIMEOUT Cannot play file: Timeout by checking of announcement finished playing.

Versions:

Additional context
I think, sayit is using the datapoint announcementto playback via chromecast and then waiting for the end of the playback. As the playback lasts quite long, the timeout gets active and thinks, there is a problem, but in reality the file is still playing. Maybe, setting the timeout depending on the length of the mp3 file (e.g. using mp3info) would be a solution? Or making the timeout configurable?

neopholus commented 6 months ago

I analyzed the problem and found a way to fix it: On the iobroker server, open /opt/iobroker/node_modules/iobroker.sayit/lib/speech2device.js in e.g. nano, search for TIMEOUT and in the surrounding if-block change if (count > 20) { to if (count > (duration+1)*2) {.

Result:

if (count > (duration+1)*2) {
    clearInterval(intervalHandler);
    intervalHandler = null;
    this.adapter.log.error(`Error while checking if ${chromecastAnnouncementDev} finished playing announcement: ${announcementJSON}: TIMEOUT`);
    reject('Timeout by checking of announcement finished playing');
    return;
}

Save changes and do not forget to restart all sayIt instances in iobroker.

Then the error messages are gone. All the hard work of figuring out the length of the spoken text was already done, it was just not used. Maybe somebody can change this in the github version.

neopholus commented 6 months ago

Proposed a pull request for fix: #307

Apollon77 commented 3 months ago

Fixed in next version, thank you!

crunchip77 commented 3 months ago

@Apollon77 ich habe noch immer die Meldung mit dem timeout sayit v4.0.1 google home v3.4.0 javascript v8.4.2

`

sayit.0 | 2024-05-29 13:53:25.417 | error | Cannot play file: Timeout by checking of announcement finished playing -- | -- | -- | -- sayit.0 | 2024-05-29 13:53:25.417 | error | Error while checking if chromecast.0.Google_Home_mini.player.announcement finished playing announcement: {"url":"http://10.1.1.10:8082/sayit.0/tts.mp3?ts=1716983587901","volume":50}: TIMEOUT

`

neopholus commented 3 months ago

@crunchip77: Wie sieht denn deine Konfiguration der sayit-Instanz aus? Bitte beide Reiter "Abspielen" und "TTS-Engine"! Danke!

crunchip77 commented 3 months ago

@neopholus image image

neopholus commented 3 months ago

Danke. Komisch, das ist praktisch genau die Konfiguration, mit der ich auch arbeite. Kommt der Fehler jedes Mal oder nur hin- und wieder?

Mit welchem Befehl startest du denn deine Sprachausgabe?

crunchip77 commented 3 months ago

@neopholus wenn ichs richtig sehe, kommt es immer zum Fehler. ich lasse mir verschiedene Benachrichtigungen ausgeben, z.b. Wetterwarnungen mittels Wetterscript(kann durchaus mal eine etwas länger Sprachausgabe sein), oder aber auch, Anrufansage, wann die nächste Tonne geleert wird oder welches Fenster wie lange geöffnet ist.

neopholus commented 3 months ago

Das sind genau meine Use-Cases auch, daher kommen auch bei mir sehr lange Ansagen. Kannst du mir einen Javascript Aufruf eines der Dateien posten? z.B. wie du die Wettervorhersage ausgeben lässt? Blockly oder Javascript direkt?

Ich kann bisher keinen relevanten Unterschied in unseren Konfigurationen finden, daher kann ich bisher den Fehler leider nicht nachstellen.

crunchip77 commented 3 months ago

@neopholus das ursprüngliche script siehe https://forum.iobroker.net/topic/30616/script-dwd-uwz-nina-warnungen-als-push-sprachnachrichten?_=1717430303095 aber auch der jetzige Adapter https://forum.iobroker.net/topic/68595/test-adapter-weather-warnings?_=1717430303097 gibt den selben Fehler PS: unter anderem habe ich festgestellt, das die Lautstärke bei der eigentlichen Nachricht nicht verändert wird, kann jedoch aber auch am Adapter liegen

Edit: auch hier entsteht der Fehler `

sayit.0 | 2024-06-03 20:49:11.857 | error | Cannot play file: Timeout by checking of announcement finished playing -- | -- | -- | -- sayit.0 | 2024-06-03 20:49:11.857 | error | Error while checking if chromecast.0.Google_Home_mini.player.announcement finished playing announcement: {"url":"http://10.1.1.10:8082/sayit.0/tts.mp3?ts=1717440542348","volume":50}: TIMEOUT ` script dazu ` setState('sayit.0.tts.text' /* Text to speech */, 'Der Trockner ist fertig. '); console.log('test'); `
neopholus commented 2 months ago

Sorry, was traveling, will look into it on the weekend.

neopholus commented 2 months ago

Kannst du bitte mal folgendes ausprobieren? Die Zahl sollte die Lautstärke setzen, probier mal aus, ob das geht. Und auch, ob der Fehler mit dem Timeout kommt, gerne auch mit längeren Texten.

setState('sayit.0.tts.text' /* Text to speech */, '70;<speak>Der Trockner ist fertig.</speak>');

crunchip77 commented 2 months ago

@neopholus ja, so funktioniert es fehlerfrei, hab auch mal den Text verlängert(423Buchstaben incl. Leer/Satzzeichen)

neopholus commented 2 months ago

@crunchip77 Löst das dein Problem dann oder bleibt was zu tun?

crunchip77 commented 2 months ago

@neopholus an sich ja, bei selbst erstellten Scripten auf diese Weise, bleibt aber immer noch das Problem beim Abspielen über gewisse Adapter. Hab im Adapter thread mal hierher verlinkt

neopholus commented 2 months ago

@crunchip77: Welchen Adapter nutzt du und kannst du rausfinden, welcher Aufruf konkret dort verwendet wird? Schau nach einer Ausgabe durch einen der "gewissen" Adapter mal bitte in 'sayit.0.tts.text' nach, ob dort einfach "nur" ein Text reingeschrieben wird, ohne die <speak>-Tags.

Falls das so ist, könnte man, wenn dort ein "plain-Text" angegeben wird, die Tags automatisch hinzufügen, zumindest wenn man eine AWS-Engine verwendet.

Da dieser Issue eigentlich geschlossen ist und streng genommen mit diesem hier nichts zu tun hat, wollte ich dich bitten, auch noch einen neuen Issue zu erstellen. Danke dir!