Python vl c не работает при удалении файла после воспроизведения - PullRequest
0 голосов
/ 14 марта 2020

Я пытаюсь создать текст для речевого приложения, используя PyQt5, где я использую модуль gTTS для преобразования текста в речь. Этот API не воспроизводит речь, скорее сохраняет в формате .mp3 или .wav. Итак, после сохранения я использую VL C Player для воспроизведения звука, потому что он не останавливает приложение там, как Playsound или другие модули. Но после воспроизведения аудио я хотел бы удалить этот аудиофайл. Для этого я использую os.remove(). Если я не удаляю файл, проигрыватель VL C воспроизводит файлы, но когда я пытаюсь удалить файл после воспроизведения звука, проигрыватель VL C не может найти этот файл. Я не хочу останавливать программу во время воспроизведения аудио.

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

1 Ответ

0 голосов
/ 14 марта 2020

Проблема в том, что vl c не читает весь файл, но понемногу, поэтому, если вы удалите файл только тогда, когда он начнет воспроизводиться, он потерпит неудачу. Решение состоит в том, чтобы удалить файл в конце воспроизведения, и когда вы укажете, что хотите использовать 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_())
...