When I close the video with a cross, the audio remains. I use pafy and vlc. Also i can't close PyQt app after closing video.
I use python 3.8.
import sys
import pafy
import vlc
from PyQt5.QtWidgets import QApplication, QDialog, QLabel, QHBoxLayout, QPushButton
class GoodYoutubeGUI(QDialog):
def __init__(self):
super().__init__()
self.setFixedSize(800, 800)
self.setWindowTitle("Good Youtube")
self.buttons = []
self.generate_content()
def generate_buttons_info(self):
buttons_info = {}
for _ in range(5):
button = QPushButton('Открыть видео', self)
buttons_info[button] = "https://www.youtube.com/watch?v=zPA2Een1EQA"
return buttons_info
def generate_content(self):
pos_y = 0
for button, link in self.generate_buttons_info().items():
button.clicked.connect(lambda: self.open_video(link))
button.move(100, pos_y * 100)
pos_y += 1
def open_video(self, url):
video = pafy.new("https://www.youtube.com/watch?v=zPA2Een1EQA")
best = video.getbest()
media = vlc.MediaPlayer(best.url)
media.play()
while media.get_state() != vlc.State.Ended:
continue
media.stop()
if __name__ == '__main__':
app = QApplication(sys.argv)
dlg_main = GoodYoutubeGUI()
dlg_main.show()
sys.exit(app.exec_())
You have the following problems:
You should not use time consuming tasks within the Qt eventloop as it blocks it causing the GUI to freeze, for example the while.loop and pafy's getbest function, the first one should use a callback to know when the video finishes from reproduce and the second must be executed in a secondary thread.
You also have to pass arguments in the lambda since otherwise you will have problems with the scope.
To detect when the window closes, a possible solution is to embed the videoplayer in a QWidget and then use an eventfilter to know when the window closes and then stops the player.