はじめに
オープンソースのマルチメディアフレームワークとしてGStreamerがあります。音声・動画の再生、フォーマットの変換、録音・録画など基本的なことはもちろん、RTSPなどを用いたネットワーク通信を行うこともできます。
以前、あしたのオープンソース研究所: GStreamerという記事でGStreamerの概要や仕組みについて紹介しました。 今回はGStreamerで音声・動画の再生等を複数のエレメントを組合せて使うときに必要なパイプラインの組み立てかたについて紹介します。
GStreamerの仕組み
あしたのオープンソース研究所: GStreamerでも触れたように、GStreamerの概要を理解するために大事な概念は以下の4つです1。
- エレメント
- リンク
- パッド
- パイプライン(ビン)
ただ、GStreamerで動画を再生するだけならplaybinを使うことで上記の概念を意識することなく簡単に再生できます。その際は、GStreamerに付属しているgst-launch-1.0を使います。Ubuntuのexample-contentパッケージにOggのサンプル動画が含まれているのでそれを再生してみましょう。次のコマンドを実行するとOgg動画を再生できます。
% gst-launch-1.0 playbin uri="file:///usr/share/example-content/Ubuntu_Free_Culture_Showcase/How fast.ogg"
playbinを使う場合には、動画を引数とするだけで簡単に再生できることがわかりました。では、個々のエレメントを組みあわせて動画再生したいときにはどのようにすればいいのでしょうか。
エレメントをつないでパイプラインを組み立てる
基本的には次の手順でエレメントをつないでパイプラインを組み立てることができます。
- mediainfoで動画の情報を確認する
- 動画フォーマットに対応したdemuxerを調べる
- demuxerに対応するdecoderを調べる
- decoderに対応するsinkを調べる
mediainfoで動画の情報を確認する
まずは、動画の情報を確認しましょう。mediainfoコマンドを使うと動画の情報を知ることができます。
% mediainfo /usr/share/example-content/Ubuntu_Free_Culture_Showcase/How\ fast.ogg
General
Complete name : /usr/share/example-content/Ubuntu_Free_Culture_Showcase/How fast.ogg
Format : OGG
File size : 1.83 MiB
Duration : 30s 584ms
Overall bit rate mode : Variable
Overall bit rate : 501 Kbps
Writing application : VLC media player
Video
ID : 314165387 (0x12B9C88B)
Format : Theora
Duration : 30s 597ms
Bit rate : 344 Kbps
Nominal bit rate : 800 Kbps
Width : 1 280 pixels
Height : 720 pixels
Display aspect ratio : 16:9
Frame rate : 29.970 fps
Compression mode : Lossy
Bits/(Pixel*Frame) : 0.012
Stream size : 1.26 MiB (69%)
Writing library : Xiph.Org libtheora 1.1 20090822 (Thusnelda)
Audio
ID : 314165386 (0x12B9C88A)
Format : Vorbis
Format settings, Floor : 1
Duration : 30s 584ms
Bit rate mode : Variable
Bit rate : 128 Kbps
Channel(s) : 2 channels
Sampling rate : 44.1 KHz
Compression mode : Lossy
Stream size : 478 KiB (26%)
Writing library : libVorbis (Everywhere) (20100325 (Everywhere))
Ogg動画であることと、映像のフォーマットがTheora、音声のコーデックはVorbisであることがわかります。
動画フォーマットに対応したdemuxerを調べる
動画の音声と映像を両方というのはひとまずおいて、映像だけ再生することをまず考えてみましょう。エレメントの詳細を調べるのには、GStreamerに付属しているgst-inspect-1.0を使います。
まずは、Oggに関係のあるエレメントをgst-inspect-1.0を使って探してみます。動画から映像を抜き出すには通常demuxerを使います。なので、oggdemuxというエレメントを使うとよさそうです。
% gst-inspect-1.0 | grep ogg
typefindfunctions: application/x-id3v2: mp3, mp2, mp1, mpga, ogg, flac, tta
typefindfunctions: application/x-id3v1: mp3, mp2, mp1, mpga, ogg, flac, tta
typefindfunctions: application/ogg: ogg, oga, ogv, ogm, ogx, spx, anx, axa, axv
typefindfunctions: application/x-ogg-skeleton: no extensions
libav: avmux_ogg: libav Ogg muxer (not recommended, use oggmux instead)
ogg: oggdemux: Ogg demuxer
ogg: oggmux: Ogg muxer
ogg: ogmaudioparse: OGM audio stream parser
ogg: ogmvideoparse: OGM video stream parser
ogg: ogmtextparse: OGM text stream parser
ogg: oggparse: Ogg parser
ogg: oggaviparse: Ogg AVI parser
では、oggdemuxがどんな機能を持っているかを確認してみましょう。それにはシンクとソースのCapabilities欄を見るとわかります。シンクではaudio/oggやvideo/oggに対応していることがわかります。また、ソースには制限がないことがわかります。
% gst-inspect-1.0 oggdemux
(途中略)
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
application/ogg
audio/ogg
video/ogg
application/kate
SRC template: 'src_%08x'
Availability: Sometimes
Capabilities:
ANY
demuxerに対応するdecoderを調べる
次はoggdemuxで抜きだした映像をデコードしてやる必要があります。映像のフォーマットはTheoraでした。gst-inspect-1.0で同じように探してみましょう。
% gst-inspect-1.0 | grep theora
theora: theoradec: Theora video decoder
theora: theoraenc: Theora video encoder
theora: theoraparse: Theora video parser
typefindfunctions: video/x-theora: no extensions
rtp: rtptheoradepay: RTP Theora depayloader
rtp: rtptheorapay: RTP Theora payloader
theoradecというdecoderがあるのがわかりました。theoradecのCapabilitiesをgst-inspect-1.0で確認してみましょう。
% gst-inspect-1.0 theoradec
(途中略)
Pad Templates:
SRC template: 'src'
Availability: Always
Capabilities:
video/x-raw
format: { I420, Y42B, Y444 }
framerate: [ 0/1, 2147483647/1 ]
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
SINK template: 'sink'
Availability: Always
Capabilities:
video/x-theora
シンクがvideo/x-theoraに対応していて、ソースがvideo/x-rawに対応していることがわかります。
decoderに対応するsinkを調べる
次は、video/x-rawに対応した表示のためのシンクエレメントを探せばよいことになります。先に答えを言うとxvimagesinkがvideo/x-rawに対応したシンクエレメントです2。
% gst-inspect-1.0 xvimagesink
(途中略)
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
video/x-raw
framerate: [ 0/1, 2147483647/1 ]
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
というわけで、上記の情報から次のようなパイプラインを組み立てれば良いことがわかります。
% gst-launch-1.0 filesrc location="/usr/share/example-content/Ubuntu_Free_Culture_Showcase/How fast.ogg" ! oggdemux ! theoradec ! xvimagesink
実際に上記コマンドを実行すると動画がきちんと再生できました。
まとめ
今回はGStreamerのエレメントをつないだパイプラインの組み立てかたを紹介しました。gst-inspect-1.0を使うことで、エレメントの持つ機能を詳しく知り、どのエレメントとつなげることができるかがわかります。エレメント名にautoがついているエレメントはそのあたりを気にせずに使えて便利ですが、パイプラインがどこまできちんと動作しているかを知りたいときなど、明示的に特定のエレメントを使って確認する必要にせまられることもあります。そんなときに、どうやって組みたてたら良いか知っていると問題解決に役立つのではないでしょうか。