2011-08-10 13 views
5

He estado usando pygst en un proyecto y ha estado funcionando bien. Intento migrarlo al nuevo sistema de introspección (GI), pero he estado obteniendo un comportamiento diferente.El bus GStreamer envía Ninguno mensaje

En el antiguo pygst que tienen algo como esto:

... # 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 

El parámetromensaje tiene un atributo .type que puede ser utilizado para el procesamiento selectivo (sólo estoy interesado en el final de corriente (EOS) y error). Usando el nuevo sistema que tengo:

... # 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 

Sin embargo, el controlador siempre recibe el mensaje de parámetros como Ninguno. Intenté filtrar estos, pero sigo sin obtener nada (es decir, todos los mensajes son Ninguno).

He leído mucha documentación de GStreamer (especialmente en GstBus, add_signal_watch() y playbin2) pero no he encontrado nada relacionado con este comportamiento. He comprobado el archivo Gst gir y he visto que add_watch() no se puede introspectar, por lo que es un callejón sin salida. El bucle principal glib en este ejemplo de arriba es solo para hacer las cosas más cortas sin un ejemplo completo de GTK, pero el real usa Gtk.main() (dando exactamente el mismo comportamiento).

Estoy usando GStreamer 0.10.35.0 (según lo informado por Gst.version()) en Arch Linux 64, pero he probado el mismo comportamiento en GStreamer 0.10.32.0 en Ubuntu 11.04 de 32 bits.

¿Hay alguna alternativa a bus.connect()? ¿Lo estoy usando de forma incorrecta? He pasado bastantes horas buscando este error, realmente apreciaría cualquier idea sobre esto. ¡Gracias! =)

+0

Encontré este error: https://bugzilla.gnome.org/show_bug.cgi?id=631901 Básicamente, aún no está implementado. –

+0

Puedo confirmar que esto está solucionado en gstreamer 1.0. –

Respuesta

1

Terminé usando add_signal_watch_full(), que desafortunadamente es más detallado. Sin embargo, funciona bien y puedo recibir mensajes en mi controlador.

+0

Desafortunadamente, esto no funcionó para mí. ¿Podría proporcionar algún código de muestra? –

+0

Estoy bastante seguro de que esta respuesta es incorrecta. Vea abajo. – skagedal

+0

add_signal_watch_full (1) funciona para mí. No sé por qué es necesario el argumento "1". – mnrl

0

Si no planea usar GTK con el programa, deberá ejecutar un gobject.Mainloop() para recibir mensajes del bus. Esto, al igual que cualquier otra mainloop, se congelará todo el programa (si no está enhebrado), por lo que suelen poner algo algo como:

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

al final de un programa que no necesita una interfaz gráfica de usuario, pero necesita Gstreamer

+0

Esto no responde la pregunta. Desde la última línea del código de muestra, el comentario indica que Kenji es consciente de que se requiere un enlace principal. Y su solución no soluciona el problema. –

1

Estoy bastante seguro de que la respuesta aceptada es incorrecta. La única diferencia entre add_signal_watch_full y add_signal_watch es que la primera le permite establecer la prioridad del origen del evento, mientras que la última solo llama al primero con G_PRIORITY_DEFAULT. Puede verificar esto en C source code, número de línea 940. El nivel de prioridad solo afecta el orden de los eventos disparados, no debe afectar si se dispararon y ciertamente no el contenido del mensaje de señal, que es el problema aquí. Incluso lo he probado con varios valores de prioridad, me comeré mi sombrero si hay una forma de que esto funcione. :-)

La verdadera respuesta es que no funciona. PyGObject y GStreamer 0.10 no funcionan bien juntos. Ver:

Este último dice: "Tenga en cuenta que aunque se puede clase-de uso gstreamer0.10 con pygi, la funcionalidad de la clave está roto fundamental y cada vez suele fijarse en gstreamer0.10 (porque sería requiere ruptura API). "

sus opciones, después, son:

  • Requerir GStreamer 1.0.
  • Usa los enlaces antiguos de PyGST.
  • Utilice PyGObject con GStreamer 0.10, pero sin la posibilidad de buscar mensajes como EOS. Solo cosas muy básicas funcionan.
0

que estaba teniendo este mismo problema, pero en C.

Después de largos días de depuración, he encontrado que esto ocurría porque mi ejecutable se vincula tanto a 0,10 y 1,0, de manera indirecta por otras bibliotecas compartidas I utilizar.

Al eliminar las bibliotecas compartidas que enlazaban a 0.10 resolví mi problema.

Cuestiones relacionadas