zhiyiYo / PyQt-Fluent-Widgets

A fluent design widgets library based on C++ Qt/PyQt/PySide. Make Qt Great Again.
https://qfluentwidgets.com
GNU General Public License v3.0
5.61k stars 541 forks source link

[Bug]: 视频播放器播放白屏 #853

Closed Finally-Fantasy closed 5 months ago

Finally-Fantasy commented 6 months ago

What happened?

在我自己创建的fluent-windows中,添加一个页面,页面中放置一个widget或者vboxLayout,并添加一个videoWidget,但是play的时候对应区域显示白屏,但是视频声音是正常播放的。在example中的例程可以被正常运行和播放视频 屏幕截图 2024-04-22 094455

Operation System

Windows11 23H2

Python Version

3.7.6 64-bit

PyQt/PySide Version

PyQt 5.15.9

PyQt/PySide-Fluent-Widgets Version

v1.5.0

How to Reproduce?

修改本地视频对应路径 运行main.py 点击确认按键

Minimum code

"""video_mode.py"""
class VideoModeInterface(Ui_VideoMode, QWidget):
    video = ''

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setupUi(self)

        self.choose_video.clicked.connect(self.openVideo)
        self.choose_all.clicked.connect(self.playVideo)

        self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.vBoxLayout.addWidget(self.videoWidget)

    def openVideo(self):
        self.video = QFileDialog.getOpenFileName(self, 'Open file', '/home')

    def playVideo(self):
        self.videoWidget.setVideo(QUrl.fromLocalFile("D:/Users\kp\Videos\ccc/test.mp4"))
        self.videoWidget.play()

"""main.py"""
# coding:utf-8
import sys

from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QIcon, QDesktopServices
from PyQt5.QtWidgets import QApplication
from qfluentwidgets import MessageBox, SplitFluentWindow, FluentTranslator, setThemeColor
from qfluentwidgets import FluentIcon as FIF
from  view.video_mode import VideoModeInterface

class Window(SplitFluentWindow):

    def __init__(self):
        super().__init__()

        # create sub interface
        self.videomodeInterface = VideoModeInterface(self)
        setThemeColor('#FF7744')
        self.initNavigation()
        self.initWindow()

    def initNavigation(self):
        # add sub interface
        self.addSubInterface(self.videomodeInterface, FIF.VIDEO, '视频模式')
        self.navigationInterface.setExpandWidth(280)

    def initWindow(self):
        self.resize(1000, 765)
        self.setWindowIcon(QIcon('logo/detetion.png'))
        self.setWindowTitle('纸板缺陷检测系统')

        desktop = QApplication.desktop().availableGeometry()
        w, h = desktop.width(), desktop.height()
        self.move(w//2 - self.width()//2, h//2 - self.height()//2)

if __name__ == '__main__':
    QApplication.setHighDpiScaleFactorRoundingPolicy(
        Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

    # setTheme(Theme.DARK)

    app = QApplication(sys.argv)

    # install translator
    # translator = FluentTranslator()
    # app.installTranslator(translator)

    w = Window()
    w.show()
    app.exec_()

""" Ui_VideoMode.py """

from PyQt5 import QtCore
from qfluentwidgets import FluentIcon as FIF
from PyQt5.QtWidgets import QWidget, QVBoxLayout
from qfluentwidgets.multimedia import VideoWidget

class Ui_VideoMode(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(960, 810)
        Form.setMinimumSize(QtCore.QSize(0, 0))
        self.Slider = Slider(Form)
        self.Slider.setGeometry(QtCore.QRect(800, 160, 200, 141))
        self.Slider.setObjectName("Slider")
        self.SubtitleLabel_2 = SubtitleLabel(Form)
        self.SubtitleLabel_2.setGeometry(QtCore.QRect(760, 360, 141, 51))
        self.SubtitleLabel_2.setObjectName("SubtitleLabel_2")
        self.SubtitleLabel = SubtitleLabel(Form)
        self.SubtitleLabel.setGeometry(QtCore.QRect(780, 100, 131, 51))

        self.SubtitleLabel.setObjectName("SubtitleLabel")
        self.choose_all = PrimaryPushButton(FIF.ACCEPT, "确定", self)
        self.choose_all.setGeometry(QtCore.QRect(780, 680, 131, 51))
        self.choose_all.setObjectName("choose_all")
        self.Slider_2 = Slider(Form)
        self.Slider_2.setGeometry(QtCore.QRect(800, 430, 200, 161))
        self.Slider_2.setObjectName("Slider_2")
        self.choose_video = PrimaryPushButton(FIF.VIDEO, "选择视频", self)
        self.choose_video.setGeometry(QtCore.QRect(780, 620, 131, 51))
        self.choose_video.setObjectName("choose_video")
        # self.verticalLayoutWidget = QtWidgets.QWidget(Form)
        # self.verticalLayoutWidget.setGeometry(QtCore.QRect(30, 80, 691, 661))
        # self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        # self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        # self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        # self.verticalLayout.setObjectName("verticalLayout")
        self.widget = QWidget(Form)
        self.widget.setGeometry(QtCore.QRect(30, 70, 675, 675))
        self.widget.setObjectName("widget")
        self.vBoxLayout = QVBoxLayout(self.widget)
        self.videoWidget = VideoWidget(self.widget)
        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.SubtitleLabel_2.setText(_translate("Form", "非极大抑制"))
        self.SubtitleLabel.setText(_translate("Form", "置信度"))

from qfluentwidgets import PrimaryPushButton, Slider, SubtitleLabel
AlexZhu2001 commented 6 months ago

无法复现该问题,你试试如下几条

  1. 换个视频试试,比如使用不同的封装格式和不同的编码格式,你也可以提供你的测试视频供大家测试
  2. LAVFilter是否正确安装
  3. 你的路径看起来不太对劲,不要在路径里混用正反斜杠,python一般不区分所以建议只使用/避免转义或者使用r字符串
AlexZhu2001 commented 6 months ago

最好能把你的视频发一下,看看是不是编码导致的

Finally-Fantasy commented 6 months ago

最好能把你的视频发一下,看看是不是编码导致的

我的路径确实书写不规范,这一点已经改正。LAVFilter已安装v0.79。在下面的视频,我分别演示了在 example的deom 和 我的代码 运行同一个视频,可以看到官方例程运行是正常的,而我的界面会闪一下然后白屏

https://github.com/zhiyiYo/PyQt-Fluent-Widgets/assets/95769638/882be02c-9cb5-44dc-9233-f4273ff1accb

[这是否可以说明一些问题。由于这里上传的文件大小限制,我无法直接发出我的测试视频文件 https://wwm.lanzoul.com/im1N51w47kid 如果我将视频压缩将会导致官方例程的videowidget显示黑屏

AlexZhu2001 commented 6 months ago

研究了一下 还是无法复现 由于之前报告过和yolo有冲突 (#644) 所以可能得提供一下详细的环境信息

  1. 是不是使用了conda安装了部分包,如果是,使用conda env export > environment.yml导出所有包
  2. 只使用了pip,那就使用pip freeze > packages.txt导出所有包
Finally-Fantasy commented 6 months ago

研究了一下 还是无法复现 由于之前报告过和yolo有冲突 (#644) 所以可能得提供一下详细的环境信息

  1. 是不是使用了conda安装了部分包,如果是,使用conda env export > environment.yml导出所有包
  2. 只使用了pip,那就使用pip freeze > packages.txt导出所有包

因为不支持yml,我将yml后缀改成了txt environment.txt 同时,我将异常的完整代码上传到github上了。 我的代码

AlexZhu2001 commented 6 months ago

问题出现在Pytorch 1.7.1版本上,和PyQt5一起使用时就会出现这种情况,具体原因还在查,可能不会很快查出来甚至查不出来,但是可以提供几个解决方法: 1.使用1.8.1版本的pytorch,经测试,1.8.1版本是没有问题的 2.我看你应该是要部署yolo,如果是yolo v3-v9的模型,完全可以使用Ultralytics Yolo里给出的方法来部署,常见部署方法是使用onnx模型配合onnxruntime或者trt模型配合NVIDIA TensorRT部署,相比使用pytorch,速度和稳定性都有提升,而且yolo官方也提供了能在最新版本的torch上跑的模型,完全可以用更新的pytorch

AlexZhu2001 commented 6 months ago

还有,我注意到你貌似手动向Designer生成的文件里添加了如下语句:

self.vBoxLayout = QVBoxLayout(self.widget)
self.videoWidget = VideoWidget(self.widget)

这也是不建议的,任何情况下都不要修改uic生成的文件。 其实你可以直接在Designer里完成这些操作的,然后直接提升控件就行

Finally-Fantasy commented 6 months ago

问题出现在Pytorch 1.7.1版本上,和PyQt5一起使用时就会出现这种情况,具体原因还在查,可能不会很快查出来甚至查不出来,但是可以提供几个解决方法: 1.使用1.8.1版本的pytorch,经测试,1.8.1版本是没有问题的 2.我看你应该是要部署yolo,如果是yolo v3-v9的模型,完全可以使用Ultralytics Yolo里给出的方法来部署,常见部署方法是使用onnx模型配合onnxruntime或者trt模型配合NVIDIA TensorRT部署,相比使用pytorch,速度和稳定性都有提升,而且yolo官方也提供了能在最新版本的torch上跑的模型,完全可以用更新的pytorch

感谢您的帮助和建议

Finally-Fantasy commented 6 months ago

问题出现在Pytorch 1.7.1版本上,和PyQt5一起使用时就会出现这种情况,具体原因还在查,可能不会很快查出来甚至查不出来,但是可以提供几个解决方法: 1.使用1.8.1版本的pytorch,经测试,1.8.1版本是没有问题的 2.我看你应该是要部署yolo,如果是yolo v3-v9的模型,完全可以使用Ultralytics Yolo里给出的方法来部署,常见部署方法是使用onnx模型配合onnxruntime或者trt模型配合NVIDIA TensorRT部署,相比使用pytorch,速度和稳定性都有提升,而且yolo官方也提供了能在最新版本的torch上跑的模型,完全可以用更新的pytorch

我已经卸载了虚拟环境中的pytorch,而且本质上(目前状态也是如此)如果我不接入yolo,根本就不需要调用pytorch模块,但是视频仍然无法正常播放。是因为cuda的问题吗

AlexZhu2001 commented 6 months ago

问题出现在Pytorch 1.7.1版本上,和PyQt5一起使用时就会出现这种情况,具体原因还在查,可能不会很快查出来甚至查不出来,但是可以提供几个解决方法: 1.使用1.8.1版本的pytorch,经测试,1.8.1版本是没有问题的 2.我看你应该是要部署yolo,如果是yolo v3-v9的模型,完全可以使用Ultralytics Yolo里给出的方法来部署,常见部署方法是使用onnx模型配合onnxruntime或者trt模型配合NVIDIA TensorRT部署,相比使用pytorch,速度和稳定性都有提升,而且yolo官方也提供了能在最新版本的torch上跑的模型,完全可以用更新的pytorch

我已经卸载了虚拟环境中的pytorch,而且本质上(目前状态也是如此)如果我不接入yolo,根本就不需要调用pytorch模块,但是视频仍然无法正常播放。是因为cuda的问题吗

有可能 我等会看看

AlexZhu2001 commented 6 months ago

你试试看所有的模块中都不要导入pytorch模块,注意,所有关联的模块都不要导入,因为导入过程会执行一遍py文件 另外,能不能说一下你的调试过程:

  1. 是直接用conda删除的pytorch吗
  2. 删除后对于使用了yolo的模块是怎么处理的
AlexZhu2001 commented 6 months ago

在我的环境里,只要不导入pytorch就行,对于cpuonly版本也是一样的,其实我的想法应该是pytorch初始化了某些模块使用了qt的后端,比如PIL好像就有qt后端,所以可能是某些初始化设置导致的

Finally-Fantasy commented 6 months ago

在我的环境里,只要不导入pytorch就行,对于cpuonly版本也是一样的,其实我的想法应该是pytorch初始化了某些模块使用了qt的后端,比如PIL好像就有qt后端,所以可能是某些初始化设置导致的

我是卸载掉pytorch后运行的

AlexZhu2001 commented 6 months ago

在我的环境里,只要不导入pytorch就行,对于cpuonly版本也是一样的,其实我的想法应该是pytorch初始化了某些模块使用了qt的后端,比如PIL好像就有qt后端,所以可能是某些初始化设置导致的

我是卸载掉pytorch后运行的

那就奇怪了,我这里卸载掉pytorch之后就没问题了 然后一下是刚刚的一些发现

  1. 尝试直接使用Qt的复现,是可以正常运行的,所以很奇怪
  2. 根据测试,如果在使用自定义的GraphicsVideoItem,重载paint函数,设置混合模式为SourceAtop或者Difference都可以正常运行,说明和alpha通道有关系,具体的还没测试
AlexZhu2001 commented 6 months ago

在我的环境里,只要不导入pytorch就行,对于cpuonly版本也是一样的,其实我的想法应该是pytorch初始化了某些模块使用了qt的后端,比如PIL好像就有qt后端,所以可能是某些初始化设置导致的

我是卸载掉pytorch后运行的

你conda list打一下包,确定pytorch删干净了吗

Finally-Fantasy commented 6 months ago

在我的环境里,只要不导入pytorch就行,对于cpuonly版本也是一样的,其实我的想法应该是pytorch初始化了某些模块使用了qt的后端,比如PIL好像就有qt后端,所以可能是某些初始化设置导致的

我是卸载掉pytorch后运行的

你conda list打一下包,确定pytorch删干净了吗

干净了,我甚至创建了一个新的虚拟环境,python版本是3.8,只装pyqt和fluent相关,也无法正常播放

AlexZhu2001 commented 6 months ago

那就不清楚具体情况了 我在正常环境无法复现该问题,唯一环境上差别是我是Windows10,不知道是不是这个原因

2455DD commented 5 months ago

我这边复现出同样问题,表现为开始播放后只有音频,对同一个视频官方示例的程序可以正常播放

Finally-Fantasy commented 5 months ago

我这边复现出同样问题,表现为开始播放后只有音频,对同一个视频官方示例的程序可以正常播放

有解决方案吗

2455DD commented 5 months ago

我这边复现出同样问题,表现为开始播放后只有音频,对同一个视频官方示例的程序可以正常播放

有解决方案吗

很遗憾暂时我也还在探索,目前仍在尝试