2016-11-06 26 views
0

소켓에서 xml을 읽고 텍스트를 wav 파일로 변환 한 다음 오디오 출력 장치에서 재생하는 기존 프로그램을 사용하고 있습니다.python espeak + subprocess 코드를 변환하여 출력 오디오를 직접 재생합니다.

나는 스트립을 내려 오디오에 직접 텍스트가 재생되도록하고 싶습니다.

바로 지금 나는 올바른 코드를 가지고 있는지 알아 내고 실제로 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를 사용하여이 같은 코드를 본 적이 없습니다.

wav 파일을 만들지 않고 출력을 aplay으로 파이프 또는 리디렉션하는 것으로 서브 프로세스 코드를 변경하는 것이 쉽습니까?

이 단서를 얻을 수있는 또 다른 대답이었다 - 그러나 다시, 내 초보자의 이해

How to use python Popen with a espeak and aplay

답변

2

당신은 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의 입력이 닫히지 않으면 둘 중 어느 것도 종료되지 않습니다.

+0

감사합니다. 시도해 보겠습니다. 나는 espeak와 서브 프로세스를 이해하는데 어려움을 겪고있다. – dbmitch