QtVideoWidget Video Stretching
-
Hello,
I am using a QVideoWidget to display a video in my application. Although I have KeepAspectRatio set, when I resize the window the video becomes stretched (see image).
I would like the aspect ratio of the video to be maintained. Any idea how I can achieve this? My current widget code is below.
class Editor(QWidget): def __init__(self, video_filename, parent=None): super().__init__(parent) main_layout = QVBoxLayout() video = QVideoWidget() video.setAspectRatioMode(Qt.KeepAspectRatio) main_layout.addWidget(video) play_button = QPushButton("Play") play_button.clicked.connect(self.play) main_layout.addWidget(play_button) self.player = QMediaPlayer() self.player.setMedia(QUrl.fromLocalFile(video_filename)) self.player.setVideoOutput(video) self.setLayout(main_layout) @Slot() def play(self): self.player.play()
-
Just a follow up, the desired output is something like the image below where the aspect ratio of the video is preserved.
Currently, when I resize the window, the video flickers and seems to preserve the aspect ratio with black bars like in the image above, but when I release the cursor the video becomes stretched.
I'm on Ubuntu 18.04 with GStreamer 1.14.5 and Qt 5.15.0
-
I couldn't get QVideoWidget to maintain the video's aspect ratio. Maybe this is a bug in QVideoWidget? I managed to get it working by switching to QGraphicsVideoItem on a QGraphicsView. Others may find my code below useful.
class Editor(QWidget): def __init__(self, video_filename, parent=None): super().__init__(parent) main_layout = QVBoxLayout() self.setContentsMargins(0, 0, 0, 0) self.setMinimumSize(640, 480) self.item = QGraphicsVideoItem() self.item.setAspectRatioMode(Qt.KeepAspectRatio) self.scene = QGraphicsScene(self) self.scene.addItem(self.item) self.scene.setBackgroundBrush(Qt.black) self.view = QGraphicsView(self.scene) self.view.setRenderHint(QPainter.Antialiasing, True) self.view.setRenderHint(QPainter.SmoothPixmapTransform, True) self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) main_layout.addWidget(self.view) self.player = QMediaPlayer(self, QMediaPlayer.VideoSurface) self.player.setMedia(QUrl.fromLocalFile(video_filename)) self.player.setVideoOutput(self.item) self.setLayout(main_layout) self.player.play() def resizeEvent(self, event: QResizeEvent): self.view.fitInView(self.item, Qt.KeepAspectRatio)
The image quality of the video is not as good as QVideoWidget. Setting SmoothPixmapTransform and Antialising render hints improved it a little, but it's still below par. Any tips to improve this would be great.