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
每秒发出一次,因为 QMediaPlayer
的 notifyInterval
属性 是在那段时间内设置的。因此,您可以将 属性 更改为 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_())
- 使用来自
QVideoProbe
的 VideoFrameProbed
信号:
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_())
我正在创建一个视频播放器,我需要在它上面绘制一些多边形。我正在使用 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
每秒发出一次,因为QMediaPlayer
的notifyInterval
属性 是在那段时间内设置的。因此,您可以将 属性 更改为 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_())
- 使用来自
QVideoProbe
的VideoFrameProbed
信号:
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_())