2010-06-07 29 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