使用PySide在QLabel中显示视频流

5
有人能指点我如何在PySide中创建一个新的QMovie“提供者”吗?
我有一个视频流,想要尽可能简单地显示它(没有音频,只是一系列帧,帧率未知且可变)。这个示例看起来很完美,但我的视频来自于一个非传统的来源。它不是文件,而是一个格式不规范的网络流。我可以轻松编写代码接收每一帧,我的想法是创建一个“QMovie提供者”,以便我可以像上面的示例那样将此流显示在标签上。
我最初的想法是子类化QMovie并覆盖其中几个函数,但是当阅读文档时,我开始对此产生了疑虑,因为我不知道我的实例应该从哪个“设备”中读取。
我在前面提到的文档中注意到QMovie使用QImageReader,因此我的下一个想法是扩展该类并让它从我的流中读取帧。然而,这也带来了类似的问题,例如,“supportedImageFormats()”函数应该怎么办?
我一直在尝试直接更新我的QLabel上的图像,每次收到新帧时都这样做,但是我一直收到错误“QPixmap:在GUI线程之外使用像素图不安全”。
因此,基本上我有点困惑,并且非常感激任何关于如何在PySide应用程序中让QLabel显示我的视频流的指针或教程。
1个回答

9
以下是我如何使其正常工作的方法:
使用信号和槽机制,下面的应用程序可以正常工作。信号/槽机制似乎能够确定在up_camera_callback函数内创建并发射到CameraDisplay.updateFrame函数中的图像来自不同的线程,并采取必要的预防措施。
class CameraDisplay(QtGui.QLabel):
  def __init__(self):
    super(CameraDisplay, self).__init__()

  def updateFrame(self, image):
    self.setPixmap(QtGui.QPixmap.fromImage(image))

class ControlCenter(QtGui.QWidget):
  up_camera_signal = QtCore.Signal(QtGui.QImage)
  up_camera = None

  def __init__(self):
    super(ControlCenter, self).__init__()
    self.up_camera = CameraDisplay()
    self.up_camera_signal.connect(self.up_camera.updateFrame)

    grid = QtGui.QGridLayout()
    grid.setSpacing(10)

    grid.addWidget(self.up_camera, 0, 0)

    self.setLayout(grid)

    self.setGeometry(300, 300, 350, 300)
    self.setWindowTitle('Control Center')
    self.show()

  def up_camera_callback(self, data):
    '''This function gets called by an external thread'''
    try:
      image = QtGui.QImage(data.data, data.width, data.height, QtGui.QImage.Format_RGB888)
      self.up_camera_signal.emit(image)

    except Exception, e:
      print(e)

if __name__ == "__main__":
  app = QtGui.QApplication(sys.argv)
  ex = ControlCenter()
  sys.exit(app.exec_())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接