我正在尝试使用PyQt5创建语音应用程序的文本,其中我正在使用gTTS模块将文本转换为语音。该API不播放语音,而是以.mp3
或.wav
格式保存。因此,保存后,我将使用VLC Player播放音频,因为它不会像Playsound或其他模块那样冻结应用程序。但是在播放音频后,我想删除该音频文件。为此,我正在使用os.remove()
。如果我没有删除文件,则VLC Player会播放文件,但是当我尝试在播放音频后删除文件时,VLC Player无法找到该文件。我不想在播放音频时冻结程序。
import os
from gtts import gTTS
from datetime import datetime
from vlc import MediaPlayer
def convert_text(text):
lang='fr'
tts = gTTS(text=text, lang=lang)
now = datetime.now()
file_name = "sample_" + now.strftime("%b-%d-%Y-%H%M%S")+".mp3"
tts.save(file_name)
pl = MediaPlayer(file_name)
pl.play()
os.remove(file_name)
return tts, file_name
if __name__ == '__main__':
text = "Bonjour je m'appelle Antoine et j'habite à Montréal au Québec. Ce soir je serai à " \
"la maison et je pourrai enfin voir mes enfants."
convert_text(text)
错误
/home/garud/anaconda3/bin/python
/home/garud/Documents/SpeechRecog/SpeechRecognition_v2/text2speech.py
[00007fc2940076d0] filesystem stream error: cannot open file /home/garud/Documents/SpeechRecog/SpeechRecognition_v2/sample_Mar-14-2020-113837.mp3 (No such file or directory)
[00005583b470a8e0] main input error: Your input can't be opened
[00005583b470a8e0] main input error: VLC is unable to open the MRL 'file:///home/garud/Documents/SpeechRecog/SpeechRecognition_v2/sample_Mar-14-2020-113837.mp3'. Check the log for details.
Process finished with exit code 0
问题在于,vlc不会一点一点地读取整个文件,因此,如果仅在文件开始播放时将其删除,则它将失败。解决方案是在播放结束时删除文件,并指出要使用PyQt5,然后可以使用QTimer连续检查播放器的状态。
from datetime import datetime
import os
import sys
import threading
from gtts import gTTS
from vlc import MediaPlayer
from PyQt5 import QtCore, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class ConverterWorker(QtCore.QObject):
finished = QtCore.pyqtSignal(str)
def convert(self, text, lang):
threading.Thread(target=self._convert, args=(text, lang), daemon=True).start()
def _convert(self, text, lang):
tts = gTTS(text=text, lang=lang)
now = datetime.now()
file_name = "sample_{}.mp3".format(now.strftime("%b-%d-%Y-%H%M%S"))
path = os.path.join(CURRENT_DIR, file_name)
tts.save(path)
self.finished.emit(path)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.converter = ConverterWorker()
self.player = MediaPlayer()
self.timer = QtCore.QTimer(interval=100, timeout=self.on_timeout)
self.path = ""
self.lineedit = QtWidgets.QLineEdit()
self.button = QtWidgets.QPushButton(self.tr("Start"))
lay = QtWidgets.QHBoxLayout(self)
lay.addWidget(self.lineedit)
lay.addWidget(self.button)
self.button.clicked.connect(self.on_clicked)
self.converter.finished.connect(self.on_finished)
text = (
"Bonjour je m'appelle Antoine et j'habite à Montréal au Québec. Ce soir je serai à "
"la maison et je pourrai enfin voir mes enfants."
)
self.lineedit.setText(text)
@QtCore.pyqtSlot()
def on_clicked(self):
self.converter.convert(self.lineedit.text(), "fr")
self.button.setEnabled(False)
@QtCore.pyqtSlot(str)
def on_finished(self, path):
self.path = path
media = self.player.get_instance().media_new(path)
self.player.set_media(media)
self.player.play()
self.timer.start()
@QtCore.pyqtSlot()
def on_timeout(self):
if not self.player.is_playing():
self.timer.stop()
self.button.setEnabled(True)
if os.path.isfile(self.path):
os.remove(self.path)
self.path = ""
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(640, 60)
w.show()
sys.exit(app.exec_())