I am basically building a GUI with pyqt5 supposed to incorporate two videos. To do this, I use QMediaPlayer in combination with QVideoWidget, one for each class. The point is: while the first video plays as expected, the second one refuses to play. It uses exactly the same framework as the first one (one pushbuton for play/pause and one slidebar), and the same structure of code, but the screen remains desperately black when trying to play.
Worse, if I comment the code for the first video, the second now plays normally. Could that mean there is some conflict between the two QMedialPlayers? I can't make sense of that.
Any help would be greatly appreciated.
Here is my code (the GUI looks weird because I have removed most of it for clarity):
from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QPushButton, QLineEdit, QFrame, QHBoxLayout, QCheckBox, QRadioButton, QButtonGroup, QStyle, QSlider, QStackedLayout import sys from tkinter import Tk from PyQt5.QtCore import pyqtSlot, QRect, Qt, QRunnable, QThreadPool, QThread, QObject, QUrl, QSize import time from PyQt5 import QtMultimedia from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer from PyQt5.QtMultimediaWidgets import QVideoWidget from PyQt5.QtGui import QFont from PyQt5.QtGui import QImage, QPalette, QBrush, QIcon, QPixmap class DNN_Viewer(QWidget): def __init__(self, n_filters=2): super(DNN_Viewer, self).__init__() # initialise GUI self.init_gui() # initialise videos to display images self.mp1.play() self.mp1.pause() self.mp2.play() self.mp2.pause() def init_gui(self): # main window root = Tk() screen_width = root.winfo_screenwidth() # screen width screen_height = root.winfo_screenheight() # screen heigth self.width = 1900 # interface width self.heigth = 1000 # interface height self.left = (screen_width - self.width) / 2 # left-center interface self.top = (screen_height - self.heigth) / 2 # top-center interface self.setFixedSize(self.width, self.heigth) self.move(self.left, self.top) self.setStyleSheet("background: white"); # interface background color # bottom left frame self.fm2 = QFrame(self) # creation self.fm2.setGeometry(30, 550, 850, 430) # left, top, width, height self.fm2.setFrameShape(QFrame.Panel); # use panel style for frame self.fm2.setLineWidth(1) # frame line width # video for weights and gradients self.vw1 = QVideoWidget(self) # declare video widget self.vw1.move(50,555) # left, top self.vw1.resize(542,380) # width, height self.vw1.setStyleSheet("background-color:black;"); # set black background # wrapper for the video self.mp1 = QMediaPlayer(self) # declare QMediaPlayer self.mp1.setVideoOutput(self.vw1) # use video widget vw1 as output fileName = "path_to_video_1" # local path to video self.mp1.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) # path to video self.mp1.stateChanged.connect(self.cb_mp1_1) # callback on change state (play, pause, stop) self.mp1.positionChanged.connect(self.cb_mp1_2) # callback to move slider cursor self.mp1.durationChanged.connect(self.cb_mp1_3) # callback to update slider range # play button for video self.pb2 = QPushButton(self) # creation self.pb2.move(50,940) # left, top self.pb2.resize(40,30) # width, height self.pb2.setIconSize(QSize(18,18)) # button text self.pb2.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) # standard triangle icon for play self.pb2.clicked.connect(self.cb_pb2) # callback on click (play/pause) # position slider for video self.sld1 = QSlider(Qt.Horizontal,self) # creation self.sld1.setGeometry( 110, 940, 482, 30) # left, top, width, height self.sld1.sliderMoved.connect(self.cb_sld1) # callback on move # title label self.lb23 = QLabel(self) # creation self.lb23.setText("Loss and accuracy") # label text self.lb23.move(980,10) # left, top self.lb23.setStyleSheet("font-size: 30px; font-family: \ FreeSans; font-weight: bold") # set font and size # top right frame self.fm3 = QFrame(self) # creation self.fm3.setGeometry(980, 50, 850, 430) # left, top, width, height self.fm3.setFrameShape(QFrame.Panel); # use panel style for frame self.fm3.setLineWidth(1) # frame line width # video for loss and accuracy self.vw2 = QVideoWidget(self) # declare video widget self.vw2.move(1000,55) # left, top self.vw2.resize(542,380) # width, height self.vw2.setStyleSheet("background-color:black;"); # set black background # wrapper for the video self.mp2 = QMediaPlayer(self) # declare QMediaPlayer self.mp2.setVideoOutput(self.vw2) # use video widget vw1 as output fileName2 = "path_to_video_2" # local path to video self.mp2.setMedia(QMediaContent(QUrl.fromLocalFile(fileName2))) # path to video self.mp2.stateChanged.connect(self.cb_mp2_1) # callback on change state (play, pause, stop) self.mp2.positionChanged.connect(self.cb_mp2_2) # callback to move slider cursor self.mp2.durationChanged.connect(self.cb_mp2_3) # callback to update slider range # play button for video self.pb3 = QPushButton(self) # creation self.pb3.move(1000,440) # left, top self.pb3.resize(40,30) # width, height self.pb3.setIconSize(QSize(18,18)) # button text self.pb3.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) # standard triangle icon for play self.pb3.clicked.connect(self.cb_pb3) # callback on click (play/pause) # position slider for video self.sld2 = QSlider(Qt.Horizontal,self) # creation self.sld2.setGeometry(1060, 440, 482, 30) # left, top, width, height self.sld2.sliderMoved.connect(self.cb_sld2) # callback on move def cb_mp1_1(self, state): if self.mp1.state() == QMediaPlayer.PlayingState: # if playing, switch button icon to pause self.pb2.setIcon(self.style().standardIcon(QStyle.SP_MediaPause)) elif self.mp1.state() == QMediaPlayer.StoppedState: # if stopped, rewind to first image self.mp1.play() self.mp1.pause() else: self.pb2.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) # if paused, switch button icon to play def cb_mp1_2(self, position): self.sld1.setValue(position) # set slider position to video position def cb_mp1_3(self, duration): self.sld1.setRange(0, duration) # set slider range to video position def cb_pb2(self): if self.mp1.state() == QMediaPlayer.PlayingState: # set to pause if playing self.mp1.pause() else: self.mp1.play() # set to play if in pause def cb_sld1(self, position): self.mp1.setPosition(position) # set video position to slider position def cb_mp2_1(self, state): if self.mp2.state() == QMediaPlayer.PlayingState: # if playing, switch button icon to pause self.pb3.setIcon(self.style().standardIcon(QStyle.SP_MediaPause)) elif self.mp2.state() == QMediaPlayer.StoppedState: # if stopped, rewind to first image self.mp2.play() self.mp2.pause() else: self.pb3.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) # if paused, switch button icon to play def cb_mp2_2(self, position): self.sld2.setValue(position) # set slider position to video position def cb_mp2_3(self, duration): self.sld2.setRange(0, duration) # set slider range to video position def cb_pb3(self): if self.mp2.state() == QMediaPlayer.PlayingState: # set to pause if playing self.mp2.pause() else: self.mp2.play() # set to play if in pause def cb_sld2(self, position): self.mp2.setPosition(position) # set video position to slider position # run GUI def dnn_viewer(): app = QApplication(sys.argv) # initiate app; sys.argv argument is only for OS-specific settings viewer = DNN_Viewer() # create instance of Fil_Rouge_Dashboard class viewer.show() # display dashboard sys.exit(app.exec_()) # allow exit of the figure by clicking on the top right cross # call window function dnn_viewer()