In this article you’ll see the code to create a video player with PyQT5.
It contains a menu bar for opening the video file.
PyQt5 supports multimedia, including a video widget: QVideoWidget. This is used in combination with the class QMediaPlayer.
The QMediaPlayer class has all kinds of properties that you may know from video players: audioAvailable, duration, position, volume and a few others.
Related course: Create PyQt Desktop Appications with Python (GUI)
Introduction
We create a window (QMainWindow) that contains a widget for its contents (QWidget).
Then we add the videowidget and control widgets.
videoWidget = QVideoWidget() |
The player will only play a video, in this example we don’t use back buttons, stop buttons.
QMediaPlayer Example
The complete code below:# PyQt5 Video player
#!/usr/bin/env python
from PyQt5.QtCore import QDir, Qt, QUrl
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import (QApplication, QFileDialog, QHBoxLayout, QLabel,
QPushButton, QSizePolicy, QSlider, QStyle, QVBoxLayout, QWidget)
from PyQt5.QtWidgets import QMainWindow,QWidget, QPushButton, QAction
from PyQt5.QtGui import QIcon
import sys
class VideoWindow(QMainWindow):
def __init__(self, parent=None):
super(VideoWindow, self).__init__(parent)
self.setWindowTitle("PyQt Video Player Widget Example - pythonprogramminglanguage.com")
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
videoWidget = QVideoWidget()
self.playButton = QPushButton()
self.playButton.setEnabled(False)
self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
self.playButton.clicked.connect(self.play)
self.positionSlider = QSlider(Qt.Horizontal)
self.positionSlider.setRange(0, 0)
self.positionSlider.sliderMoved.connect(self.setPosition)
self.errorLabel = QLabel()
self.errorLabel.setSizePolicy(QSizePolicy.Preferred,
QSizePolicy.Maximum)
# Create new action
openAction = QAction(QIcon('open.png'), '&Open', self)
openAction.setShortcut('Ctrl+O')
openAction.setStatusTip('Open movie')
openAction.triggered.connect(self.openFile)
# Create exit action
exitAction = QAction(QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(self.exitCall)
# Create menu bar and add action
menuBar = self.menuBar()
fileMenu = menuBar.addMenu('&File')
#fileMenu.addAction(newAction)
fileMenu.addAction(openAction)
fileMenu.addAction(exitAction)
# Create a widget for window contents
wid = QWidget(self)
self.setCentralWidget(wid)
# Create layouts to place inside widget
controlLayout = QHBoxLayout()
controlLayout.setContentsMargins(0, 0, 0, 0)
controlLayout.addWidget(self.playButton)
controlLayout.addWidget(self.positionSlider)
layout = QVBoxLayout()
layout.addWidget(videoWidget)
layout.addLayout(controlLayout)
layout.addWidget(self.errorLabel)
# Set widget to contain window contents
wid.setLayout(layout)
self.mediaPlayer.setVideoOutput(videoWidget)
self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
self.mediaPlayer.positionChanged.connect(self.positionChanged)
self.mediaPlayer.durationChanged.connect(self.durationChanged)
self.mediaPlayer.error.connect(self.handleError)
def openFile(self):
fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie",
QDir.homePath())
if fileName != '':
self.mediaPlayer.setMedia(
QMediaContent(QUrl.fromLocalFile(fileName)))
self.playButton.setEnabled(True)
def exitCall(self):
sys.exit(app.exec_())
def play(self):
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
self.mediaPlayer.pause()
else:
self.mediaPlayer.play()
def mediaStateChanged(self, state):
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
self.playButton.setIcon(
self.style().standardIcon(QStyle.SP_MediaPause))
else:
self.playButton.setIcon(
self.style().standardIcon(QStyle.SP_MediaPlay))
def positionChanged(self, position):
self.positionSlider.setValue(position)
def durationChanged(self, duration):
self.positionSlider.setRange(0, duration)
def setPosition(self, position):
self.mediaPlayer.setPosition(position)
def handleError(self):
self.playButton.setEnabled(False)
self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
if __name__ == '__main__':
app = QApplication(sys.argv)
player = VideoWindow()
player.resize(640, 480)
player.show()
sys.exit(app.exec_())
If you are new to Python PyQt, then I highly recommend this book.
when I run it i get this error: any way to fix this? (all modules well imported)
DirectShowPlayerService::doRender: Unresolved error code 0x80040266 (IDispatch error #102)
This error often happens when it can't find the right video codec. Try installing the K-lite codecs and LAV filters, see the links in this thread https://stackoverflow.com/q...
I can't get the QMediaPlayer to work with this code under MacOs (High Sierra) It doesn't give out any errors. Just hanging when trying to play a video or an audio file. Its state is "playing", but nothing is actually being played. I can just toggle between play/pause states of the button without any changes. Do you have any ideas, what can I do with this? Thank you in advance!
When I run this code, the menubar with the File menu does not appear. I am running on Mac OS. Is there something i need to adjust in the code? (Edit: I solved this by adding menu.setNativeMenuBar(False) right after menuBar = self.menuBar().)
This example has been very helpful. My covid-lockdown programming project is writing programs to operate an IP based security camera. This camera, in its normal use, monitors a bird's nest (Osprey) during spring/summer/fall. The camera is setup to save mp4 files (about 20sec. long) to an internal SD card triggered by motion detection. I'm able to ftp these mp4 files to my computer where I can play them using code from the above example. I need some help figuring out how to extend my program to stream mp4 or h.264 straight from the camera to my application's window. I'm currently using mjpeg, but that eats up too much bandwidth for this application. I've searched the internet for a few days but haven't found anything yet. Can you suggest any modifications to the above example?
mjpeg is not using much compression compared to other formats (mp4, h264) and so it's not suitable for streaming over network. You would have to open the network stream with PyQt. Maybe you can set the url with setMedia(QUrl()); but I'm not sure.
try different video formats. PyQt on Mac is using QuickTime technology underneath, try updating QuickTime and if it can play the videos
Thanks for your reply. Of course, I had tried different formats before I wrote this with no success. And no problems with Quick Time with any of these video files...
Finally, this problem disappeared without any actions from my side. Maybe some automatic updates of I don't know what helped...