2010-06-07 9 views
10

Estoy cableando una aplicación gstreamer con Python. Y me da una LinkError con siguiente código:Gstreamer de python's gst.LinkError problema

import pygst 
pygst.require('0.10') 
import gst 

import pygtk 
pygtk.require('2.0') 
import gtk 

# this is very important, without this, callbacks from gstreamer thread 
# will messed our program up 
gtk.gdk.threads_init() 

def main(): 
    pipeline = gst.Pipeline('pipleline') 

    filesrc = gst.element_factory_make("filesrc", "filesrc") 
    filesrc.set_property('location', 'C:/a.mp3') 

    decode = gst.element_factory_make("decodebin", "decode") 

    convert = gst.element_factory_make('audioconvert', 'convert') 

    sink = gst.element_factory_make("autoaudiosink", "sink") 

    pipeline.add(filesrc, decode, convert, sink) 
    gst.element_link_many(filesrc, decode, convert, sink) 

    pipeline.set_state(gst.STATE_PLAYING) 

    gtk.main() 

main() 

y el error:

ImportError: could not import gio 
Traceback (most recent call last): 
    File "H:\workspace\ggg\src\test2.py", line 37, in <module> 
    main() 
    File "H:\workspace\ggg\src\test2.py", line 31, in main 
    gst.element_link_many(filesrc, decode, convert, sink) 
gst.LinkError: failed to link decode with convert 

Es muy extraño, con la misma tubería, pero construido con parse_launch, funciona. Aquí está el código:

import pygst 
pygst.require('0.10') 
import gst 

import pygtk 
pygtk.require('2.0') 
import gtk 

# this is very important, without this, callbacks from gstreamer thread 
# will messed our program up 
gtk.gdk.threads_init() 

def main(): 
    player = gst.parse_launch('filesrc location=C:/a.mp3 ! decodebin ! audioconvert ! autoaudiosink') 
    player.set_state(gst.STATE_PLAYING) 
    gtk.main() 

main() 

Aquí viene la pregunta, ¿por qué el Manual falló, pero el éxito analizado uno? ¿Qué está mal con eso? ¿Cómo puedo arreglarlo?

Gracias.

+0

para el registro, no obtengo el primer error que ha enumerado: "ImportError: could not gio import". Obtengo el resto de ellos, sin embargo, vea a continuación –

Respuesta

20

su problema está aquí:

gst.element_link_many(filesrc, decode, convert, sink) 

la razón es que no todos los elementos tienen entradas simples, estáticos y salidas. en este punto de su programa, , su decodificación no tiene ningún parche fuente (es decir: sin salidas).

un pad es como un pezón: es una entrada/salida a un elemento. las almohadillas pueden aparecer, desaparecer o simplemente sentarse allí. hay tres clases de pastillas: almohadillas estáticas (el más fácil y lo que cabría esperar), almohadillas petición (que aparecen sólo cuando se pide para ellos) y veces almohadillas (que aparecen sólo cuando el elemento quiere hacer ellos aparecen). las salidas de decodebin son a veces las almohadillas.

Si inspecciona la salida de gst-inspect decodebin, se puede ver esto por sí mismo:

Pad Templates: 
    SINK template: 'sink' 
    Availability: Always 
    Capabilities: 
     ANY 

    SRC template: 'src%d' 
    Availability: Sometimes 
    Capabilities: 
     ANY 

en la línea 26 de su programa, no se puede vincular a decodificar nada, ya que no tiene ninguna fuente parches para vincular los pads fuente en un decodificador solo aparecen cuando se decodifica el flujo de entrada: esto no ocurre instantáneamente. puede aparecer cualquier cantidad de fuentes (por ejemplo, una para una transmisión de audio, dos para una secuencia de video con audio, ninguna para una transmisión no decodificable).

necesita esperar hasta que se creen los pads, y luego vincularlos. decodebin emite una señal, "new-decoded-pad" para indicarle cuándo sucede esto (esto también está documentado en gst-inspect decodebin). debe conectar una función de devolución de llamada a esta señal y vincular su decodificación y conversión de audio en la devolución de llamada. aquí está el código corregido:

#!/usr/bin/python 

import pygst 
pygst.require('0.10') 
import gst 

import pygtk 
pygtk.require('2.0') 
import gtk 

# this is very important, without this, callbacks from gstreamer thread 
# will messed our program up 
gtk.gdk.threads_init() 

def on_new_decoded_pad(dbin, pad, islast): 
    decode = pad.get_parent() 
    pipeline = decode.get_parent() 
    convert = pipeline.get_by_name('convert') 
    decode.link(convert) 
    pipeline.set_state(gst.STATE_PLAYING) 
    print "linked!" 

def main(): 
    pipeline = gst.Pipeline('pipleline') 

    filesrc = gst.element_factory_make("filesrc", "filesrc") 
    filesrc.set_property('location', 'C:/a.mp3') 

    decode = gst.element_factory_make("decodebin", "decode") 

    convert = gst.element_factory_make('audioconvert', 'convert') 

    sink = gst.element_factory_make("autoaudiosink", "sink") 

    pipeline.add(filesrc, decode, convert, sink) 
    gst.element_link_many(filesrc, decode) 
    gst.element_link_many(convert, sink) 

    decode.connect("new-decoded-pad", on_new_decoded_pad) 

    pipeline.set_state(gst.STATE_PAUSED) 

    gtk.main() 

main() 

gst.parse_launch obras, ya que se encarga de todos estos detalles niggly para usted. también está el elemento de alto nivel playbin que crea y vincula automáticamente una decodificación interna.

+0

[Decodebin] (http://gstreamer.freedesktop.org/data/doc/greather/head/manual/html/section-components-decodebin.html) también se explica en el Manual de desarrollo de aplicaciones GStreamer. – Dejan

Cuestiones relacionadas