Python + QT + Gstreamer

I am working with PyQt and trying to get video from a webcam to play a QT widget. I found tutorials for C and Qt, as well as for python and gtk, but NOTHING for this combination of pyQt and gstreamer. Anyone get this job?

Video playback is excellent, but in a separate window:

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

I need the overlay to work so that it appears in the widgets of my GUI. Thank you Internet guru!

ok, so I got a lot more, but still need some help. I actually write this for Maemo, but the following code works fine on my linux laptop:

 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() 

where wId is the window identifier of the im widget trying to display the output. When I launch it on the N900, the screen turns black and blinks. Any ideas? I'm dying here!

EDIT: I was asked to publish the full code, and although I still need to clean it up a bit, here's what you need to do:

 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) 

This is a combination of several bits, and I cannot check it right now, but maybe it will be useful to someone. Good luck

+6
python gstreamer pyqt4 maemo
source share
4 answers

Got! Looks like I needed to make the resolution of the pipeline match the resolution of the widget in which I uploaded the video:

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'))

Then just add them to the pipeline, like the other elements, and it works great. Man, it seems so easy to look at it now, but when I banged my head on the wall for several days, it was not so obvious ...

+1
source share

If you use PySide instead of PyQt on a platform other than Linux, winId () returns PyCObject, which cannot be used directly with built-in functions or other modules . In my case, this came in handy when using GStreamer (pygst) with PySide on Microsoft Windows:

 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) 
+3
source share

Ptterb can you post your full code please?

I copied your code.
Added fvidscale_cap to the pipeline:

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

In the main program, I create a new QWidget and pass it winId () to the Vid constructor.
The widget starts loading, but it crashes.

Output:
should play
Segmentation error

+1
source share

The pasted code does not show gobject loading, which cannot be undone. It took me a while to figure out what was missing. Thank you June for having a working audio example.

 import gobject, pygst pygst.require('0.10') import gst from PyQt4.QtGui import QMainWindow, QWidget, QApplication import sys class Video(QMainWindow): def __init__(self): QMainWindow.__init__(self) container = QWidget() self.setCentralWidget(container) self.windowId = container.winId() self.setGeometry(300,300,640,480) self.show() def setUpGst(self): self.player = gst.Pipeline("player") source = gst.element_factory_make("v4l2src", "vsource") sink = gst.element_factory_make("xvimagesink", "sink") fvidscale_cap = gst.element_factory_make("capsfilter", "fvidscale_cap") fvidscale = gst.element_factory_make("videoscale", "fvidscale") caps = gst.caps_from_string('video/x-raw-yuv') fvidscale_cap.set_property('caps', caps) source.set_property("device", "/dev/video0") self.player.add(source, fvidscale, fvidscale_cap, sink) gst.element_link_many(source,fvidscale, fvidscale_cap, 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) print "end of message" 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_xwindow_id(win_id) def startPrev(self): self.player.set_state(gst.STATE_PLAYING) print "should be playing" if __name__ == "__main__": gobject.threads_init() app = QApplication(sys.argv) video = Video() video.setUpGst() video.startPrev() sys.exit(app.exec_()) 
+1
source share

All Articles