Python + QT + Gstreamer

Я работаю с PyQt и пытаюсь заставить видео от веб-камеры играть в спокойном виджете. Я нашел учебные руководства для 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 является идентификатором окна виджета, я пытаюсь добраться для отображения вывода в. Когда я выполняю это на 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)

Это соединяет несколько битов, и я не могу протестировать его прямо сейчас, но возможно это будет полезно кому-то.Удачи!

6
задан Ptterb 2 June 2010 в 17:40
поделиться

2 ответа

Понятно! Похоже, мне нужно было заставить разрешение конвейера соответствовать разрешению виджета, в который я накачивал видео:

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

Затем просто добавьте их в конвейер, как и другие элементы, и работает отлично. Господи, сейчас это кажется таким легким, но когда я несколько дней бился головой о стену, это было не так очевидно ...

1
ответ дан 17 December 2019 в 02:27
поделиться

Ptterb, не могли бы вы опубликовать свой полный код, пожалуйста?

Я скопировал ваш код.
В конвейер добавлен fvidscale_cap с:

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)

Из основной программы я создаю новый QWidget и передаю его winId () конструктору Vid.
Виджет начинает загружаться, но вылетает.

В выводе говорится:
должен воспроизводиться
Ошибка сегментации

1
ответ дан 17 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: