How do I implement a slider that controls when an mp3 file is playing?(PyQt 5, Python 3)

I've seen some examples where QSlider was created that was bound to QMediaPlayer. But these examples were complicated by various additional functions, which made it very difficult for me to understand the device of the slider itself.

I would like to create a simple slider that could control when an audio file is playing. Please tell me how it can be done?

Right now, my code can only play and pause files that have paths to them. stores a dictionary self.dict:

from PySide2 import QtCore, QtWidgets, QtGui, QtMultimedia

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.dict = {
            '1.Papercut.mp3': [], 
            '13.Numb.mp3': []
        }

        self.song = ''

        self.player = QtMultimedia.QMediaPlayer()
        self.qsl = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.qsl.sliderMoved[int].connect(self.SetPlayPosition)
        self.box = QtWidgets.QGridLayout(self)   

        for line, song in enumerate(self.dict):
            play_btn = QtWidgets.QPushButton('Play', clicked=lambda song=song: self.play(song))

            pause_btn = QtWidgets.QPushButton('Pause', clicked=self.pause, enabled=False)

            label = QtWidgets.QLabel(song)
            self.box.addWidget(play_btn, line, 0)
            self.box.addWidget(pause_btn, line, 1)
            self.box.addWidget(label, line, 2)

            self.dict[song].append(play_btn)
            self.dict[song].append(pause_btn)

        self.box.addWidget(self.qsl, 2, 0)

    def SetPlayPosition(self):
        self.player.setPosition(self.qsl.value())

    # Воспроизведение
    def play(self, song):
        if self.player.isAudioAvailable() == False:
            self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl(song)))
            self.dict[song][1].setEnabled(True)
            self.song = song

        if self.song == song:
            pass
        else:
            self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl(song)))
            self.dict[self.song][1].setEnabled(False)
            self.dict[song][1].setEnabled(True)
            self.song = song

        self.player.play()

    # Пауза
    def pause(self):
        self.player.pause()


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle('MP3-player, PyQt5')
    window.show()
    sys.exit(app.exec_())
Author: S. Nick, 2020-03-05

1 answers

In general, all the details are here https://doc.qt.io/qt-5/qmediaplayer.html
and here https://doc.qt.io/qt-5/qslider.html

I have marked the lines that have been changed for you.

#from PySide2 import QtCore, QtWidgets, QtGui, QtMultimedia
from PyQt5 import QtCore, QtWidgets, QtGui, QtMultimedia

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.dict = {
            'bibi.mp3': [], 
            'D:/_Qt/EXE/Mp3/new_build/QThread_mp3/img/zvuki_prirody.mp3': []
        }
        self.song = ''

        self.player = QtMultimedia.QMediaPlayer()
        # [signal]void QMediaPlayer::stateChanged(QMediaPlayer::State state)           # +++
        self.player.stateChanged.connect(self.playerState)                             # +++   !!!

        self.qsl = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.qsl.sliderMoved[int].connect(self.SetPlayPosition)
        self.qsl.sliderReleased.connect(self.slider_released)                          # +++   !!!

        self.box = QtWidgets.QGridLayout(self)   

        for line, song in enumerate(self.dict):            # !!!    vv                               # vvvv             
            play_btn = QtWidgets.QPushButton('Play', clicked=lambda ch, song=song: self.play(song))  # + ch, !!!

            pause_btn = QtWidgets.QPushButton('Pause', clicked=self.pause, enabled=False)

            label = QtWidgets.QLabel(song)
            self.box.addWidget(play_btn, line, 0)
            self.box.addWidget(pause_btn, line, 1)
            self.box.addWidget(label, line, 2)

            self.dict[song].append(play_btn)
            self.dict[song].append(pause_btn)

        self.box.addWidget(self.qsl, 2, 0, 1, 3)                                                # + , 1, 3

# ++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv      
        self.Play_Pause = True
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.PlayMode)
        self.timer.start(1000)

    def PlayMode(self):
        if self.Play_Pause==False:
            self.qsl.setMinimum(0)
            self.qsl.setMaximum(self.player.duration())
            self.qsl.setValue(self.qsl.value() + 1000)

    def slider_released(self):
#        print(f'slider_released ->> {self.qsl.value()}')                  # !!!
        self.player.setPosition(self.qsl.value())                          # !!!
# ++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    def SetPlayPosition(self, val):
        pass
#?        self.player.setPosition(self.qsl.value())  # см. выше
#        print(val)                                                        # !!!

    # Воспроизведение
    def play(self, song):
        if self.player.isAudioAvailable() == False:
            self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl(song)))
            self.dict[song][1].setEnabled(True)
            self.song = song

        if self.song == song:
            pass
        else:
            self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl(song)))
            self.dict[self.song][1].setEnabled(False)
            self.dict[song][1].setEnabled(True)
            self.song = song

        self.player.play()
        self.Play_Pause=False                                                            # +++

    # Пауза
    def pause(self):
        self.player.pause()
        self.Play_Pause=True                                                             # +++

# ++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv      
    def playerState(self, state):
        if state == 0:
#            self.qsl.setValue(0)
            self.Play_Pause=True
            self.qsl.setSliderPosition(0)
# ++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle('MP3-player, PyQt5')
    window.show()
    sys.exit(app.exec_())

enter a description of the image here

 2
Author: S. Nick, 2020-03-05 22:45:48