pythonqtpyqt5pysideqvideowidget

How to rotate video in QVideoWidget in PyQt5


GUI

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'facebio.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(600, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.widget = QVideoWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(10, 10, 500, 500))
        self.widget.setObjectName("widget")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

from PyQt5.QtMultimediaWidgets import QVideoWidget

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Main

from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia

from GUI import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)

        self.mediaPlayer = QtMultimedia.QMediaPlayer(self)
        self.mediaPlayer.setVideoOutput(self.widget)
        # fileName = "/path/of/your/local_file"
        url = QtCore.QUrl.fromLocalFile("./KakaoTalk_20210818_171950283.mp4")
        self.mediaPlayer.setMedia(QtMultimedia.QMediaContent(url))
        self.mediaPlayer.play()

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

I'm testing PyQt5 QVideowidget and I'm having a problem with the video rotating.

The videos I found on the internet didn't have rotation, so I didn't have any problems.

But I'm having trouble rotating the video I took with my phone in QVideowidget.

enter image description here

I didn't turn my phone, I just grabbed it and took the video

enter image description here

In this way, the video taken by QVideoWidget comes out lying down.

enter image description here

As you can see, the video is lying down and I want to rotate this video, is there any way to do it?

I don't want to edit the video information. If there is a way to rotate the media, I would like to have the image information and rotate the media using an if statement.


Solution

  • One possible solution is to use QGraphicsVideoItem:

    import os
    from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia, QtMultimediaWidgets
    
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
    
            self._scene = QtWidgets.QGraphicsScene(self)
            self._gv = QtWidgets.QGraphicsView(self._scene)
    
            self._videoitem = QtMultimediaWidgets.QGraphicsVideoItem()
            self._scene.addItem(self._videoitem)
    
            self._player = QtMultimedia.QMediaPlayer(
                self, QtMultimedia.QMediaPlayer.VideoSurface
            )
            self._player.stateChanged.connect(self.on_stateChanged)
            self._player.setVideoOutput(self._videoitem)
    
            file = os.path.join(os.path.dirname(__file__), "KakaoTalk_20210818_171950283.mp4")
            self._player.setMedia(
                QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file))
            )
            button = QtWidgets.QPushButton("Play")
            button.clicked.connect(self._player.play)
    
            self.resize(640, 480)
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(self._gv)
            lay.addWidget(button)
    
            self._videoitem.setRotation(90)
    
        @QtCore.pyqtSlot(QtMultimedia.QMediaPlayer.State)
        def on_stateChanged(self, state):
            if state == QtMultimedia.QMediaPlayer.PlayingState:
                self._gv.fitInView(self._videoitem, QtCore.Qt.KeepAspectRatio)
    
        def resizeEvent(self, event):
            super().resizeEvent(event)
            self._gv.fitInView(self._videoitem, QtCore.Qt.KeepAspectRatio)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    

    Another possible option is to use Video QML with QQuickWidget:

    import os
    from pathlib import Path
    import sys
    
    from PyQt5 import QtCore, QtWidgets, QtQuickWidgets
    
    CURRENT_DIRECTORY = Path(__file__).resolve().parent
    
    
    class VideoWidget(QtQuickWidgets.QQuickWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.setResizeMode(QtQuickWidgets.QQuickWidget.SizeRootObjectToView)
            qml_filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
            url = QtCore.QUrl.fromLocalFile(qml_filename)
            self.setSource(url)
            self.resize(640, 480)
    
            self.rootObject().setProperty("orientation", 90)  # 90 or 270
    
        @property
        def source(self):
            return self.rootObject().property("source")
    
        @source.setter
        def source(self, url):
            self.rootObject().setProperty("source", url)
    
        def play(self):
            QtCore.QMetaObject.invokeMethod(
                self.rootObject(), "play", QtCore.Qt.DirectConnection
            )
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = VideoWidget()
        filename = os.fspath(CURRENT_DIRECTORY / "KakaoTalk_20210818_171950283.mp4")
        w.source = QtCore.QUrl.fromLocalFile(filename)
        w.play()
        w.show()
        sys.exit(app.exec_())
    

    main.qml

    import QtMultimedia 5.15
    
    Video {
    }