我正在用Python连接一个gstreamer应用程序。我得到了一个包含以下代码的LinkError:
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()问题来了,为什么手动的失败了,而解析的成功了呢?这有什么问题吗?我怎么才能修复它?
谢谢。
发布于 2010-06-15 06:14:30
你的问题在这里:
gst.element_link_many(filesrc, decode, convert, sink)原因是并不是所有的元素都有简单的静态输入和输出。在程序中的这一点上,您的解码器没有任何源码垫(即:无输出)。
pad就像一个乳头--它是元素的输入/输出。pads可以出现,也可以消失,或者只是停在那里。有三种类型的pads:静态pads (最简单的,也是您所期望的),request pads (请求pads )(仅当您请求它们时出现),以及有时pads(仅当元素想要使它们出现时出现)。decodebin的输出有时是pads。
如果您检查gst-inspect decodebin的输出,您可以自己看到以下内容:
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
ANY
SRC template: 'src%d'
Availability: Sometimes
Capabilities:
ANY在您的程序的第26行,您不能将decode链接到任何东西,因为它没有任何可链接的源码垫。只有当输入流被解码时,解码器上的源垫才会出现:这不会立即发生。可以出现任意数量的源填充(例如,一个用于音频流,两个用于具有音频的视频流,没有一个用于不可解码的流)。
您需要等待焊盘创建完成,然后将它们链接起来。当发生这种情况时,decodebin会发出一个信号"new-decoded-pad“来告诉你(这在gst-inspect decodebin中也有说明)。您必须将回调函数连接到此信号,并在回调中链接您的解码和音频转换。以下是您更正后的代码:
#!/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,它在内部自动创建和链接解码器。
https://stackoverflow.com/questions/2993777
复制相似问题