PyQt视频帧更新信号(每个视频帧后触发函数)

PyQt video frame update signal (Trigger function after each video frame)

我正在创建一个视频播放器,我需要在它上面绘制一些多边形。我正在使用 QGraphicsScene 来创建它,我需要在每一帧之后更新屏幕上的多边形。我目前正在使用 QMediaPlayer 与 QGraphicsVideoItem 配对来创建它。我遇到的问题是 QMediaPlayer 没有在每一帧上激活的信号。它有 positionChanged(),但这似乎每秒只触发一次。

我尝试使用 QMovie,因为它确实会在每一帧上发送更新,但它没有显示任何内容。这是我用来实现这个的代码。

    video_view = QGraphicsView()#view to hold video
    video_item = QGraphicsVideoItem()#video item for scene
    video_scene = QGraphicsScene()#scene for Qgraphics view
    video_view.setScene(video_scene)

    label = QLabel()
    movie = QMovie(self.video_paths[index]) #contains file path
    label.setMovie(movie)
    video_scene.addWidget(label)
    self.vlayout_main_video.addWidget(video_view)

我使用的视频文件是 .avi 文件,大小为 72Mb。

如果有人能指出我如何做到这一点的正确方向,我将不胜感激。我目前正在使用 PyQt5。

谢谢

有2个选项:

  • positionChanged 每秒发出一次,因为 QMediaPlayernotifyInterval 属性 是在那段时间内设置的。因此,您可以将 属性 更改为 60 毫秒。

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

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        scene = QtWidgets.QGraphicsScene(self)
        self.video_view = QtWidgets.QGraphicsView(scene)
        self.setCentralWidget(self.video_view)

        self.player = QtMultimedia.QMediaPlayer(self, QtMultimedia.QMediaPlayer.VideoSurface)
        self.video_item = QtMultimediaWidgets.QGraphicsVideoItem()
        self.player.setVideoOutput(self.video_item)
        scene.addItem(self.video_item)
        file = "/path/of/video"
        self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file)))
        self.player.positionChanged.connect(self.on_positionChanged)
        self.player.setNotifyInterval(60)
        self.player.play()

    @QtCore.pyqtSlot('qint64')
    def on_positionChanged(self, p):
        print(p, QtCore.QTime.currentTime().toString("hh:mm:ss.zzz"))

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())
  • 使用来自 QVideoProbeVideoFrameProbed 信号:

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

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        scene = QtWidgets.QGraphicsScene(self)
        self.video_view = QtWidgets.QGraphicsView(scene)
        self.setCentralWidget(self.video_view)

        self.player = QtMultimedia.QMediaPlayer(self, QtMultimedia.QMediaPlayer.VideoSurface)
        self.video_item = QtMultimediaWidgets.QGraphicsVideoItem()
        self.player.setVideoOutput(self.video_item)
        scene.addItem(self.video_item)
        file = "/path/of/video"
        self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file)))
        self.player.play()

        probe = QtMultimedia.QVideoProbe(self)
        probe.videoFrameProbed.connect(self.on_videoFrameProbed)
        probe.setSource(self.player)

    @QtCore.pyqtSlot()
    def on_videoFrameProbed(self):
        print(QtCore.QTime.currentTime().toString("hh:mm:ss.zzz"))

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())