In this Python PyQt5 article we want to learn How to Build Python Media Player with PyQt5, Python is powerful language that can be used for different types of applications including creating multimedia applications. PyQt5 is popular Python library that allows developers to create graphical user interfaces for desktop applications. in this article we want to talk about how to build Python media player with PyQt5.
How to Build Python Media Player with PyQt5
First of all we need to install PyQt5 and you can use pip for the installation.
1 |
pip install PyQt5 |
This is the complete code for Python PyQt5 Media Player
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
import sys from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QSlider, QFileDialog from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent from PyQt5.QtMultimediaWidgets import QVideoWidget from PyQt5.QtCore import Qt, QUrl class MediaPlayer(QWidget): def __init__(self, parent=None): super(MediaPlayer, self).__init__(parent) self.setWindowTitle("GeeksCoders - Media Player") # Create the media player object self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVolume(50) # Create the play button self.playButton = QPushButton("Play") self.playButton.setEnabled(False) self.playButton.clicked.connect(self.play) # Create the stop button self.stopButton = QPushButton("Stop") self.stopButton.setEnabled(False) self.stopButton.clicked.connect(self.stop) # Create the slider for seeking self.seekSlider = QSlider(Qt.Horizontal) self.seekSlider.setRange(0, 0) self.seekSlider.sliderMoved.connect(self.setPosition) # Create the open button self.openButton = QPushButton("Open") self.openButton.clicked.connect(self.openFile) # Create the horizontal layout for the buttons and slider controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.stopButton) controlLayout.addWidget(self.seekSlider) controlLayout.addWidget(self.openButton) # Create the video widget self.videoWidget = QVideoWidget() # Create the vertical layout for the window mainLayout = QVBoxLayout() mainLayout.addWidget(self.videoWidget) mainLayout.addLayout(controlLayout) # Set the main layout of the window self.setLayout(mainLayout) # Connect the media player signals to the appropriate methods self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Video", "", "Video Files (*.mp4 *.avi *.mkv)") if fileName != '': self.setMedia(fileName) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def stop(self): self.mediaPlayer.stop() def setPosition(self, position): self.mediaPlayer.setPosition(position) def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setText("Pause") else: self.playButton.setText("Play") def positionChanged(self, position): self.seekSlider.setValue(position) def durationChanged(self, duration): self.seekSlider.setRange(0, duration) self.seekSlider.setEnabled(duration > 0) self.playButton.setEnabled(duration > 0) self.stopButton.setEnabled(duration > 0) def setMedia(self, url): mediaContent = QMediaContent(QUrl.fromLocalFile(url)) self.mediaPlayer.setMedia(mediaContent) self.playButton.setEnabled(True) self.stopButton.setEnabled(True) self.mediaPlayer.play() self.videoWidget.show() self.mediaPlayer.setVideoOutput(self.videoWidget) if __name__ == '__main__': app = QApplication(sys.argv) player = MediaPlayer() player.show() sys.exit(app.exec_()) |
So first of all we have imported the required libraries and modules from PyQt5.
1 2 3 4 5 |
import sys from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QSlider, QFileDialog from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent from PyQt5.QtMultimediaWidgets import QVideoWidget from PyQt5.QtCore import Qt, QUrl |
This code defines class called MediaPlayer that extends from QWidget class. __init__ method is the constructor of the class which takes an optional parent argument. in the __init__ method super function is called to initialize the QWidget base class. next line sets the window title of the media player to “GeeksCoders – Media Player”. after that an instance of the QMediaPlayer class is created and assigned to the instance variable self.mediaPlayer. QMediaPlayer object is initialized with two arguments: None and QMediaPlayer.VideoSurface, first argument is the parent object of the media player which is set to None, second argument specifies the type of media that the player can handle, which is set to video in this case, also we set volume of the media player to 50 using the setVolume method of the QMediaPlayer object.
1 2 3 4 5 6 7 8 |
class MediaPlayer(QWidget): def __init__(self, parent=None): super(MediaPlayer, self).__init__(parent) self.setWindowTitle("GeeksCoders - Media Player") self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVolume(50) |
In this code we have create two QPushButton, one for playing the video and another one for stopping the video, also we have connected the clicked signal of these buttons to the specific method or slots.
1 2 3 4 5 6 7 8 |
self.playButton = QPushButton("Play") self.playButton.setEnabled(False) self.playButton.clicked.connect(self.play) self.stopButton = QPushButton("Stop") self.stopButton.setEnabled(False) self.stopButton.clicked.connect(self.stop) |
This code initializes horizontal QSlider object and assigns it to the instance variable self.seekSlider. slider is created using the Qt.Horizontal parameter which sets the orientation of the slider to horizontal. setRange method is then called on the self.seekSlider object to set the range of the slider to (0, 0). this effectively makes the slider unusable since it has no range to move along. also sliderMoved signal of the self.seekSlider object is connected to the setPosition method. this means that when the user moves the slider the setPosition method will be called which will handle setting the position of the media playback accordingly.
1 2 3 |
self.seekSlider = QSlider(Qt.Horizontal) self.seekSlider.setRange(0, 0) self.seekSlider.sliderMoved.connect(self.setPosition) |
This code creates an instance of the QPushButton class and assigns it to the instance variable self.openButton. button is initialized with the label Open. clicked signal of the self.openButton object is then connected to the openFile method. this means that when the user clicks on the self.openButton openFile method will be called which will handle opening the file that the user wants to play.
1 2 |
self.openButton = QPushButton("Open") self.openButton.clicked.connect(self.openFile) |
This code initializes horizontal box layout object controlLayout and sets its content margins to zero on all sides using setContentsMargins method. after that addWidget method is called on the controlLayout object four times to add four widgets: self.playButton, self.stopButton, self.seekSlider and self.openButton. these widgets are added to the layout in the order they are listed.
1 2 3 4 5 6 |
controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.stopButton) controlLayout.addWidget(self.seekSlider) controlLayout.addWidget(self.openButton) |
This code creates an instance of the QVideoWidget class and assigns it to the instance variable self.videoWidget. QVideoWidget class is a widget that can be used to display video content. it provides a surface for the QMediaPlayer to display its video output.
1 |
self.videoWidget = QVideoWidget() |
This code connects three signals emitted by the QMediaPlayer object to their slot methods. first line connects stateChanged signal of the self.mediaPlayer object to the mediaStateChanged method. this means that when the state of the media player changes for example when it goes from playing to paused , mediaStateChanged method will be called to handle the change.
second line connects positionChanged signal of the self.mediaPlayer object to the positionChanged method. this means that when the position of the media playback changes for example when the user seeks to a new position in the video, positionChanged method will be called to handle the change.
third line connects the durationChanged signal of the self.mediaPlayer object to the durationChanged method. this means that when the duration of the media playback changes for example when new video file is loaded , durationChanged method will be called to handle the change.
by connecting these signals to their slot methods, media player object can communicate important changes in its state to the rest of the program and trigger the necessary actions to respond to those changes.
1 2 3 |
self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) |
In this code we are using QFileDialog to open a video file
1 2 3 4 |
def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Video", "", "Video Files (*.mp4 *.avi *.mkv)") if fileName != '': self.setMedia(fileName) |
This code defines two methods play and stop which are called when the corresponding buttons are clicked.
play method first checks the state of the media player by calling self.mediaPlayer.state(). if the media player is already in the PlayingState the method pauses the playback using pause() method of the media player object. if the media player is not in the PlayingState the method starts playing the media using the play() method of the media player object.
stop method simply stops the media playback using the stop() method of the media player object. when this method is called, media player will stop playing the current media file and reset the playback position to the beginning of the file.
1 2 3 4 5 6 7 8 |
def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def stop(self): self.mediaPlayer.stop() |
This code defines a method setPosition that is called when the user changes the position of the seek slider widget. the method takes single parameter position which is the new position that the user has set.
1 2 |
def setPosition(self, position): self.mediaPlayer.setPosition(position) |
This code defines a method mediaStateChanged that is called when the state of the QMediaPlayer object changes. this method takes single parameter state which represents the new state of the media player.
mediaStateChanged method then checks the current state of the media player using the state() method of the media player object.
1 2 3 4 5 |
def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setText("Pause") else: self.playButton.setText("Play") |
This code defines a method positionChanged that is called when the playback position of the media file being played changes. this method takes single parameter position which represents the new playback position of the media file being played.
1 2 |
def positionChanged(self, position): self.seekSlider.setValue(position) |
This code defines a method durationChanged that is called when the duration of the media file being played changes. this method takes a single parameter duration which represents the new duration of the media file being played.
1 2 3 4 5 |
def durationChanged(self, duration): self.seekSlider.setRange(0, duration) self.seekSlider.setEnabled(duration > 0) self.playButton.setEnabled(duration > 0) self.stopButton.setEnabled(duration > 0) |
Run the complete code and this will be the result

Learn More on PyQt5
- How to Deploy PyQt5 Applications
- How to Integrate PyQt5 with OpenCV
- How to Use Stylesheets in PyQt5
- Learn PyQt5 Event Handling with Signals and Slots
- PyQt5 Tutorial: Creating Menus and Toolbars
- How to Open & Save Files in Python PyQt5
- PyQt5 Designer Tutorial: Complete Guide to Qt Designer
- PyQt5 vs Tkinter: Which GUI Library is Right for You
- How to Build Web Applications in PyQt5
- How to Integrate Python Flask with PyQt5