Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 缩放主窗口_Python_Pyqt5_Qmainwindow_Mpv - Fatal编程技术网

Python 缩放主窗口

Python 缩放主窗口,python,pyqt5,qmainwindow,mpv,Python,Pyqt5,Qmainwindow,Mpv,短上下文: 我有一个QMainwindow,里面有一个mpv播放器。我使用mpv播放视频,使用PIL创建覆盖图像,并在pyqt窗口中运行所有这些。覆盖图像或多或少会在视频的每一帧更新 这是我的问题: 如果mpv图片很大,那么更新覆盖图片的速度就太慢了(为了提高性能,我做了很多优化,使用单独的进程和线程,只使用一个覆盖等等)。然而,如果图片很小,那么它的工作就完美无缺(这表明它的性能并不令人满意) 我不介意为了获得性能而降低分辨率,所以我希望有一个分辨率较低的大窗口。这可能吗 这里的瓶颈是mpv的

短上下文:

我有一个QMainwindow,里面有一个mpv播放器。我使用mpv播放视频,使用PIL创建覆盖图像,并在pyqt窗口中运行所有这些。覆盖图像或多或少会在视频的每一帧更新

这是我的问题:

如果mpv图片很大,那么更新覆盖图片的速度就太慢了(为了提高性能,我做了很多优化,使用单独的进程和线程,只使用一个覆盖等等)。然而,如果图片很小,那么它的工作就完美无缺(这表明它的性能并不令人满意)

我不介意为了获得性能而降低分辨率,所以我希望有一个分辨率较低的大窗口。这可能吗

这里的瓶颈是mpv的
overlay.update
功能

我的主要想法是缩放QMainwindow,但我似乎找不到这样做的方法。当然,任何其他解决方案都已足够

示例代码(请注意test.mp4是硬编码视频,请提供您所有的内容)

简短摘要


拥有一个大窗口会导致mpv的
覆盖。update
方法消耗太多的时间/计算。可以降低叠加图片甚至视频的dpi(分辨率)以使其运行更快。

从源代码中可以看到,
update
似乎每次都会创建一个新的PIL.Image,也许您可以对图像进行一些缓存(基于当前分辨率)并直接使用mpv实例调用
self.command('overlay\u add
,…)`。我无法测试这一点,也不能保证它会严重提高性能,因为覆盖对象通常不打算设置动画。目的是在
覆盖中调用
to_bytes
。创建一个新的图像实际上是相当便宜的。我曾考虑过兑现,但在视频中进行帧步进和查找时会变得非常复杂。不幸的是,对于你的简单示例,我帮不了你那么多(我想你脑子里除了随机矩形之外还有别的想法),但是我建议从一个基本的例子开始,创建一个带有固定图像集的简单缓存,看看是否有实际的改进。如果是这样,您可以创建一个自定义对象,根据大小和时间戳返回图像,并手动调用
instance.command('overlay\u add',…)
。您的问题的实际答案是无法“缩放”小部件(无论如何,这与您希望的情况不同)特别是考虑到mpv对象实际上是嵌入在qt小部件中的外来窗口对象,并且视频播放也意味着底层视频系统可能正在进行一些您无法控制的软件/硬件覆盖。唯一的选择是完全避免使用mpv,而是使用它。事实上,我非常想画矩形,虽然不是随机的,但我认为这个例子应该足够了。我将用一个更大的窗口编辑问题中的代码,您将看到它不再足够快地更新矩形。缓存可以工作,但当允许在视频中搜索时会很麻烦,而且应该没有必要,因为我正在绘制非常简单的图像。问题似乎很简单,但解决方案却变得过于复杂。
#!/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_())