Page 1 of 1

[Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided)

Posted: 25 May 2020 21:42
by Elus
Hi all,

I am trying to accomplish something very simple: playing 2 videos consecutively using a QLabel & a VLC media list player.

I have succeeded in doing this using the tutorial I found (See: ref 1). However, here's a weird bug I keep running into.

The VLC output initially fits the output QLabel perfectly fine (it takes up the entire label). The moment the second video begins playing, VLC output only takes up a small part of the QLabel.

However, if I resize the video player after the second video starts playing, the output is correctly scaled again!

A self-contained, 50-line snippet example to reproduce the problem:

Code: Select all

import sys import vlc from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLabel class SimplePlayer(QMainWindow): """ Extremely simple video player using libVLC. Consists of vertical layout, widget, and a QLabel """ def __init__(self, master=None): QMainWindow.__init__(self, master) # Define file variables self.playlist = ['video_file_1.mp4', 'video_file_2.mp4'] # Define the QT-specific variables we're going to use self.vertical_box_layout = QVBoxLayout() self.central_widget = QWidget(self) self.video_frame = QLabel() # Define the VLC-specific variables we're going to use self.vlc_instance = vlc.Instance('--quiet') self.vlc_player = self.vlc_instance.media_list_player_new() self.media_list = self.vlc_instance.media_list_new(self.playlist) # Create the user interface, set up the player, and play the 2 videos self.create_user_interface() self.video_player_setup() self.vlc_player.play() def video_player_setup(self): """Sets media list for the VLC player and then sets VLC's output to the video frame""" self.vlc_player.set_media_list(self.media_list) self.vlc_player.get_media_player().set_nsobject(int(self.video_frame.winId())) def create_user_interface(self): """Create a 1280x720 UI consisting of a vertical layout, central widget, and QLabel""" self.setCentralWidget(self.central_widget) self.vertical_box_layout.addWidget(self.video_frame) self.central_widget.setLayout(self.vertical_box_layout) self.resize(1280, 720) if __name__ == '__main__': app = QApplication([]) player = SimplePlayer() player.show() sys.exit(app.exec_())

Screenshots showing the problem:
Image
Image


Attempted solutions:
  • Tried using QMacCocoaViewContainer instead of QLabel
  • Tried setting self.video_frame.setScaledContents(True)
  • I tried checking if the pixmap for the label has changed but amazingly, pyQT returns None for the pixmap. Is VLC doing something special here? Typically, you'd set an image on a QLabel using a pixmap but VLC seems to be going around this.
Any help with this would be much appreciated!

Thank you.

References:
  • Ref 1: https://git.videolan.org/?p=vlc/bindings/python.git;a=blob_plain;f=examples/pyqt5vlc.py;hb=HEAD

Re: [Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided

Posted: 09 Nov 2020 21:20
by Timothy Grove
Did you ever find a fix for this?

I am facing a similar problem with VLC 3.0.11.1 on macOS Mojave and Sierra, which doesn't occur with VLC 2 or the early releases of 3.0. Sometimes videos do resize properly, but mostly they either don't scale up or don't scale down to fit their display window when initially loaded, until I manually resize the window. This doesn't seem to be an issue on Windows or Linux.

I can replicate this in the sample project located at: https://raw.githubusercontent.com/oaube ... s/qtvlc.py, which I've updated and included below:

Code: Select all

#! /usr/bin/python3 # https://raw.githubusercontent.com/oaubert/python-vlc/master/examples/qtvlc.py import sys import os.path import vlc from PyQt5 import QtGui, QtCore, QtWidgets unicode = str # Python 3 class Player(QtWidgets.QMainWindow): """A simple Media Player using VLC and Qt """ def __init__(self, master=None): QtWidgets.QMainWindow.__init__(self, master) self.setWindowTitle("Media Player") self.instance = vlc.Instance() self.mediaplayer = self.instance.media_player_new() self.createUI() self.isPaused = False def createUI(self): self.widget = QtWidgets.QWidget(self) self.setCentralWidget(self.widget) self.videoframe = QtWidgets.QFrame() self.palette = self.videoframe.palette() self.palette.setColor (QtGui.QPalette.Window, QtGui.QColor(0,0,0)) self.videoframe.setPalette(self.palette) self.videoframe.setAutoFillBackground(True) self.positionslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) self.positionslider.setToolTip("Position") self.positionslider.setMaximum(1000) self.positionslider.sliderMoved.connect(self.setPosition) self.hbuttonbox = QtWidgets.QHBoxLayout() self.playbutton = QtWidgets.QPushButton("Play") self.hbuttonbox.addWidget(self.playbutton) self.playbutton.clicked.connect(self.PlayPause) self.stopbutton = QtWidgets.QPushButton("Stop") self.hbuttonbox.addWidget(self.stopbutton) self.stopbutton.clicked.connect(self.Stop) self.hbuttonbox.addStretch(1) self.volumeslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self) self.volumeslider.setMaximum(100) self.volumeslider.setValue(self.mediaplayer.audio_get_volume()) self.volumeslider.setToolTip("Volume") self.hbuttonbox.addWidget(self.volumeslider) self.volumeslider.valueChanged.connect(self.setVolume) self.vboxlayout = QtWidgets.QVBoxLayout() self.vboxlayout.addWidget(self.videoframe) self.vboxlayout.addWidget(self.positionslider) self.vboxlayout.addLayout(self.hbuttonbox) self.widget.setLayout(self.vboxlayout) open = QtWidgets.QAction("&Open", self) open.triggered.connect(self.OpenFile) exit = QtWidgets.QAction("&Exit", self) exit.triggered.connect(sys.exit) menubar = self.menuBar() filemenu = menubar.addMenu("&File") filemenu.addAction(open) filemenu.addSeparator() filemenu.addAction(exit) self.timer = QtCore.QTimer(self) self.timer.setInterval(200) self.timer.timeout.connect(self.updateUI) def PlayPause(self): if self.mediaplayer.is_playing(): self.mediaplayer.pause() self.playbutton.setText("Play") self.isPaused = True else: if self.mediaplayer.play() == -1: self.OpenFile() return self.mediaplayer.play() self.playbutton.setText("Pause") self.timer.start() self.isPaused = False def Stop(self): self.mediaplayer.stop() self.playbutton.setText("Play") def OpenFile(self, filename=None): if not filename: filename = QtWidgets.QFileDialog.getOpenFileName(self, "Open File", os.path.expanduser('~'))[0] if not filename: return self.media = self.instance.media_new(filename) self.mediaplayer.set_media(self.media) self.media.parse() self.setWindowTitle(self.media.get_meta(0)) if sys.platform.startswith('linux'): # for Linux using the X Server self.mediaplayer.set_xwindow(self.videoframe.winId()) elif sys.platform == "win32": # for Windows self.mediaplayer.set_hwnd(self.videoframe.winId()) elif sys.platform == "darwin": # for MacOS self.mediaplayer.set_nsobject(int(self.videoframe.winId())) self.PlayPause() def setVolume(self, Volume): self.mediaplayer.audio_set_volume(Volume) def setPosition(self, position): self.mediaplayer.set_position(position / 1000.0) def updateUI(self): self.positionslider.setValue(self.mediaplayer.get_position() * 1000) if not self.mediaplayer.is_playing(): self.timer.stop() if not self.isPaused: self.Stop() if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) player = Player() player.show() player.resize(640, 480) if sys.argv[1:]: player.OpenFile(sys.argv[1]) sys.exit(app.exec_())
I moved up from VLC 3.0.3 to overcome an issue stated in the changelog for 3.0:
Changes between 3.0.8 and 3.0.9:
---------------------------------

macOS:
* Use a layer based video output on 10.14 and higher, which should
fix various rendering issues where the vout would glitch between
a wrong size and the correct size.
But now I've got a different problem! Any ideas/suggestions welcome.

Re: [Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided

Posted: 09 Nov 2020 21:27
by Timothy Grove
I meant to say macOS Mojave and Catalina; not Sierra. My display uses:

Intel HD Graphics 4000:

Chipset Model: Intel HD Graphics 4000
Type: GPU
Bus: Built-In
VRAM (Dynamic, Max): 1536 MB
Vendor: Intel
Device ID: 0x0166
Revision ID: 0x0009
Metal: Supported, feature set macOS GPUFamily1 v4

Re: [Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided

Posted: 11 Nov 2020 15:12
by Timothy Grove
I've now added this as separate topic: "Video doesn't scale until manual resize (macOS)".

Re: [Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided

Posted: 12 Nov 2020 06:08
by mfkl
so according to https://forum.videolan.org/viewtopic.ph ... 45#p510745, this regression was introduced in 3.0.7. Can you confirm as well, OP?

Re: [Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided

Posted: 14 Nov 2020 13:33
by Timothy Grove
Sorry, I don't know what you mean by "OP" ???

Re: [Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided

Posted: 16 Nov 2020 04:09
by mfkl
Original Poster, so Elus.