Шина GStreamer отправляет сообщение None - PullRequest
5 голосов
/ 10 августа 2011

Я использую Pygst в проекте, и он работает нормально. Я пытаюсь перенести его на новую систему самоанализа (GI), но у меня другое поведение.

В старом пигсте у меня есть что-то вроде этого:

... # other imports
import pygst
pygst.require('0.10')
import gst
... # other imports

gobjects.threads_init()

...

def my_handler(bus, message):
    # handle the message

...

player = gst.element_factory_make('playbin2', 'my_player')
bus = player.get_bus()
bus.connect('message', my_handler)
bus.add_signal_watch()
...
player.set_state(gst.STATE_PLAYING)
# start the main Glib loop

Параметр message имеет атрибут .type , который можно использовать для выборочной обработки (меня интересуют только конец потока (EOS) и ошибка). Используя новую систему у меня:

... # other imports
from gi.repository import Gst
import glib
import gobject
.... # other imports

gobject.threads_init()

loop = glib.MainLoop(None, False)

def bus_handler(bus, message):
    print message
    # handle the message
...

Gst.init_check(None)
player = Gst.ElementFactory.make('playbin2', 'my_player')
player.set_property('uri', 'file:///home/kenji/button.ogg')
bus = player.get_bus()
bus.connect('message', bus_handler)
bus.add_signal_watch()
player.set_state(Gst.State.PLAYING)
# start the main loop

Однако обработчик всегда получает параметр , сообщение как Нет . Я попытался отфильтровать их, но все равно ничего не получил (т.е. все сообщения Нет ).

Я прочитал много документации GStreamer (особенно по GstBus, add_signal_watch () и playbin2), но я не нашел ничего связанного с этим поведением. Я проверил файл Gst gir и увидел, что add_watch () не может быть самоанализ, так что это тупик. Основной цикл glib в этом примере просто для того, чтобы сделать вещи короче без полного примера GTK, но реальная вещь использует Gtk.main () (что дает точно такое же поведение).

Я использую GStreamer 0.10.35.0 (как сообщает Gst.version ()) в Arch Linux 64, но я протестировал такое же поведение на GStreamer 0.10.32.0 в Ubuntu 11.04 32-bit.

Есть ли альтернатива bus.connect ()? Я использую это неправильно? Я потратил довольно много часов на поиски этой ошибки, и я был бы очень признателен за понимание этого. Спасибо! =) * * Тысяча двадцать-семь

Ответы [ 4 ]

1 голос
/ 14 ноября 2011

Я использовал add_signal_watch_full(), что, к сожалению, более многословно.Хотя он работает нормально, и я могу получать сообщения на свой обработчик.

1 голос
/ 01 июня 2013

Я почти уверен, что принятый ответ неверен.Единственная разница между add_signal_watch_full и add_signal_watch заключается в том, что первый позволяет вам установить приоритет источника события, в то время как последний просто вызывает первый с помощью G_PRIORITY_DEFAULT.Вы можете проверить это в исходном коде C , номер строки 940. Уровень приоритета влияет только на порядок инициируемых событий, не должен влиять на то, инициированы ли они, и, конечно, не на содержание сигнального сообщения, котороепроблема здесь.Я даже проверил это с различными значениями приоритета, я съем свою шляпу, если есть способ, которым это работает.: -)

Реальный ответ - это то, что это не работает.PyGObject и GStreamer 0.10 плохо работают вместе.См .:

Последний говорит: «Обратите внимание, что хотя вы можете сортировать , используйте GStreamer0.10 с PyGI, ключевая функциональность в корне нарушена и никогда не будет исправлена ​​в GStreamer0.10 (потому что это потребовало бы поломки API). "

В таком случае вы можете выбрать следующие параметры:

  • Требуется GStreamer 1.0.
  • Использовать старые привязки PyGST.
  • Использовать PyGObject с GStreamer 0.10, но без возможности проверять сообщения типа EOS.Работают только очень простые вещи.
0 голосов
/ 05 августа 2013

У меня была точно такая же проблема, но в C.

После долгих дней отладки я обнаружил, что это происходит, потому что мой исполняемый файл связывался с 0.10 и 1.0, косвенно другими общими библиотеками, которые я использую.

Удаление общих библиотек, связанных с 0.10, решило мою проблему.

0 голосов
/ 02 сентября 2011

Если вы не планируете использовать GTK с программой, вам придется запустить gobject.Mainloop(), чтобы получать сообщения с шины. Это, как и любой другой mainloop, заморозит всю программу (если она не потоковая), поэтому я обычно помещаю что-то вроде:

g_loop = threading.Thread(target=gobject.MainLoop().run)
g_loop.daemon = True
g_loop.start()

в конце программы, которая не нуждается в графическом интерфейсе, но нуждается в Gstreamer.

...