Short context:
I have a QMainwindow with an mpv player inside. I play videos with mpv, create overlay images with PIL and run it all in the pyqt window. The overlay image is updated more or less every frame of the video.
Here is my issue:
If the mpv picture is large, then updating the overlay images is far too slow (I have optimized a lot to improve performance, using separate processes and threads, only using one overlay etc.). If the picture is small, however, it all works flawlessly (thus indicating that it is not far from satisfactory in performance).
I wouldn't mind losing resolution to gain performance, so I want to have a large window with lower resolution content. Is this possible?
The bottleneck here is mpv's overlay.update
function
My main idea is to zoom the QMainwindow, but I cannot seem to find a way to do this. Any other solution is of course sufficient.
Example code (note that test.mp4 is the hardcoded video, provide anything you have)
#!/usr/bin/env python3
import mpv
import sys
from PIL import Image, ImageDraw
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Test(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.container = QWidget(self)
self.setCentralWidget(self.container)
self.container.setAttribute(Qt.WA_DontCreateNativeAncestors)
self.container.setAttribute(Qt.WA_NativeWindow)
self.w = 1800
self.h = int(self.w / 16 * 9)
self.setFixedSize(self.w, self.h)
self.player = mpv.MPV(wid=str(int(self.container.winId())),
log_handler=print)
self.player.play('test.mp4')
self.overlay = self.player.create_image_overlay()
self.coords = [20, 20, 50, 50]
def play(self):
@self.player.property_observer("time-pos")
def _time_observer(_name: str, value: float) -> None:
for i in range(len(self.coords)):
self.coords[i] = self.coords[i]*2 % self.h
img = Image.new("RGBA", (self.w, self.h), (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
draw.rectangle(self.coords, outline=(255,255,255,255), width=4)
self.overlay.update(img)
app = QApplication(sys.argv)
# This is necessary since PyQT stomps over the locale settings needed by libmpv.
# This needs to happen after importing PyQT before creating the first mpv.MPV instance.
import locale
locale.setlocale(locale.LC_NUMERIC, 'C')
win = Test()
win.show()
win.play()
sys.exit(app.exec_())
Short Summary
Having a large window causes mpv's overlay.update
method to consume too much time/computation. It is acceptable to decrease the dpi (resolution) of the overlay pictures, and even the video, to make it run faster.