1

Maybe I'm doing this completely wrong here, I'm trying to make the "timeline" for an mp3 player. Everything works and I've tried to set the slider to one value and it was fine. My problem is when I try updating the timeline as it keeps on freezing the program and it doesn't unfreeze. Here's my code, I commented out where to start looking at in terms of where I'm having trouble in:

import sys
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton, 
    QSlider
import vlc

player = vlc.MediaPlayer("/songs/Immigrant Song.mp3")

class window(QMainWindow):    
    def __init__(self):
        super(window, self).__init__()
        self.setGeometry(50, 50, 400, 200)
        self.setWindowTitle('SlugPlayer')
        #self.setWindowIcon(QIcon('pic.png'))

        self.home()

    def home(self):
        playing = 0
        btn = QPushButton('quit', self)
        btn.clicked.connect(self.close_application)

        btn.resize(btn.sizeHint())  #set to acceptable size automatic
        btn.move(0, 0)

        playbtn = QPushButton('Play', self)
        # playbtn.clicked.connect(self.update_bar, playing)
        playbtn.clicked.connect(self.play_music, playing)
        playbtn.resize(playbtn.sizeHint())
        playbtn.move(100, 0)

        psebtn = QPushButton('Pause', self)

        psebtn.clicked.connect(self.pause_music, playing)

        psebtn.resize(psebtn.sizeHint())
        psebtn.move(200, 0)

        stopbtn = QPushButton('Stop', self)

        stopbtn.clicked.connect(self.stop_music, playing)

        stopbtn.resize(stopbtn.sizeHint())
        stopbtn.move(300, 0)

        self.sl = QSlider(Qt.Horizontal, self)
        self.sl.setFocusPolicy(Qt.NoFocus)
        self.sl.setGeometry(30, 50, 300, 20)
        self.sl.setMinimum(0)
        self.sl.setMaximum(100)
        self.sl.setValue(0)
        self.sl.move(50, 100)

        # self.sl.valueChanged[int].connect(self.print_value)
        self.show()

    def close_application(self):
        sys.exit()

    #here is where I'm trying to update the bar
    def play_music(self, playing):
        player.play()
        playing = 1
        while playing == 1: 
            self.update_bar(playing)



    def pause_music(self, playing):
        player.pause()
        playing = 0

    def stop_music(self, playing):
        player.stop()
        playing = 0

    def print_value(self, value):
        print(value)

    #function to update the bar (converts to an int)
    def update_bar(self, playing):
        self.sl.setValue(int(player.get_position() * 100))

def run():
    app = QApplication(sys.argv)
    Gui = window()
    sys.exit(app.exec_())


run()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
CaptainFS
  • 13
  • 3

1 Answers1

0

An infinite loop like while playing == 1 freezes the GUI since it does not allow you to do other tasks, in these cases it is better to use a QTimer. Going a little further to the bottom of the problem I have implemented a class that is in charge of managing the player by sending signals when necessary.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
import vlc

class VLCManager(QtCore.QObject):
    durationChanged = QtCore.pyqtSignal(int)
    positionChanged = QtCore.pyqtSignal(int)

    def __init__(self, parent=None):
        super(VLCManager, self).__init__(parent)
        self._player = vlc.MediaPlayer()
        self._timer = QtCore.QTimer(self, interval=100, timeout=self.update_values)

    def setFileName(self, filename):
        self._player = vlc.MediaPlayer(filename)

    def position(self):
        self.durationChanged.emit(self.duration())
        return self._player.get_time()

    def setPosition(self, time):
        if self.position() != time:
            self._player.set_time(time)

    @QtCore.pyqtSlot()
    def update_values(self):
        self.positionChanged.emit(self.position())

    def duration(self):
        return self._player.get_length()

    @QtCore.pyqtSlot()
    def play(self):
        self._player.play()
        self.update_values()
        self._timer.start()

    @QtCore.pyqtSlot()
    def pause(self):
        self._player.pause()
        self.update_values()
        self._timer.stop()

    @QtCore.pyqtSlot()
    def stop(self):
        self._player.stop()
        self.update_values()
        self._timer.stop()


class window(QtWidgets.QMainWindow):    
    def __init__(self):
        super(window, self).__init__()
        self._manager = VLCManager(self)
        self._manager.setFileName("/songs/Immigrant Song.mp3")
        self.setWindowTitle('SlugPlayer')
        self.home()

    def home(self):
        quitbtn = QtWidgets.QPushButton('quit')
        quitbtn.clicked.connect(self.close)

        playbtn = QtWidgets.QPushButton('Play')
        playbtn.clicked.connect(self._manager.play)

        psebtn = QtWidgets.QPushButton('Pause', self)
        psebtn.clicked.connect(self._manager.pause)

        stopbtn = QtWidgets.QPushButton('Stop', self)
        stopbtn.clicked.connect(self._manager.stop)

        self.sl = QtWidgets.QSlider(orientation=QtCore.Qt.Horizontal)
        self.sl.setFocusPolicy(QtCore.Qt.NoFocus)
        self._manager.durationChanged.connect(self.sl.setMaximum)
        self._manager.positionChanged.connect(self.sl.setValue)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QVBoxLayout(central_widget)

        hlay = QtWidgets.QHBoxLayout()
        for b in (quitbtn, playbtn, psebtn, stopbtn, ):
            hlay.addWidget(b)
        lay.addLayout(hlay)
        lay.addWidget(self.sl)
        self.sl.valueChanged[int].connect(self._manager.setPosition)
        self.show()

def run():
    app = QtWidgets.QApplication(sys.argv)
    Gui = window()
    sys.exit(app.exec_())

run()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241