RealtimeTTS icon indicating copy to clipboard operation
RealtimeTTS copied to clipboard

can't create new thread at interpreter shutdown

Open rejilraj opened this issue 1 year ago • 6 comments

Error: can't create new thread at interpreter shutdown WARNING:root:error in play() with engine system: can't create new thread at interpreter shutdown Traceback: Traceback (most recent call last): File "D:\tts\RealtimeTTS\RealtimeTTS\text_to_stream.py", line 318, in play self.player.start() File "D:\tts\RealtimeTTS\RealtimeTTS\stream_player.py", line 292, in start self.playback_thread.start() File "C:\Users\rejil\miniconda3\Lib\threading.py", line 992, in start _start_new_thread(self._bootstrap, ()) RuntimeError: can't create new thread at interpreter shutdown

rejilraj avatar Jun 15 '24 12:06 rejilraj

Please provide more info. What is the the code that leads to this error?

(The error indicates that your Python program is attempting to start a new thread during or after the interpreter shutdown process, which is not allowed. This typically happens when your application is trying to do some threading-related operations, like starting a new thread, when Python is cleaning up or terminating.)

KoljaB avatar Jun 15 '24 13:06 KoljaB

I face this with the most basic example while trying out RealtimeTTS.

Platform: Windows Python version: 3.12 library installed with selective packages: pip install -U realtimetts[system,gtts]

Here's my Code:

from RealtimeTTS import TextToAudioStream, SystemEngine, GTTSEngine

engine = SystemEngine()
stream = TextToAudioStream(engine)
stream.feed("Hello world! How are you today?")
stream.play_async()

Error in a loop:

Error: can't create new thread at interpreter shutdown
WARNING:root:error in play() with engine gtts: can't create new thread at interpreter shutdown
Traceback: Traceback (most recent call last):
  File "D:\Docs\Personal\Projects\Python\Projects\RealtimeTTS\.env\Lib\site-packages\RealtimeTTS\text_to_stream.py", line 332, in play
    self.player.start()
  File "D:\Docs\Personal\Projects\Python\Projects\RealtimeTTS\.env\Lib\site-packages\RealtimeTTS\stream_player.py", line 292, in start
    self.playback_thread.start()
  File "C:\Python312\Lib\threading.py", line 992, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't create new thread at interpreter shutdown

I tried with both SystemEngine and GTTSEngine. same result for both. and based on the error it seems the library itself is using a separate thread for playing audio, which may have the original issue.

DK013 avatar Oct 23 '24 03:10 DK013

I have tested some scenarios, and it seems to me that the player thread is taking too much time to start and the main thread is closing before that. There may be adjustments needed to the application flow, but that will need more debugging to figure out. Time for which I don't have right now so I leave that to the author and moderators.

DK013 avatar Oct 23 '24 03:10 DK013

from RealtimeTTS import TextToAudioStream, SystemEngine, GTTSEngine

engine = SystemEngine()
stream = TextToAudioStream(engine)
stream.feed("Hello world! How are you today?")
stream.play_async()

play_async() is nonblocking. I assume the script just ends too fast with this code which terminates the main thread. Can you replace play_async() with play() and test again?

KoljaB avatar Oct 23 '24 08:10 KoljaB

play_async() is nonblocking. I assume the script just ends too fast with this code which terminates the main thread. Can you replace play_async() with play() and test again?

with play() it seems to be working fine. 👍

so basically if this code is used in a long running process which doesn't close the thread immediately and keep on processing the next statements after play_async() (which I'm sure the async function is designed for) then it's all good.

@KoljaB you should really update the QuickStart example to have the play() function instead of the async one. and have it as a separate note I guess.

DK013 avatar Oct 24 '24 08:10 DK013

@KoljaB you should really update the QuickStart example to have the play() function instead of the async one. and have it as a separate note I guess.

Yeah. It was this way before, I did not look close enough when merging a PR that changed it. Will rework.

KoljaB avatar Oct 24 '24 08:10 KoljaB