1 /* 2 * gstreamer_helloworld is placed in the 3 * public domain. 4 */ 5 6 module gstreamer_helloworld; 7 8 import std.stdio; 9 10 //gtkD imports: 11 12 import glib.Str; 13 import gtk.Main; 14 15 //gstreamerD imports: 16 17 import gstreamer.GStreamer; 18 19 import gobject.ObjectG; 20 import glib.ErrorG; 21 import gstreamer.Element; 22 import gstreamer.Pipeline; 23 import gstreamer.ElementFactory; 24 import gstreamer.Pad; 25 import gstreamer.Message; 26 import gstreamer.Bus; 27 28 import gstreamerc.gstreamertypes; 29 import gstreamerc.gstreamer; 30 31 import gtkc.glib; 32 33 34 class GstHello 35 { 36 public: 37 38 bool busCall( Message msg ) 39 { 40 debug(gstreamer) 41 { 42 writefln("GstHello.busCall(msg) START."); 43 scope(exit) writefln("GstHello.busCall(msg) END."); 44 } 45 46 switch( msg.type ) 47 { 48 case GstMessageType.UNKNOWN: 49 writefln("Unknown message type."); 50 break; 51 case GstMessageType.EOS: 52 writefln("End-of-stream."); 53 Main.quit(); 54 break; 55 56 case GstMessageType.ERROR: 57 { 58 string dbug; 59 ErrorG err; 60 msg.parseError(err, dbug); 61 //g_free (dbug); 62 writefln("Error: %s dbug: %s", Str.toString(err.getErrorGStruct().message), dbug); 63 Main.quit(); 64 break; 65 } 66 default: 67 break; 68 } 69 70 return true; 71 } 72 73 this(string file) 74 { 75 // create elements 76 77 pipeline = new Pipeline("audio-player"); 78 79 source = ElementFactory.make("filesrc", "file-source"); 80 parser = ElementFactory.make("oggdemux", "ogg-parser"); 81 decoder = ElementFactory.make("vorbisdec", "vorbis-decoder"); 82 conv = ElementFactory.make("audioconvert", "converter"); 83 sink = ElementFactory.make("alsasink", "alsa-output"); 84 85 if( pipeline is null || source is null || parser is null || decoder is null || conv is null || sink is null ) 86 { 87 writefln("One or more element could not be created"); 88 89 if( pipeline is null ) writefln(" : no pipeline."); 90 if( source is null ) writefln(" : no source."); 91 if( parser is null ) writefln(" : no parser."); 92 if( decoder is null ) writefln(" : no decoder."); 93 if( conv is null ) writefln(" : no conv."); 94 if( sink is null ) writefln(" : no sink."); 95 96 throw new Exception("One or more gstreamerD elements could not be created."); 97 } 98 99 // set filename property on the file source. Also add a message handler. 100 101 source.location( file ); //You can also use this like a D property: source.location = file; 102 //Or you can also do: source.setProperty("location", file); 103 104 pipeline.getBus().addWatch( &busCall ); 105 106 // put all elements in a bin 107 pipeline.addMany( source, parser, decoder, conv, sink ); 108 109 // link together - note that we cannot link the parser and 110 // decoder yet, because the parser uses dynamic pads. For that, 111 // we set a pad-added signal handler. 112 source.link( parser ); 113 114 //shouldbe, but doesn't work yet: 115 //decoder.linkMany( conv, sink ); 116 decoder.link( conv ); 117 conv.link( sink ); 118 //Here's where we set the pad-added signal handler. It will 119 //connect the dynamic pads when they become available. 120 parser.addOnPadAdded(&newPad); 121 122 // Now set to playing and iterate. 123 writefln("Setting to PLAYING."); 124 pipeline.setState( GstState.PLAYING ); 125 writefln("Running."); 126 } 127 128 ~this() 129 { 130 pipeline.setState( GstState.NULL ); 131 } 132 133 void newPad( Pad pad, Element element ) 134 { 135 writefln("newPad callback called. START."); 136 137 Pad sinkpad; 138 139 // We can now link this pad with the audio decoder 140 writefln("Dynamic pad created, linking parser/decoder"); 141 142 sinkpad = decoder.getStaticPad("sink"); 143 144 writefln("doing a gst_pad_link."); 145 146 pad.link( sinkpad ); 147 148 writefln("Done. That was ok."); 149 } 150 151 protected: 152 153 Pipeline pipeline; 154 Element source, parser, decoder, conv, sink; 155 } 156 157 158 int main(string[] args) 159 { 160 writefln("gstreamerD Hello World!"); 161 162 uint major, minor, micro, nano; 163 164 writefln("Trying to init..."); 165 166 //Main.init(args); 167 GStreamer.init(args); 168 169 // check input arguments 170 if (args.length != 2) 171 { 172 writefln("Usage: %s <Ogg/Vorbis filename>", args[0]); 173 174 return -1; 175 } 176 177 writefln("Checking version of GStreamer..."); 178 179 GStreamer.versio(major, minor, micro, nano); 180 181 writefln("The installed version of GStreamer is %s.%s.%s", major, minor, micro ); 182 writefln( "The file is: %s", args[1] ); 183 184 GstHello gstHello = new GstHello( args[1] ); 185 186 //We must use the gtkD mainloop to run gstreamerD apps. 187 Main.run(); 188 189 return 0; 190 }