转换python espeak +子进程代码以直接播放输出音频



我正在使用一个现有的程序,该程序从套接字读取xml,将文本转换为wav文件,然后在音频输出设备上播放。

我想把它剥离下来,这样它就直接将文本播放到音频中。

现在我很难弄清楚我是否有正确的代码并理解它是否真的在创建 wav 文件。

调用

调用文本到语音转换函数的函数

def generate_audio(self, language, voice=None):
    info = self.get_first_info(language, bestmatch=False)
    if info is None:
        self.media_info[language] = None
        return False
    truncate = not self.broadcast_immediately() and bcastplayer.Config.setting('alerts_truncate')
    message_text = info.get_message_text(truncate)
    location = bcastplayer.ObData.get_datadir() + "/alerts"
    if os.access(location, os.F_OK) == False:
        os.mkdir(location)
    filename = self.reference(self.sent, self.identifier) + "-" + language + ".wav"
    resources = info.get_resources('audio')
    if resources:
        if resources[0].write_file(os.path.join(location, filename)) is False:
            return False
    elif message_text:
        self.write_tts_file(os.path.join(location, filename), message_text, voice)
    else:
        return False

可以修改以直接播放音频吗?

def write_tts_file(self, path, message_text, voice=None):
    if not voice:
        voice = 'en'
    proc = subprocess.Popen([ 'espeak', '-m', '-v', voice, '-s', '130', '--stdout' ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
    (stdout, stderr) = proc.communicate(message_text.encode('utf-8') + b" <break time="2s" /> " + message_text.encode('utf-8') + b" <break time="3s" /> ")
    proc.wait()
    with open(path, 'wb') as f:
        f.write(stdout)

我从未见过这样的代码使用 processsubprocessstdoutPIPE

在不

创建 wav 文件的情况下将子流程代码更改为仅通过管道将输出重定向到aplay的内容是否容易?

还有另一个答案可能会提供线索 - 但同样,我的新手理解不确定如何将此代码转换为该答案

如何使用python Popen与espeak and aplay

您可以使用 subprocess.PIPE 将两个进程链接在一起。以下是write_tts_file函数的修改版本:

def write_tts_file(self, path, message_text, voice=None):
    if not voice:
        voice = 'en'
    proc = subprocess.Popen(['espeak', '-m', '-v', voice, '-s', '130', '--stdout' ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
    aplay = subprocess.Popen(['aplay', '-D', 'sysdefault'], stdin=proc.stdout)
    proc.stdin.write(message_text.encode('utf-8') + b" <break time="2s" /> " + message_text.encode('utf-8') + b" <break time="3s" /> n")
    proc.stdin.close()
    proc.wait()

发送要说出的消息后关闭procstdin非常重要。这将使proc在发送数据时退出,并将其输出关闭到 aplay ,而 将在完成播放后退出。如果proc的输入没有关闭,他们都不会退出。

最新更新