2010-06-07 28 views
10

我正在用Python连接gstreamer应用程序。而我得到下面的代码LinkError:Python的gst.LinkError问题的Gstreamer

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

和错误:

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 

这是非常奇怪的,具有相同的管道,但parse_launch建成,它的工作原理。这里是代码:

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

问题出在这里,为什么手动失败,但解析一个成功?那有什么问题?我该如何解决它?

谢谢。

+0

为记录,我没有得到你列出的第一个错误:“ImportError:无法导入gio”。我确实得到了其余的,但是,见下面 – 2010-06-14 21:40:08

回答

20

你的问题是在这里:

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

的原因是,并不是所有的元素有简单的,静态的输入和输出。在您的程序中的这一点上,您的解码器没有任何源垫(即:无输出)。

垫子就像一个乳头 - 它是一个元素的输入/输出。垫可以出现,消失或只是坐在那里。有三类垫:静电垫(最容易和你所期望的),请求垫(只有当你问他们时才会出现)和有时垫(只有当元素想要使他们出现)。 decodebin的输出是有时垫

,如果你检查的gst-inspect decodebin输出,你可以看到自己这一点:

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

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

在程序的第26行,你不能链接到解码任何东西,因为它没有任何来源垫与链接。解码器上的源极焊盘仅在输入流解码时出现:这不会立即发生。可以出现任何数量的源垫(例如,一个用于音频流,两个用于具有音频的视频流,而不用于不可解码的流)。

您需要等待,直到创建完成,然后将它们链接起来。解码器发出一个信号,“新解码的”垫片告诉你什么时候发生了这种情况(这也记录在gst-inspect decodebin)。您必须将回调函数连接到此信号,并在回调中链接解码和audioconvert。这里是你纠正代码:

#!/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的作品,因为它照顾到所有的这些小动作细节给你。还有高级元素playbin,它在内部自动创建并链接解码器。

+0

[Decodebin](http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-components-decodebin.html)也被解释在GStreamer应用程序开发手册中。 – Dejan 2012-01-22 20:38:13