2016-11-06 59 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) 

我從來沒有見過像這樣使用processsubprocessstdoutPIPE代碼。

將子進程代碼更改爲僅管道或將輸出重定向到aplay而不創建wav文件很容易嗎?

有可能給一個線索另一個答案 - 但是,我的新手的理解是不知道如何將此代碼轉換爲這個問題的答案

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

謝謝 - 我會試試看。我真的很難理解語言和子流程 – dbmitch