KimJitae
KimJitae

Reputation: 265

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.

Upvotes: 1

Views: 1005

Answers (1)

eyllanesc
eyllanesc

Reputation: 244252

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 {
}

Upvotes: 2

Related Questions