先日、あしたのオープンソース研究所の第6回でオープンソースのマルチメディアフレームワークであるGStreamerを紹介してきました。
あしたのオープンソース研究所では、海外のオープンソースソフトウェアのドキュメントを翻訳されていて、翻訳対象の文書も募集されています。GStreamerなどいくつか応募したのですが、そのうちの1つとしてGStreamerを採用してもらえたのでGStreamerの概要を紹介をしてきました。
スライドを見ただけでは伝わらないはずなので少し説明も加えておきます。いくつか省略しているページもあるので、完全版が見たい場合は画像のリンク先を見てください。
GStreamerとは
GStreamerはマルチメディアのフレームワークです。音声・動画の再生、フォーマットの変換、録音・録画など基本的なことはもちろん、RTSPなどを用いたネットワーク通信を行うこともできます。
使い方
GStreamerにはgst-launchというコマンドラインツールが付属していて、gst-launchを使うことによりプログラムを作らなくてもGStreamerの機能を利用することができます。
GStreamerにはplaybinという機能があり、再生するときはこの機能が便利です。URIを指定するだけで、内容からフォーマットを自動で判別し、フォーマットに合わせた再生処理をします。音声・動画どちらでも再生することができます。
GStreamerではshのパイプのように機能をつなぎ合わせて目的を実現します。Ogg VorbisからAACへフォーマットを変換する場合は、以下のように機能を組み合わせます。
- ファイルから読み込み(filesrc)
- OggコンテナからVorbisデータを取り出し(oggdemux)
- Vorbisデータをデコード(vorbisdec)
- 音声データのフォーマットを微調整(audioconvert)
- AACでエンコード(faac)
- AACデータをMP4コンテナに格納(ffmux_mp4)
- ファイルへ書き込み(filesink)
GStreamerはVideo4Linuxにも対応しているので、Linux環境ではVideo4Linuxを利用してPCに接続されたWebカメラで録画することもできます。ここでは以下のように機能を組み合わせて、Webカメラで撮影した動画を画面に出力しています。
- Video4LinuxでWebカメラから撮影した動画を取り込み(v4l2src)
- 動画を画面に出力(autovideosink)
撮影した動画を画面に出力する前にテキストを挿入することもできます。GStreamerでは機能をつなぎ合わせて目的を実現するので、間に追加の機能を挿入することが簡単にできます。
- Video4LinuxでWebカメラから撮影した動画を取り込み(v4l2src)
- [追加] 動画にテキストを挿入(textoverlay)
- 動画を画面に出力(autovideosink)
動画と合わせて音声も録音することができます。動画用のパイプライン(機能のつなぎ合わせ)と音声用のパイプラインが別々になっていることがポイントです。
GStreamerでは機能を付け替えることが簡単にできるため、データの入力元・出力先をファイルからネットワーク通信に変えてやることで別のホストに動画を転送することもできます。この例ではRTPなどを使わず、直接TCPでOggデータをやりとりしています。まず、データを受信して画面に表示するクライアント側を動かします。
別の端末で録画したものをOggにエンコードしてクライアント側にTCPでデータを送信します。Theoraにエンコードしている部分で「video/x-raw-yuv,framerate=10/1」としているのは、フレームレートをおとしてデータ量を減らすためです。
サーバ側・クライアント側で何もデータを変換しなければネットワーク経由でのファイルコピーも実現できます。GStreamerは機能をつなぎ合わせるための汎用的な環境を提供しているので、こんなこともできるよ、という話です。
GStreamerでどういうことができるのかというイメージをつかめたでしょうか。
GStreamerの周辺
GStreamerはGNOMEアプリケーションで利用されています。メディアプレイヤーのTotem、音楽プレイヤーのRhythmbox、CDリッパーのSound_Juicer、VoIP・ビデオ会議アプリケーションのEkigaなどはGStreamerを利用しています。GStreamerはGNOMEアプリケーション以外でも利用されています。FlashプレイヤーのGnashや動画編集ソフトのPiTiVi、Mozillaテクノロジーをベースとした音楽プレイヤーであるSongbirdなどもGStreamerを利用しています。
GStreamerと類似しているソフトウェアにはFfmpeg、Phonon、QuickTime、DirectShowなどがあります。どれもマルチメディアを扱うソフトウェアなのでGStreamerと似ているのですが、GStreamerはこれらのソフトウェアと競合するものではありません。
これらのソフトウェアの関係を図示したものです。ここでは、「API」、「フレームワーク」、「ライブラリ」という層に分けていますが、一般的な分け方ではないので注意してください。実際、複数の層にまたがるソフトウェアが多く、この分類にすっきり当てはまるわけではありません。ただ、このようにざっくりと分類した方がイメージがつかみやすいのではないかということでこのような分類を導入しました。
上の層ほど高レベルのソフトウェアで下の層のソフトウェアを利用したりして実現されています。それぞれの層は以下のように分類しています。
ライブラリ層はコーデックなどマルチメディアデータのフォーマットを扱う機能などを提供します。GUIがないことが多く、プログラムや付属のコマンドラインツールなどからライブラリの機能を利用することになります。1つのライブラリで必要な機能がすべて満たされる場合はこの層を直接利用するとよいでしょう。複数のライブラリが必要になる場合は、フレームワーク層やAPI層を利用した方が開発効率がよくなることが多いです。この層にあるソフトウェアは、サーバ上でも広く利用されているFFmpegやTheoraをエンコード・デコードする機能を提供するlibtheoraなどの各種コーデック、などです。
フレームワーク層はメディアフォーマットのエンコード・デコード機能だけではなく、複数のフォーマットを統一的に扱う機能や、マルチメディア再生時の制御機能など、メディアプレイヤーで必要になるようなマルチメディア関連の機能を包括的に提供します。フレームワークに後から機能(コーデックなど)を追加する仕組みがあることが多く、この仕組みにより、プログラムの変更を最小限に抑えながらアプリケーションを新しいフォーマットに対応させたりすることができます。より汎用的なアプリケーションを開発する場合はこの層を使って開発するとよいでしょう。この層にあるソフトウェアは、GStreamerやMac OS XのQuickTime、WindowsのDirectShowなどです。
API層は実際の処理を行わず、フレームワークやライブラリを利用してプログラマが安心してマルチメディア機能を使うための安定したAPIを提供する層です。プログラマがAPI層を利用する利点は、環境(やフレームワークやライブラリ)に依存せずに同じコードでマルチメディアの機能を利用できることです。この層にあるソフトウェアはQtに含まれているPhononやMac OS XでのQTKitです。QtプログラマはPhononが提供するAPIを用いてプログラムを開発することで、クロスプラットフォームで動作するマルチメディア機能を実現することができます1。
GStreamerが他のソフトウェアと競合しないのは、GStreamerが他のソフトウェアの機能を利用できるからです。GStreamerは、後からGStreamerに機能を追加できるプラグインシステムを実装しています。プラグインシステムを用いて、FFmpegの機能を利用したり、Mac OS XではQuickTimeの機能を利用したり、WindowsではDirectShowの機能を利用したりできます。つまり、GStreamerは他のソフトウェアと協調して動作することができます。このため、他のソフトウェアと競合しないのです。
GStreamerの仕組み
GStreamerの概要を理解するために大事な概念は以下の4つです2。
- エレメント
- リンク
- パッド
- パイプライン(ビン)
エレメントが個々の機能に対応します。エレメントにはデータの出入り口となるパッドがあります。エレメントから別のエレメントにデータを渡す場合は、エレメント同士を接続しなければいけません。これをリンクといいます。エレメント同士を接続するときは、パッドとパッドを接続します。
エレメントをつなぎ合わせて目的とする機能を実現したら、エレメントをパイプラインに入れます。パイプラインに入れると、エレメントの処理の開始・停止などを一括で指示できるようになります。それぞれのエレメントに対して指示する必要はありません。
エレメントはパッドの持ち方で以下の3種類に分類できます。
- ソースエレメント
- フィルタエレメント
- シンクエレメント
ソースエレメントはデータ出力用のパッド(ソースパッド)のみを持つエレメントです。データ生成用のエレメントで、エレメントのつなぎ合わせの先頭におきます。ファイルからデータを読み込むエレメントなどがソースエレメントです。
フィルタエレメントはデータの入力用パッド(シンクパッド)と出力用パッド(ソースパッド)を持つエレメントです。入力用と出力用のパッドを1つずつ持つエンコーダーやデコーダーのようにデータを変換するエレメントがあります。エレメントはパッドを複数持つことができます。マルチプレクサーは複数の入力から1つのコンテナフォーマットのデータを生成し、デマルチプレクサーは1つのコンテナフォーマットのデータを分解し、複数の出力データを生成します。
シンクエレメントはデータ入力用のパッド(シンクパッド)のみを持つエレメントです。データ受信用のエレメントで、エレメントのつなぎ合わせの最後におきます。ファイルにデータを出力するエレメントなどがシンクエレメントです。
目的の機能を実現するためにはソースエレメント→フィルタエレメント→…→フィルタエレメント→シンクエレメントというようにリンクします。
リンクしたエレメントはビン(パイプライン。パイプラインはビンの1種)に入れて利用します。
例えば、Ogg Vorbisを再生する場合はこのようにエレメントをリンクします。
どのエレメント同士もリンクできるわけではありません。パッドは受け付けられるMIME-typeを複数持っています。パッド同士が同じMIME-typeを利用する場合のみエレメントをリンクできます。
Ogg Vorbisプレイヤーの場合はこのようなMIME-typeのパッドでリンクしています。
Ogg Vorbis/Theoraプレイヤーはこのようになります。Oggデマルチプレクサーからの出力を両方とも利用しています。
まとめ
GStreamerはマルチメディアフレームワークで、マルチメディアを扱う場合に必要な機能が一通り揃っていて、GNOMEアプリケーションなど多くのアプリケーションで利用されていています。PhononやQuickTimeなど類似のソフトウェアがありますが、GStreamerはそれらと競合するソフトウェアではなく、それらと協調して動作します。
GStreamerにはエレメントとパッドとビンという概念があります。
エレメントはデータを処理するもので、複数のエレメントをつなぎ合わせて目的の機能を実現します。エレメント同士をつなぎ合わせることをリンクといい、エレメントをリンクするときはエレメントのパッドとパッドをつなぎ合わせます。リンクしたエレメントをビン(パイプライン)に入れて目的の機能を利用します。
ここではGStreamerの概要のみを扱ったので、省略したことがたくさんあります。
あしたのオープンソース研究所ではGStreamerのチュートリアルを翻訳してくれるそうです。チュートリアルにはここで説明したことより多くのことが書かれているので、GStreamerに興味を持った方はチュートリアルも読んでみてください。翻訳は1,2ヶ月後には公開されているようなので、2月か3月になると日本語でチュートリアルが読めるのではないでしょうか。楽しみですね。
解説付きで資料を公開してみました。スライド中で使っているSVGの画像やRabbitのソースもあわせて公開しました3。もし利用する場合ははじめにCOPYINGに書かれたライセンスを確認してください。