[Python] Simple PyQT5 Video Player: VLC output scales incorrectly until manual resize. (Simple code example provided)
Posted: 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:
Screenshots showing the problem:
Attempted solutions:
Thank you.
References:
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:
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.
Thank you.
References:
- Ref 1: https://git.videolan.org/?p=vlc/bindings/python.git;a=blob_plain;f=examples/pyqt5vlc.py;hb=HEAD