Python + QT + Gstreamer

标签 python pyqt4 gstreamer maemo qt-maemo

我正在使用 PyQt 并尝试从网络摄像头获取视频以在 QT 小部件中播放。我已经找到了 C 和 Qt 的教程,以及 python 和 gtk 的教程,但是对于这个 pyQt 和 gstreamer 的组合没有任何教程。有人让这个工作吗?

这可以很好地播放视频,但在一个单独的窗口中:

self.gcam = gst.parse_launch('v4l2src device=/dev/video0 ! autovideosink')
self.gcam.set_state(gst.STATE_PLAYING)

我需要的是让叠加层正常工作,以便它显示在我的 GUI 上的一个小部件中。谢谢,互联网大师!

好的,我已经取得了很大进展,但仍然需要一些帮助。我实际上是为 Maemo 编写的,但以下代码在我的 Linux 笔记本电脑上运行良好:

class Vid:
    def __init__(self, windowId):
    self.player = gst.Pipeline("player")
    self.source = gst.element_factory_make("v4l2src", "vsource")
    self.sink = gst.element_factory_make("autovideosink", "outsink")
    self.source.set_property("device", "/dev/video0")
    self.scaler = gst.element_factory_make("videoscale", "vscale")
    self.window_id = None
    self.windowId = windowId

    self.player.add(self.source, self.scaler, self.sink)
    gst.element_link_many(self.source,self.scaler, self.sink)

    bus = self.player.get_bus()
    bus.add_signal_watch()
    bus.enable_sync_message_emission()
    bus.connect("message", self.on_message)
    bus.connect("sync-message::element", self.on_sync_message)

    def on_message(self, bus, message):
    t = message.type
    if t == gst.MESSAGE_EOS:
        self.player.set_state(gst.STATE_NULL)
    elif t == gst.MESSAGE_ERROR:
       err, debug = message.parse_error()
       print "Error: %s" % err, debug
       self.player.set_state(gst.STATE_NULL)

    def on_sync_message(self, bus, message):
    if message.structure is None:
        return
    message_name = message.structure.get_name()
    if message_name == "prepare-xwindow-id":
        win_id = self.windowId
        assert win_id
        imagesink = message.src
        imagesink.set_property("force-aspect-ratio", True)
        imagesink.set_xwindow_id(win_id)
    def startPrev(self):
    self.player.set_state(gst.STATE_PLAYING)
    print "should be playing"
vidStream = Vid(wId)
vidStream.startPrev()

其中 wId 是我试图在其中显示输出的小部件的窗口 ID。当我在 N900 上运行它时,屏幕变黑并闪烁。有任何想法吗?我快死在这里了!

编辑:我被要求发布完整的代码,虽然我仍然需要稍微清理一下,但这里是相关部分:

self.cameraWindow = QtGui.QWidget(self)
self.cameraWindow.setGeometry(QtCore.QRect(530, 20, 256, 192))
self.cameraWindow.setObjectName("cameraWindow")
self.cameraWindow.setAttribute(0, 1); # AA_ImmediateWidgetCreation == 0
self.cameraWindow.setAttribute(3, 1); # AA_NativeWindow == 3

global wId
wId = self.cameraWindow.winId()

self.camera = Vid(wId)

self.camera.startPrev()

class Vid:
    def __init__(self, windowId):
    self.player = gst.Pipeline("player")
    self.source = gst.element_factory_make("v4l2src", "vsource")
    self.sink = gst.element_factory_make("autovideosink", "outsink")
    self.source.set_property("device", "/dev/video0")
    #self.scaler = gst.element_factory_make("videoscale", "vscale")
    self.fvidscale = gst.element_factory_make("videoscale", "fvidscale")
    self.fvidscale_cap = gst.element_factory_make("capsfilter", "fvidscale_cap")
    self.fvidscale_cap.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=256, height=192'))
    self.window_id = None
    self.windowId = windowId
    print windowId

    self.player.add(self.source, self.fvidscale, self.fvidscale_cap, self.sink)
    gst.element_link_many(self.source,self.fvidscale, self.fvidscale_cap, self.sink)

    bus = self.player.get_bus()
    bus.add_signal_watch()
    bus.enable_sync_message_emission()
    bus.connect("message", self.on_message)
    bus.connect("sync-message::element", self.on_sync_message)

    def on_message(self, bus, message):
    t = message.type
    if t == gst.MESSAGE_EOS:
        self.player.set_state(gst.STATE_NULL)
    elif t == gst.MESSAGE_ERROR:
       err, debug = message.parse_error()
       print "Error: %s" % err, debug
       self.player.set_state(gst.STATE_NULL)

    def on_sync_message(self, bus, message):
    if message.structure is None:
        return
    message_name = message.structure.get_name()
    if message_name == "prepare-xwindow-id":
        win_id = self.windowId
        assert win_id
        imagesink = message.src
        imagesink.set_property("force-aspect-ratio", True)
        imagesink.set_xwindow_id(win_id)
    def startPrev(self):
    self.player.set_state(gst.STATE_PLAYING)
    def pausePrev(self):
    self.player.set_state(gst.STATE_NULL)

这是拼凑的一些内容,我现在无法测试,但也许会对某些人有所帮助。祝你好运!

最佳答案

如果您碰巧在 Linux 以外的平台上使用 PySide 而不是 PyQt,则 winId() 返回一个 PyCObject can't be used directly with native functions or other modules .就我而言,在 Microsoft Windows 上将 GStreamer (pygst) 与 PySide 结合使用时,这会派上用场:

from ctypes import pythonapi, c_void_p, py_object
...
if message_name == 'prepare-xwindow-id':
    # convert winId from PyCObject to void pointer
    pythonapi.PyCObject_AsVoidPtr.restype = c_void_p
    pythonapi.PyCObject_AsVoidPtr.argtypes = [py_object]
    hWnd = pythonapi.PyCObject_AsVoidPtr(self.videoWidget.winId())

    # set window handle to video sink
    self.videoSink.set_xwindow_id(hWnd)

关于Python + QT + Gstreamer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2398958/

相关文章:

python - 检查一个 numpy 数组中有多少个 numpy 数组与另一个不同大小的 numpy 数组中的其他 numpy 数组相等

python - 使用pypi安装scrapy时出错

python - 如何在pyqt中将数据从对话框窗口检索到主窗口?

python - Pyside PyQt,如何将 Key_Delete 连接到 4 个不同的 QListWidget

python - 如何在 Pyqt4 中设置 QTableView 标题名称

ffmpeg - 具有 LGPL 元素的 gstreamer rtsp 流媒体链

c++ - 使用 OpenCV 访问相机(通过 GStreamer)

python 3 : for-loop break and else (if statement)

python - PyUnicodeUCS4_FromEncodedObject 错误

python - Qt : How to render 3D animation shapes over a camera video stream?