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

This forum is about all development around libVLC.
Elus
New Cone
New Cone
Posts: 1
Joined: 25 May 2020 20:42

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

Postby Elus » 25 May 2020 21:42

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

Timothy Grove
Blank Cone
Blank Cone
Posts: 33
Joined: 07 Sep 2011 13:17

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

Postby Timothy Grove » 09 Nov 2020 21:20

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.

Timothy Grove
Blank Cone
Blank Cone
Posts: 33
Joined: 07 Sep 2011 13:17

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

Postby Timothy Grove » 09 Nov 2020 21:27

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

Timothy Grove
Blank Cone
Blank Cone
Posts: 33
Joined: 07 Sep 2011 13:17

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

Postby Timothy Grove » 11 Nov 2020 15:12

I've now added this as separate topic: "Video doesn't scale until manual resize (macOS)".

mfkl
Developer
Developer
Posts: 740
Joined: 13 Jun 2017 10:41

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

Postby mfkl » 12 Nov 2020 06:08

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?
https://mfkl.github.io

Timothy Grove
Blank Cone
Blank Cone
Posts: 33
Joined: 07 Sep 2011 13:17

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

Postby Timothy Grove » 14 Nov 2020 13:33

Sorry, I don't know what you mean by "OP" ???

mfkl
Developer
Developer
Posts: 740
Joined: 13 Jun 2017 10:41

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

Postby mfkl » 16 Nov 2020 04:09

Original Poster, so Elus.
https://mfkl.github.io


Return to “Development around libVLC”

Who is online

Users browsing this forum: No registered users and 5 guests