Конвертируйте код Python espeak + subprocess для прямого воспроизведения выходного аудио
Я использую существующую программу, которая читает 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)
Я никогда не видел такой код, используя process
, subprocess
, stdout
, PIPE
,
Легко ли изменить код подпроцесса на что-то, что просто передает или перенаправляет вывод на aplay
без создания файла WAV?
Был другой ответ, который мог бы дать подсказку - но, опять же, мое понимание новичка не уверено, как преобразовать этот код в этот ответ
1 ответ
Вы можете связать два процесса вместе, используя 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()
Важно закрыть proc
"s stdin
после того, как вы отправили сообщение, которое нужно произнести. Это сделает proc
выйти, когда он отправил свои данные, и закрыть свой вывод aplay
, который, в свою очередь, выйдет, когда он закончит играть. Если proc
Вход не закрыт, ни один из них не выйдет.