gstremer-sharpでOgg/Speexを再生する

demuxerを使った場合のLinkのさせ方で詰まったのでメモ。

初期化
var path = @"C:\gstreamer";
Environment.SetEnvironmentVariable("PATH", String.Format(@"C:\Windows;{0}\lib;{0}\bin", path));
Environment.SetEnvironmentVariable("GST_PLUGIN_PATH", "");
Environment.SetEnvironmentVariable("GST_PLUGIN_SYSTEM_PATH", String.Format(@"{0}\bin\plugins", path));

Environment.SetEnvironmentVariable("GST_DEBUG", "*:3");
Environment.SetEnvironmentVariable("GST_DEBUG_FILE", "GstreamerLog.txt");
Environment.SetEnvironmentVariable("GST_DEBUG_DUMP_DOT_DIR", path);

Gst.Application.Init();
パイプラインを構築して実行
gst-launch -v filesrc location=test.ogg ^
            ! oggdemux ^
            ! speexdec ^
            ! audioconvert ^
            ! audioresample ^
            ! autoaudiosink

と同等のものをC#で組み立てる。

var loop = new Gst.GLib.MainLoop();

var pipeline = new Pipeline("player");
var source = ElementFactory.Make("filesrc", "file-source");
var demuxer = ElementFactory.Make("oggdemux", "ogg-demuxer");
var decoder = ElementFactory.Make("speexdec", "speex-decoder");
var conveter = ElementFactory.Make("audioconvert", "converter");
var resampler = ElementFactory.Make("audioresample", "resampler");
var sink = ElementFactory.Make("autoaudiosink", "audio-output");

source["location"] = @"C:\test.ogg";

pipeline.Add(source, demuxer, decoder, conveter, resampler, sink);

if (!source.Link(demuxer))
    throw new Exception("link failed between source and demuxer");

demuxer.PadAdded += new PadAddedHandler((o, args) =>
{
    args.Pad.Link(decoder.GetStaticPad("sink"));
});

if (!decoder.Link(conveter)) 
    throw new Exception("link failed between decoder and converter");

if (!conveter.Link(resampler)) 
    throw new Exception("link failed between converter and resampler");

if (!resampler.Link(sink)) 
    throw new Exception("link failed between resampler and sink");

pipeline.SetState(State.Playing);

loop.Run();

pipeline.SetState(State.Null);
pipeline.Dispose();