gstlogo

在 Linux 有許多單一用途的多媒體播映器(media player),諸如 mplayerxinexmms 等,但是卻沒有一個統一的架構,所以這些不同的程式都是某個特定的解碼函式庫(mp3/mpeg)綁在一起,因此非但大部份的程式碼都無法重複使用,系統的延伸彈性也有限。即使像 xmms 提供 plugin framework,也僅適用在單一的介面。(當然還有像是 LADSPA 之類的方案),在其他作業系統平台上,都已經有類似的方案,如 Windows 上的 DirectShow、MacOS 的 QuickTime frameworkBeOS Media Kit 還有所有平台共通的 RealMedia Toolkit 等。


雖然有些 Software Development Kit 像是 SGI 的 dmSDLBEAST/BSEaRtsEnlightened Sound Daemon。但是這些軟體或是開發工具的功能與上述的 Media Framework 比較起來還是有限。

GStreamer 是一個 Open Source Media Framework,是一個有效解決這個領域的方案。完全元件式的架構,他提供給程式設計者簡潔且具備足夠彈性的程式架構來撰寫多媒體軟體,輕易的在你的程式中嵌入多媒體互動程式,無論是在桌上型電腦、網路系統甚至是嵌入式系統。

整個 Framework 包含三個元素,分別是廣泛具彈性的核心函式庫、非常聰明的插件架構(Plugin Architecture)、以及多樣的開發工具。整個系統是基於 GLib 2.0,每個元件 (Element) 都是繼承於 GObject,每個元件皆是一個 self-containted object,可以分為 Data source、Encoders, decoders、Muxers, demuxers、Filters、Data sinks。這些元件本身包含敘述本身介面的資訊,包含可收納的來源格式,輸出的格式與數量,因此各個元件可以輕易的連結在一起,只要可以對上來源與輸出,甚至不用寫任何程式就可以開始播放多媒體檔案。架構中足足包含了超過 130 個元件。整個核心架構基於少量的核心函式庫上,只用了 glib、popt 與 libxml(選用)。還支援 Python Language bindings,被大量的應用在 Gnome 2.2 程式中。

這個計畫提供了完善的開發/測試工具文件(Application Development Manual 與 Plugin Writer’s Guide 已經超過一百五十頁),還有圖形化的管線 (pipeline) 編輯工具、動態建立管線的指令工具 gst-launch、Element 與 plugin 查詢工具 gst-inspect等。

gst-editor

以我們要開發一個 MP3 Player 為例,首先我們要建立一個容器(Bin Element)來擺放各式元件,容器本身也是一個元件,容器的兩種型態分別是管線(Pipeline Element)與執行緒(Thread Element)。要撥放 MP3,首先我們需要 Data source element 來讀入資料,可能是檔案、網址或其他串流來源,接下來需要一個解碼器來解開 mp3 串流,以這裡為例我使用 mad mp3 decoder ,最後輸出給 Data sinks 即可。可以使用 gst-inspect mad 來查詢 mad 元件的細節,同理可以查詢 filesrc、osssink、alsasink 等。

各個元件由接點(Pad)連結起來。我們可以用 gst-launch 來達成我們的目的,像是這樣

gst-launch -v filesrc location=music.mp3 ! mad ! osssink

或是使用 alsa 驅動程式來輸出

gst-launch -v filesrc location=music.mp3 ! mad ! alsasink

由於元件與元件間以 MIME types 與媒體類別各自表述,所以程式可以很聰明的把不同的元件自動串接在一起,而不需要特別描述。所以你可以快速的串接每個元件,甚至不用寫任何一行 C 語言程式。你可以用 gst-inspect 與 gst-inspect-gui 來查看每個元件的特性。除此之外,每個元件還可用 XML 來轉出敘述,所以可以透過 Gstreamer Pipeline Editor 先行設計串流,然後儲存成 XML 檔案,在程式撰寫中載入變成外掛模組,模組中的模組。

gst-editor

此架構很適合拿來開發 Media player、Audio mixing/processing、Telephony (IP phones)、Video Non-Linear Editing 等任何多媒體應用軟體。例如可以搭配 icecastsend 來當作 icecast client,由於 GStreamer 的高元件彈性,所以來源可以是檔案、http、RTP、CDDA、DVD、從麥克風,可以讀取 mp3、wave、gsm、au 等等,最後可以混音輸出到 icecast server。在這同時,你還可以對串流掛上 Filters,要 Echo 、Amplifier 等 audio effect 。再誇張點,掛上 Festival speech synthesis system,讓電腦對著網路自言自語去吧。(已經有 plugin,但是我可沒說已經支援中文語音合成)

BTW, GStreamer 宣告為 LGPL 版權。開發測試用工具為 GPL

後記 SourceForge 上有類似的計畫 – GPlayGStreamix。不過兩個計畫都呈現死亡狀態。

  • 阿欽

    因為最近在用藍芽耳機A2DP聽音樂
    播放器是用banshee的,我有用一個按鈕就是可以切換藍芽耳機與電腦內建喇叭的功能
    主要就是用執行一個script

    #!/bin/bash

    state=`gconftool –get /system/gstreamer/0.10/default/musicaudiosink | cut -d\ -f1`

    if [ $state == “autoaudiosink” ]; then
    gconftool –type string –set /system/gstreamer/0.10/default/musicaudiosink “alsasink device=bluetooth”
    zenity –info –title=”GStreamer” –text=”Switched to Bluetooth headphones.”
    else
    gconftool –type string –set /system/gstreamer/0.10/default/musicaudiosink “autoaudiosink”
    zenity –info –title=”GStreamer” –text=”Switched to speaker output.”
    fi

    echo musicaudiosink set to `gconftool –get /system/gstreamer/0.10/default/musicaudiosink`

    但這個功能沒有辦法即使切換,要它繼續播到下一首歌或是我重新按播放的功能才會切換到另一個輸出
    我在藍牙耳機連線的時候,輸入
    # aplay -l
    **** List of PLAYBACK Hardware Devices ****
    card 0: Intel [HDA Intel], device 0: ALC662 Analog [ALC662 Analog]
    Subdevices: 1/1
    Subdevice #0: subdevice #0

    如果是切換內建speaker時(已經換到下一首歌),變成
    card 0: Intel [HDA Intel], device 0: ALC662 Analog [ALC662 Analog]
    Subdevices: 0/1
    Subdevice #0: subdevice #0

    在Subdevices確是有不同,這邊代表就是不同的輸出嗎??
    如果我要切換這個Subdevices是否就可以達到即時切換呢?

    所以我研究過audio的架構:
    ■Audio

    ———————————————————-
    │Application │
    │ Banshee Amarok │
    │ ↓ │
    ———————————————————-
    │Desktop Environment │
    │ ↓ ↓ ↓ │
    │ GNOME KDE XFCE │
    │ │
    ————————–DBus—————————-
    │ │
    ———————————————————- GStreamer framework解碼器
    │Sound Server │
    │ ↓ ↓ │
    │ ↓ ↓ │
    │ ESD aRTs PulseAudio│
    ———————————————————-
    │Kernel │
    │ ↓ │
    │ ALSA driver │
    ———————————————————-
    │Hardware │
    │ ↓ │
    │ Soundcard │
    ———————————————————-
    是否是我只控制到Gstreamer解碼器這邊的部份,如果要做到即時的話,是否說要控制到kernel那部份
    才可以達到即時切換的功能,還是說從GStreamer這邊就可以做到即時切換的功能 ,謝謝
    OS: [Xubuntu] 8.04.1 kernel 2.6.24-19-generic

  • Hi,阿欽: 這是 banshe/gstreamer 的設計問題,banshe/gstreamer 並不會被自動通知 default sink 被更動了,所以再 banshe 撥下一首歌時才會自動重新載入 gstreamer.

    若你希望可以做到即時轉換,建議你搭配 Sound Server 使用,PulseAudio 是一個很好的選擇。
    請參考
    http://fosswire.com/2008/10/25/better-bluetooth-audio/
    http://forums.overclockers.com.au/showthread.php?t=694010