PyQt5 + Gstreamer

Posted

技术标签:

【中文标题】PyQt5 + Gstreamer【英文标题】: 【发布时间】:2015-04-01 23:29:35 【问题描述】:

我正在尝试将视频从网络摄像头流式传输到使用 PyQt5 和 Gstreamer 制作的 GUI。到目前为止,我得到了一个包含此代码的视频:

import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
GObject.threads_init()
Gst.init(None)

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class WebCam(QMainWindow):
"""Form for Streaming a WebCam"""
def __init__(self, parent = None):
    super(WebCam, self).__init__(parent)
    self.display = QWidget()
    self.windowId = self.display.winId()
    self.setGeometry(300,300,640,480)
    self.setWindowTitle("WebCam Streaming")

def setUpGst(self):
    portUDP_RTP = 5800
    self.WebCamPipe = Gst.Pipeline() # define the GStreamer Pipeline
    self.UDP_RTP = Gst.ElementFactory.make('udpsrc', None) 
    self.UDP_RTP.set_property('port', portUDP_RTP)
    self.WebCamPipe.add(self.UDP_RTP) # Add Elements to Pipeline
    cameraCaps = Gst.Caps.from_string('application/x-rtp, encoding-name=JPEG,payload=26')
    self.capsFilter = Gst.ElementFactory.make('capsfilter', None)
    self.capsFilter.set_property('caps', cameraCaps)        
    self.WebCamPipe.add(self.capsFilter) # Add Elements to Pipeline
    self.UDP_RTP.link(self.capsFilter)  # Link Elements of Pipeline
    self.rtpjpegdepay = Gst.ElementFactory.make('rtpjpegdepay', None) 
    self.WebCamPipe.add(self.rtpjpegdepay) # Add Elements to Pipeline
    self.capsFilter.link(self.rtpjpegdepay)  
    self.jpegdec = Gst.ElementFactory.make('jpegdec', None) 
    self.WebCamPipe.add(self.jpegdec) 
    self.rtpjpegdepay.link(self.jpegdec)        
    self.autovideosink = Gst.ElementFactory.make('autovideosink', None)
    self.WebCamPipe.add(self.autovideosink) 
    self.jpegdec.link(self.autovideosink)
    bus =  self.WebCamPipe.get_bus()
    bus.add_signal_watch()
    bus.enable_sync_message_emission()
    bus.connect('sync-message::element', self.on_sync_message)

def on_sync_message(self, bus, msg):        
    if msg.get_structure().get_name() == 'prepare-window-handle':
        msg.src.set_window_handle(self.windowId)    

def startPrev(self):
    self.WebCamPipe.set_state(Gst.State.PLAYING)
    print("should be playing")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    screen = WebCam()
    screen.setUpGst()
    screen.startPrev()
    screen.show
    sys.exit(app.exec_()) 

我需要让叠加层正常工作,以便它显示在我的 GUI 上的小部件中。我认为问题在于这部分代码

bus.connect('sync-message::element', self.on_sync_message)

它也给了我这个错误信息:

Traceback (most recent call last):
  File "WebCamWidget.py", line 66, in on_sync_message
    msg.src.set_window_handle(self.windowId)    
AttributeError: '__main__.GstXvImageSink' object has no attribute 'set_window_handle'

【问题讨论】:

【参考方案1】:

我找到了解决办法,就是从gi.repository导入GstVideo,正确的代码行应该变成:

    from gi.repository import GObject, Gst, GstVideo   

有关更多信息,您可以访问以下两个链接:

1 - https://wiki.ubuntu.com/Novacut/GStreamer1.0#Using_GStreamer_1.0_from_Python

2 - http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/webcam-1.0

【讨论】:

特别是,如果您有多个 .py 文件,则 GstVideo 导入必须在调用 Gst.init() 的文件中。

以上是关于PyQt5 + Gstreamer的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5快速入门

python pyqt5 自定义信号和槽

PyQt5 和 Anaconda:ModuleNotFoundError:没有名为“PyQt5”的模块

PyQt5 与 QML

PyQt5快速入门PyQt5信号槽机制

PyQt5快速入门PyQt5布局管理