TTS icon indicating copy to clipboard operation
TTS copied to clipboard

espeak-ng.exe subprocesses causing windows to popup when python running under pythonw.exe

Open Barnacules opened this issue 1 year ago β€’ 0 comments

Describe the bug

When I run my python script that uses Coqui-ai TTS under pythonw.exe which runs it without a window it will spawn espeak-ng.exe subprocesses that popup windows for a spit second a few times while running the python script. It just dumps the output of the console to the main window when python.exe is used however I suspect that without an STDOUT to push the console text too it just spawns a window to do it then it closes quickly. Is there a way to add a flag that will prevent the subprocess from outputting text by redirecting it to nothing so that this doesn't happen when calling scripts silently using pythonw.exe to prevent windows from popping up? This is common when using things like streamerbot.exe to create actions so that you don't have constant windows popping up on the screen when actions are firing.

image

The above image shows me catching the conhost.exe processes spawning while I'm running the script under pythonw.exe. When I run the script under python.exe the output from espeak-ng.exe just gets sent to the same console window as the pythons script is running.

Perhaps the following code could be used whenever TTS is spawning subprocesses behind the API? This will ensure SW_HIDE is applied on process startup to ensure the console window doesn't become visible even for an instant.

import subprocess

def run_hidden(*args, **kwargs): """Run a process without a visible console window.""" startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE kwargs['startupinfo'] = startupinfo return subprocess.Popen(*args, **kwargs)

Usage example:

run_hidden(['your_command', 'arg1', 'arg2'], stderr=subprocess.PIPE, stdout=subprocess.PIPE)

To Reproduce

from TTS.api import TTS

device="cuda" tts = TTS(model_name="tts_models/en/ljspeech/neural_hmm", progress_bar=False).to(device) wav = tts.tts(text=response, preset="ultra_fast")

Expected behavior

When python script is run under pythonw.exe I expect no new windows to popup even if subprocesses are called. All of the STDOUT should be redirected to NUL instead of having windows popup for each child process that spawns. It would be nice if any of the subprocesses called to espeak-ng.exe or other processes would have a flag added to direct their output to nothing so no child window pops up.

Logs

I don't have any logs but the screen shot of processes explorer catching the multiple instances of espeak-ng.exe opening at the same time the console windows would blink on the desktop and go away is a pretty good indicator that it's conhost.exe's are spawning the windows for a moment. Not long enough to see what text is being shown in them though.

Environment

{
    "CUDA": {
        "GPU": [
            "NVIDIA GeForce RTX 4090"
        ],
        "available": true,
        "version": "11.8"
    },
    "Packages": {
        "PyTorch_debug": false,
        "PyTorch_version": "2.2.0+cu118",
        "TTS": "0.22.0",
        "numpy": "1.22.0"
    },
    "System": {
        "OS": "Windows",
        "architecture": [
            "64bit",
            "WindowsPE"
        ],
        "processor": "Intel64 Family 6 Model 85 Stepping 4, GenuineIntel",
        "python": "3.10.13",
        "version": "10.0.22631"
    }
}

Additional context

I would like a change that would ensure all subprocesses are hidden when called from the API itself so that anyone running the python script without a window using pythonw.exe won't see child windows blinking on the desktop for each instance of the subprocesses like espeak-ng.exe which I caught using sysintenals processes explorer which is an amazing took for catching little things like this.

image

Perhaps even include a flag on TTS() itself and other class objects to pass through to any child processes telling them not to show any window when they are spawned if there isn't a parent window associated with the process like if it's running under python.exe instead of pythonw.exe. This is super useful for when you need to call python scripts from Streamer.Bot so you don't have windows blinking up on the desktop constantly every time some action triggers an event that uses the TTS.

Barnacules avatar Feb 01 '24 08:02 Barnacules