2010-06-07 9 views
10

Ich bin eine Gstreamer-Anwendung mit Python Verdrahtung. Und ich LinkError mit folgendem Code erhalten:Gstreamer von Python gst.LinkError Problem

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

und den Fehler:

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 ist sehr seltsam, mit gleicher Pipeline, aber mit parse_launch gebaut, es funktioniert. Hier ist der Code:

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

Hier kommt die Frage, warum das Handbuch ein gescheitert, aber die analysierte ein Erfolg? Was stimmt damit nicht? Wie kann ich es reparieren?

Danke. hier

+0

für den Datensatz, ich bekomme nicht den ersten Fehler, den Sie aufgelistet haben: "ImportError: konnte nicht importieren". ich bekomme den Rest von ihnen, obwohl, siehe unten –

Antwort

20

Ihr Problem ist:

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

der Grund ist, dass nicht alle Elemente verfügen über eine einfache, statische Ein- und Ausgänge. An dieser Stelle in Ihrem Programm, Ihr Decoder hat keine Quell-Pads (das heißt: keine Ausgänge).

Ein Pad ist wie ein Nippel - es ist ein Eingang/Ausgang zu einem Element. Pads können erscheinen, verschwinden oder einfach nur dort sitzen. gibt es drei Klassen von Pads: statische Pads (die einfachste und was man erwarten würde), Anfrage Pads (die nur angezeigt, wenn Sie danach fragen) und manchmal Pads (die nur angezeigt werden, wenn das Element machen will sie erscheinen). die Ausgänge von decodebin sind manchmal Pads.

, wenn Sie die Ausgabe von gst-inspect decodebin überprüfen, können Sie diese für sich selbst sehen:

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

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

in Zeile 26 des Programms, Sie nicht dekodieren zu etwas verbinden können, weil es keine Quelle hat Pads zum Verknüpfen mit. Quell-Pads auf einem Dekodebin erscheinen nur, wenn der Eingangsstrom decodiert wird: Dies geschieht nicht sofort. es kann eine beliebige Anzahl von Quellen-Pads erscheinen (z. B. eine für einen Audiostream, zwei für einen Videostream mit Audio, keine für einen nicht decodierbaren Stream).

Sie müssen warten, bis die Pads erstellt sind, und dann verknüpfen Sie sie. decadebin gibt ein Signal, "new-decoded-pad" aus, um Ihnen zu sagen, wann dies passiert (dies ist auch in gst-inspect decodebin dokumentiert). Sie müssen eine Callback-Funktion mit diesem Signal verbinden und Ihre Dekodierung und Audiokonvertierung im Callback verbinden. hier ist Ihre korrigierten Code:

#!/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 funktioniert, weil es für Sie von all diesen niggly Details kümmert. Es gibt auch das High-Level-Element playbin, das intern automatisch einen Dekodebin erstellt und verbindet.

+0

[Decodebin] (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-components-decodebin.html) wird auch erklärt im GStreamer-Anwendungsentwicklungshandbuch. – Dejan