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