python的gst.LinkError问题的Gstreamer

Fan*_*Lin 10 python gstreamer

我正在使用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()
Run Code Online (Sandbox Code Playgroud)

而错误:

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
Run Code Online (Sandbox Code Playgroud)

这是非常奇怪的,使用相同的管道,但使用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()
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Jer*_*ose 20

你的问题在这里:

gst.element_link_many(filesrc, decode, convert, sink)
Run Code Online (Sandbox Code Playgroud)

原因是并非所有元素都具有简单的静态输入和输出.在你的程序的这一点,你的decodebin没有任何源垫(即:没有输出).

垫就像一个乳头 - 它是元素的输入/输出.垫可以出现,消失或只是坐在那里.有三类垫:静态垫(最简单和你期望的),请求垫(只在你要求时出现)和有时垫(仅在元素想要出现时出现).的输出decodebin有时垫.

如果您检查输出gst-inspect decodebin,您可以自己看到:

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

  SRC template: 'src%d'
    Availability: Sometimes
    Capabilities:
      ANY
Run Code Online (Sandbox Code Playgroud)

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

你需要等到创建垫,然后链接它们.decodebin发出一个信号,"new-decoding-pad"告诉你这种情况何时发生(这也记录在案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()
Run Code Online (Sandbox Code Playgroud)

gst.parse_launch之所以有效,是因为它可以为您处理所有这些琐碎的细节.还有一个高级元素playbin,可以在内部自动创建和链接解码器.