10

gstreamerアプリケーションをPythonで配線しています。そして、次のコードで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()

ここに質問があります。なぜ手動のものは失敗したのに、解析されたものは成功したのでしょうか。それのどこが悪いんだい?どうすれば修正できますか?

ありがとう。

4

1 に答える 1

20

あなたの問題はここにあります:

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

その理由は、すべての要素が単純で静的な入力と出力を持っているわけではないからです。プログラムのこの時点では、decodebinにはソースパッドがありません(つまり、出力がありません)。

パッドは乳首のようなものです-それは要素への入力/出力です。パッドは表示、非表示、またはただそこに座ることができます。パッドには3つのクラスがあります。静的パッド(最も簡単で期待できるもの)、リクエストパッド(要求したときにのみ表示される)、場合によってはパッド(要素がそれらを表示したいときにのみ表示される)です。の出力decodebin時々パッドです。

の出力を調べると、gst-inspect decodebinこれを自分で確認できます。

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

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

プログラムの26行目では、リンクするソースパッドがないため、デコードを何にもリンクできません。デコードビンのソースパッドは、入力ストリームがデコードされたときにのみ表示されます。これは瞬時には発生しません。任意の数のソースパッドが表示される場合があります(たとえば、オーディオストリーム用に1つ、オーディオ付きのビデオストリーム用に2つ、デコードできないストリーム用に1つ)。

パッドが作成されるまで待ってから、それらをリンクする必要があります。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デコードビンを内部で自動的に作成してリンクする高レベルの要素もあります。

于 2010-06-14T22:14:29.957 に答える