Как: создать видеочат с помощью gst и python и показать видео инициатора и принимающего в одном окне gtk

Я разрабатываю видеочат, используя gst и python. где я хотел бы просматривать веб-камеру конечного пользователя, а также хочу просматривать свою собственную веб-камеру в одном окне gtk (аналогично видеочату сочувствия).

для этого я использовал объект gst.Tee и создал 2 очереди, одна из которых свяжет результат с локальным окном gtk, а вторая очередь свяжет тот же видеопоток с объектом сеанса.

gst.Tee выполнили задачу, но также уменьшили скорость видеочата, и видео идет позже, чем аудио. (Я использовал другой поток для аудиосессии)

вот, фрагмент кода:

self.pipeline = gst.Pipeline()

bus = self.pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', self._on_gst_message)

self.src_bin = gst.element_factory_make("autovideosrc", "src")
autovideosinkLocal = gst.element_factory_make("autovideosink", "autovideosinkLocal")
tee = gst.element_factory_make('tee', "tee")
queueLocal = gst.element_factory_make("queue", "queueLocal")
queueSend = gst.element_factory_make("queue", "queueSend")
self.pipeline.add(self.src_bin, tee, queueLocal, autovideosinkLocal, queueSend)
gst.element_link_many(self.src_bin, tee)
tee.link(queueLocal)
queueLocal.link(autovideosinkLocal)
tee.link(queueSend)
queueSend.get_pad('src').link(self.p2psession.get_property('sink-pad'))
self.pipeline.set_state(gst.STATE_PLAYING)

Как бы я ускорил видеочат (например, если бы я использовал один приемник и отображал только видео получателя, он отлично работал)?

Есть ли другой способ сделать то же самое?

Спасибо!


person Yajushi    schedule 01.08.2011    source источник


Ответы (1)


Я воздерживался от ответа, но, поскольку никто больше не взвешивал, я попробую.

Я не уверен, что это будет связано с веб-камерой (хотя, вероятно, будет), но вы можете создать две области рисования (gtk.DrawingArea) в PyGTK для ваших двух экранов. Затем вы можете подключить свое видео к ним.

Я делаю что-то подобное в своем коде для воспроизведения видео. Для этого может потребоваться создать два отдельных приемника, но, честно говоря, я не уверен. (Если кто-то может еще больше развить эту идею, пожалуйста, не стесняйтесь делать это в комментариях.)

Вот фрагмент кода, который я использую прямо сейчас (взято из def __ init __. Я имею дело с небольшим сбоем с ним в Ubuntu (я думаю, это связано с JACK), но я почти уверен, что это зависит от компьютера , Обратите внимание, у меня есть предопределенный путь.

def __init__(self):

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

        def on_sync_message(bus, message):
            if message.structure is None: 
                return False 
            if message.structure.get_name() == "prepare-xwindow-id":
                if sys.platform == "win32":
                    win_id = videowidget.window.handle
                else:
                    win_id = videowidget.window.xid
                assert win_id
                imagesink = message.src 
                imagesink.set_property("force-aspect-ratio", True)
                imagesink.set_xwindow_id(win_id) 

        win = gtk.Window()
        win.set_resizable(False)
        win.set_has_frame(False)
        win.set_position(gtk.WIN_POS_CENTER)

        fixed = gtk.Fixed()
        win.add(fixed)
        fixed.show()

        videowidget = gtk.DrawingArea()
        fixed.put(videowidget, 0, 0)
        videowidget.set_size_request(640, 480)
        videowidget.show()

        # Setup GStreamer 
        player = gst.element_factory_make("playbin", "MultimediaPlayer")
        bus = player.get_bus() 
        bus.add_signal_watch() 
        bus.enable_sync_message_emission() 
        #used to get messages that GStreamer emits 
        bus.connect("message", on_message) 
        #used for connecting video to your application 
        bus.connect("sync-message::element", on_sync_message)
        player.set_property("uri", "file://" + os.getcwd() + "/VID/SEQ-GAME-OPEN.ogv") 
        player.set_state(gst.STATE_PLAYING)

        win.show()

Надеюсь, это поможет вам, некоторым.

person CodeMouse92    schedule 12.09.2011
comment
Привет JasonMc92, я попробовал твой код. но это дает некоторую ошибку системы X Window. любая помощь будет ощутимой. - person Yajushi; 22.09.2011
comment
Да, я тоже это понял после того, как ответил на это. Проверьте этот вопрос для ответа: stackoverflow.com /вопросы/7369712/ - person CodeMouse92; 22.09.2011