графика поверх видео в Python, экстремальная загрузка ЦП - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь поместить QPixmap поверх элемента видео. Для этого я создал сцену. (Ну, я получил код от кого-то другого, я не понимаю всего этого, я новичок в Python.)

Теперь все это вроде как работает, но производительность оставляет желать лучшего (по крайней мере, на моей (не такой медленной) Catalina Ma c) загрузка процессора огромна. Дело не в видео, «голый» видеоплеер работает хорошо. Теперь мое внутреннее чувство (и пару дней поиска в Google) подсказывает мне, что это из-за чрезмерных обновлений «где-то». Если видео Prores, у меня мерцает (image / black / image et c. Этого не происходит на «голом» плеере. Если видео - это H264, все в порядке. (Оба имеют одинаковую высокую загрузку процессора. )

Есть указатели? Спасибо, Bouke

from PyQt5 import QtWidgets, QtGui, QtCore, QtMultimediaWidgets, QtMultimedia
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *

VIDEO_WIDTH = 800
VIDEO_HEIGHT = 450

########################################
#
########################################
class MyVideoView(QGraphicsView):

    def __init__(self, parent=None):
        super(QGraphicsView, self).__init__(parent)
        # self._main = parent

        self.setBackgroundBrush(Qt.black)

        self._scene = QGraphicsScene(self)
        self.setScene(self._scene)

        self._videoItem = QGraphicsVideoItem()
        self._videoItem.setPos(0, 0)
        self._videoItem.setSize(QSizeF(VIDEO_WIDTH, VIDEO_HEIGHT))
        self._scene.addItem(self._videoItem)

        self._overlay = QPixmap(VIDEO_WIDTH, VIDEO_HEIGHT)
        self._overlay.fill(QColor(0, 150, 0, 150))
        self._graphicsPixmapItem = self._scene.addPixmap(self._overlay)

        self._player = QMediaPlayer(self)
        self._player.setVideoOutput(self._videoItem)

    ########################################
    #
    ########################################
    def loadVideo(self, fn):
        self._player.setMedia(QMediaContent(QUrl.fromLocalFile(fn)))
        self._player.play()



########################################
#
########################################
class Video(QMainWindow):

    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.setWindowTitle("Video window")
        # self.setContentsMargins(-2, -2, -2, -2)  # get rid of black lines around the vid

        self._splitter = QSplitter(Qt.Vertical)
        self.setCentralWidget(self._splitter)
        self._videoView = MyVideoView(self)
        self._splitter.addWidget(self._videoView)

        self._videoView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._videoView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.show()
        self._videoView.loadVideo('/Volumes/Data/videofiles/demo_BITC 2.mov')


    def resizeEvent(self, QResizeEvent):
        _w = self.geometry().width()
        _h = self.geometry().height()
        self._videoView._videoItem.setSize(QSizeF(_w, _h))


        self.vidwidth = int(self._videoView._videoItem.sceneBoundingRect().width())
        self.vidheight = int(self._videoView._videoItem.sceneBoundingRect().height())

        self.vidtop = self._videoView._videoItem.sceneBoundingRect().top()

        # do not get a feedback loop
        try:
            if self.ignorscaling:
                self.ignorscaling = False
                return
        except:
            pass
        _w = self._videoView._videoItem.sceneBoundingRect().right()
        _h = self._videoView._videoItem.sceneBoundingRect().bottom() - self._videoView._videoItem.sceneBoundingRect().top()

        self.ignorscaling = True
        self.resize(_w, _h)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(True)
    w = Video()
    sys.exit(app.exec_())
...