简短的上下文:
我有一个 QMainwindow,里面有一个 mpv 播放器。我用 mpv 播放视频,用 PIL 创建覆盖图像并在 pyqt 窗口中运行它。覆盖图像或多或少地在视频的每一帧中更新。
这是我的问题:
如果 mpv 图片很大,那么更新叠加图像就太慢了(我已经优化了很多以提高性能,使用单独的进程和线程,只使用一个叠加等)。但是,如果图片很小,则一切都完美无缺(因此表明它在性能上并不令人满意)。
我不介意为了获得性能而失去分辨率,所以我想要一个带有较低分辨率内容的大窗口。这可能吗?
这里的瓶颈是mpv的overlay.update
功能
我的主要想法是缩放 QMainwindow,但我似乎找不到这样做的方法。任何其他解决方案当然就足够了。
示例代码(请注意 test.mp4 是硬编码的视频,提供您拥有的任何内容)
#!/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_())
简短的摘要
具有大窗口会导致 mpv 的overlay.update
方法消耗过多的时间/计算。降低叠加图片甚至视频的 dpi(分辨率)以使其运行更快是可以接受的。