如何在Python中进行文本转语音而不阻塞主线程?

问题描述 投票:0回答:1

我基本上想要一个带有 python 文本到语音的日志系统,但我担心它会暂停主程序。以下程序对我有用,但它会在我将文本记录为语音时暂停线程。 python中有什么方法可以记录但它不应该阻止主程序。

import pyttsx3

class TextToSpeech:
    def textToSpeech(self, text):
        engine = pyttsx3.init()
        engine.say(text)
        engine.runAndWait()    

t2s = TextToSpeech()
t2s.textToSpeech("Hello")
t2s.textToSpeech("How are you")
t2s.textToSpeech("I am fine")
python text-to-speech pyttsx3
1个回答
0
投票

有趣的是,当直接在Python线程中运行时,

pyttsx3
似乎表现不佳。 Github 上的This 评论建议了一种解决方法,即在单独的子进程中运行每个进程。 请注意,这有点 hacky,并且要注意运行子进程的成本以及线程和进程之间的差异。

如果你把它放在一起,它看起来像这样

import threading
import queue
import subprocess
import time

class TextToSpeechManager:
    def __init__(self):
        self.queue = queue.Queue()
        self.thread = threading.Thread(target=self._process_queue, daemon=True)
        self.thread.start()

    def add_to_queue(self, phrase):
        self.queue.put(phrase)

    def _process_queue(self):
        while True:
            phrase = self.queue.get()
            if phrase is None:
                break
            subprocess.call(["python3", "speak.py", phrase])
            self.queue.task_done()

    def stop(self):
        self.queue.put(None)
        self.thread.join()

if __name__ == "__main__":
    tts_manager = TextToSpeechManager()

    # add stuff you want spoken into the queue
    tts_manager.add_to_queue("Hello, this is the first message.")
    tts_manager.add_to_queue("Here's the second message.")
    tts_manager.add_to_queue("And finally, the third message.")

    # Simulate some other work in parallel
    for i in range(50):
        print(f"Main program doing work {i+1}...")
        time.sleep(1)

    tts_manager.stop()

speak.py
实际上会调用实际的API:

import sys
import pyttsx3

def init_engine():
    engine = pyttsx3.init()
    return engine

def say(s):
    engine.say(s)
    engine.runAndWait()  # Blocks

if __name__ == "__main__":
    engine = init_engine()
    say(str(sys.argv[1]))

© www.soinside.com 2019 - 2024. All rights reserved.