PyQt 视频帧更新信号(每个视频帧后触发函数) [英] PyQt video frame update signal (Trigger function after each video frame)

查看:188
本文介绍了PyQt 视频帧更新信号(每个视频帧后触发函数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a video player and I need to draw some polygons on top of it. I am using a QGraphicsScene to create this and I need to update the polygons on screen after each frame. I am currently using the QMediaPlayer paired up with a QGraphicsVideoItem to create this. The problem I am having is that the QMediaPlayer doesn't have a signal that activates on each frame. It has positionChanged(), but this only seems to trigger once every second.

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

I tried using QMovie since it does send updates on every frame, but it did not display anything. This is the code I used to implement this.

    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.

The video file I am using is a .avi file and it is 72Mb large.

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

I would really appreciate it if somebody could point me in the right direction on how I could do this. I am currently using PyQt5.

谢谢

推荐答案

有 2 个选项:

  • positionChanged 每秒发出一次,因为 QMediaPlayernotifyInterval 属性是在那个时期设置的.因此,您可以更改该属性,例如更改为 60 毫秒.
  • positionChanged is emited every second because the notifyInterval property of QMediaPlayer is set in that period. So you can change that property, for example to 60 ms.
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 信号:
    • Use the VideoFrameProbed signal from QVideoProbe:
    • 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_())
      

      这篇关于PyQt 视频帧更新信号(每个视频帧后触发函数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆