Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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).

    video window

    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.

    editor2.png

    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.


Log in to reply