天天看點

使用 GStreamer 進行多用途的多媒體處理

多媒體,依照其定義,表示各種各樣的媒體類型。您可以各種格式存儲音頻、視訊和中繼資料。然而,這也就意味着要使用許多工具來處理這些不同的内容。

GStreamer 可以為您提供幫助。通過将所有不同的工具和庫隐藏到它的插件中,以及使用媒體管道 這個一般性概念,GStreamer 能以一種統一的方式表示對不同類型媒體所進行的操作。這使得您能夠将精力集中于現有的媒體,而不是困惑于究竟應該使用什麼樣的管道。

這種統一處理方法的優點顯而易見。您可以編寫音樂 或視訊 播放器,而不是編寫 MP3 播放器或者 AVI/DivX 播放器。當您希望支援另一種格式時,無需進行深入的研究并為新的庫編寫代碼。相反,僅需要安裝這種格式的插件就可以了。就是這麼簡單,甚至不需要進行重新編譯。所有的 GStreamer 應用程式都可以在運作的過程中采用新的格式。

GStreamer 可以解決許多問題,比如“需要存儲來自不同來源具有相同格式的所有音頻采樣”。因為對所有的格式進行相似的處理,是以您隻需要編寫一個工具。這将節省時間,并使得解決方案更加健壯且更易于維護。而且,在您了解了 GStreamer 的相關概念之後,幾乎可以将它應用到任何地方。如果您要讓音頻資訊流經網絡,那麼隻需要考慮這個網絡,因為您所使用的音頻 API(應用程式程式設計接口)和所有其他的操作都保持不變。

相關概念

由于其本身的特性,GStreamer 比普通的庫位于更高的層次。是以,務必了解 GStreamer 究竟是什麼以及它能夠完成哪些工作。

GStreamer 是一種媒體處理庫。這就意味着,它為您提供了某種轉換過程的抽象模型(由輸入、輸出和不同的階段組成),并且允許您為滿足特殊的最終結果和特殊的媒體類型而建構這種轉換過程的執行個體。下面是這種處理過程的一些示例:

  • 将 MP3 音頻檔案轉換為 Ogg Vorbis
  • 播放 AVI 電影檔案
  • 使用 IEEE1394 數字視訊 (DV) 錄影機捕獲現場表演,并将它儲存為 MPEG-2 流

為了實作這些不同的結果,GStreamer 通過抽象的管道概念進行工作。管道 是一個有向圖,媒體在這個有向圖中從輸入流到輸出。管道由各種元素組成,而元素則是另一個核心概念。元素 是可以放入到管道中的對象,其中包裝了對媒體進行的某種操作。您可以将不同的元素連結在一起,以使它們共同組成将輸入轉換為需要的輸出的完整處理過程。通常,使用從左(上遊)到右(下遊)的資料流來對管道進行描述。使用

gst-launch

以同樣的方式來編寫管道,關于

gst-launch

的内容将在本文後面介紹。

請務必注意,到目前為止,所有的内容都是完全抽象的。沒有涉及到視訊或音頻,之是以這樣做,有一個很好的理由。上面描述的模型并不局限于任何特定的媒體類型。隻要您可以将其描述為輸入、輸出和轉換過程,就都可以利用管道來對其進行操作。例如,桌面可以作為媒體來源,您可以錄制對視訊檔案的螢幕播放。事實上,Istanbul 應用程式正是這樣做的(請參見

參考資料

部分)。

GStreamer 的核心本身并不包含任何元素。它隻提供關于管道的知識。而所有特定的内容,都由相應的插件提供。插件 是一段經過編譯的代碼,通常以對象檔案(UNIX? 上的 .so 和Microsoft? Windows? 上的 .dll)的形式分發,可以提供一個或多個元素。在啟動過程中,GStreamer 對所有已安裝的插件進行查詢,以擷取可用于應用程式的一組元素。插件通常可以調用其他的庫,以完成特定的任務(例如,MPEG-2 解碼器可以使用現有的庫來處理 MPEG 格式的資訊),但是應用程式并不需要知道這一點。它所看到的隻是一些外觀和工作方式相同的元素。

有些插件以核心源包的形式分發,并且将其編譯為庫,甚至從概念上看,它們是一些獨立的實體。其他的基本插件以基于 gst 插件包的形式分發。在大多數的 GStreamer 安裝中,都包含這些基本插件。然後還有一些好的、差的和糟糕的 gst 插件包,其中,根據這些不同的插件得到的支援級别和許可條款對其進行收集。最後,還有一些由第三方供應商分發或注冊專門用于特定應用程式的插件。

融會貫通

既然已經了解了管道,您就還需要了解如何将它映射為 GStreamer 實作。在此過程中,您還将了解到更多的術語。

為什麼要交換源和接收器呢?

實際上并沒有對它們進行交換。接收單元是資料流進入元素的地方,而源單元是資料流産生的地方。是以,隻包含源單元的元素稱為源,而隻包含接收單元的元素稱為接收器。這是非常符合邏輯的,即使乍看上去可能有些别扭。

正如我所提到的,元素是處理過程的基本單元,由

GstElement

類來表示。GStreamer 是使用 C 進行編寫的,但是它使用了來自 GTK+ 工具包的 GObject 庫,以獲得面向對象的特性(請參見

部分)。元素中包含一些單元,這些單元是連結到其他元素的位置。有兩種類型的單元:

  • 接收單元 為元素提供輸入。
  • 可以通過源單元 通路元素所産生的資料。

這些單元所具有的相應功能稱為能力。這些功能表示什麼類型的資料可以流經該單元。例如,如果您檢查一個

vorbisdec

元素(它是一個免費 Vorbis 代碼的解碼器),可以看到如

清單 1

中所示的代碼。一行開頭處的美元符号 ($) 表示該行是正常的 UNIX Shell 指令。

清單 1. vorbisdec 元素資訊中的代碼段
$ gst-inspect-0.10 vorbisdec

[...]

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      audio/x-raw-float
                   rate: [ 8000, 50000 ]
               channels: [ 1, 6 ]
             endianness: 1234
                  width: 32

  SINK template: 'sink'
    Availability: Always
    Capabilities:
      audio/x-vorbis

[...]
      

您可以看到,其中有兩種單元模闆:一種用于源 (

src

),另一種用于接收器。源單元的可用性為 always(其他可能的可用性取值為

sometimes

request

),并且能夠以 8kHz 到 50kHz 的速率輸出原始浮點音頻,該音頻具有 1 至 6 聲道、小端位元組順序以及 32 位寬的采樣。另一方面,接收單元僅接收 Vorbis 編碼的音頻流。

要使管道正常工作,這些模闆是至關重要的。當您試圖将兩個元素連結到一起以組成一個管道時,GStreamer 會檢視它們的單元模闆是否相容。這個過程稱為協商。在協商過程中,這些元素會嘗試發現它們之間共同支援的最佳格式。如果不存在這樣的格式,那麼連結将會失敗。否則,它們将會達成協定使用一種通用格式。這種格式不再是模闆,而稱為固定的能力,這表示所有的值都具有實際意義并且是明确的。然後,可以将資料從一個元素傳遞到另一個元素。

現在,您已經了解了開始工作前所需要的内容。為了完成具體的工作,我将介紹 GStreamer 中如“瑞士軍刀”般銳利的工具,

gst-launch

工具。

回頁首 使用 gst-launch

了解您的工具

除了

gst-launch

之外,GStreamer 在分發時還附帶了一些其他的工具,如

gst-inspect

gst-typefind

。請使用這些工具,它們将是您最好的夥伴。

在不知道如何使用某個元素時,可以使用

gst-inspect

。指定任何元素或插件的名稱,它将顯示 GStreamer 所知道的關于該對象的所有資訊,當然,相關的資訊可能會比較多。

使用

gst-typefind

,這是 GStreamer 版本的優秀的舊式

file(1)

UNIX 實用程式,您可以找出檔案類型(或者确切地說,GStreamer 所認為的檔案類型)。

gst-launch

是您所碰到用途最多的工具之一。對于 GStreamer 來說,它就像是 UNIX 的 Shell。使用該工具,您甚至可以通過特殊的文法(相應地稱為 gst-launch 文法)建構複制的管道,如

清單 2

中所示。

清單 2. gst-launch 行的示例
$ gst-launch-0.10 filesrc location=
  "concept.mp3" ! decodebin ! alsasink

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: audioclock0
      

是一種最簡單的音頻播放器。現在,我正使用它聽 concept.mp3。

表 1

解釋了如何從左到右閱讀該指令行。

表 1. 清單 2 中介紹的文法的元素描述
元素 描述
gst-launch-0.10 這是該指令的名稱。

-0.10

表示在同時安裝了舊的 0.8 釋出版的情況下,應該使用特定版本 GStreamer 0.10。
filesrc location="concept.mp3" 它建立了一個

filesink

類的元素,并将其

location

屬性設定為

concept.mp3

。因為

filesrc

元素可以讀取由

location

指定的檔案,是以該指令為目前目錄中的 concept.mp3 檔案建立了一個讀取器。
! 感歎号表示連結到。與 Shell 中的管道符号 (|) 類似,之是以選擇使用感歎号,是因為它看起來與 (|) 比較相似,并且在 Shell 中無需對其進行轉義(隻要它的前後都有空格即可)。
decodebin 這是由 GStreamer 提供的 autoplugger。autoplugger 是一個元素,指定了其輸入和輸出的資料類型,它可以使用其他的可用元素來查找提供所需結果的子管道。請記住,GStreamer 中所有的連結都應該是類型化的,是以,感歎号 (

!

) 隐式地表示了它所連結的元素的類型資訊。因為

filesrc

具有

ANY

類型的能力,是以

decodebin

首先對流嘗試 typefind 操作。也就是說,它将查找表示類型的特征符号。所有的這些操作,對于使用者來說都是透明的。
alsasink 這是适合于我的 Linux? 系統的音頻輸出的元素。它與聲霸卡進行通信并為其提供原始音頻采樣。它必須與整個管道合拍,因為聲霸卡具有使用資料的正常速率。

當我按下 Enter 時,它會顯示一些狀态資訊,直到管道到達

PLAYING

狀态。然後,開始以流的形式傳輸資料,而我可以聽到聲音,由我的聲霸卡 (

audioclock0

) 設定其節奏。

正如您所看到的,GStreamer 為您節省了大量的 工作。您甚至無需了解嘗試解碼的媒體類型。請記住,正如 Shell 無法取代 C 程式,

gst-launch

工具無法取代完整的 GStreamer 應用程式。例如,

gst-launch

不允許您在其啟動之後以任何方式對管道進行控制,是以您無法跳過流中的某些部分。盡管如此,它仍然是非常有用的,特别是對于一些快速的任務,比如将音頻檔案錄制為另一種格式或者僅使用管道進行試驗。

更深入的研究

本文隻是簡單地介紹了您能夠使用 GStreamer 進行哪些工作。很顯然,使用簡單的 Shell 指令建立音頻播放器非常不錯。然而,這隻是一個非常簡單的播放器,沒有任何使用者界面和控件。要添加這些項目和更多的内容,您需要使用一些代碼。即便如此,GStreamer API 仍然很簡單并且經過了仔細的考慮。如果您不喜歡 C,可以從其他的綁定中進行選擇,包括 Python 語言綁定的謹慎維護子集。

請閱讀

gst-launch

的 man 頁面。完整文法的範圍更加廣泛,并且您可以使用它來建立更複雜和有趣的管道,包括那些可以從代碼中建立的管道。是的,您甚至可以建立自己的

gst-launch

(請檢視

gst_parse_launch ()

函數文檔以了解如何完成這項工作)。

另外,請加入該郵件清單并順便通路 IRC 頻道(

#[email protected]

)。GStreamer 開發人員組成了一個非常活躍的集體,通常總有人為您提供幫助或得到您的幫助。

學習

獲得産品和技術

  • GStreamer 首頁 :有關最新的資訊和下載下傳,請通路此站點。
  • Istanbul :Istanbul 是一種使用 GStreamer 的桌面會話錄制程式。
  • IBM 試用軟體 :使用 IBM 軟體開發您的下一個項目,可直接從 developerWorks 下載下傳這些試用軟體。

讨論