title: GStreamer fails to get WAV file duration
body: <p>I am writing a class in Vala that loads and plays a WAV file using GStreamer.</p>
  
  <pre><code>class Sample : Object
  {
      private Gst.Pipeline gst_pipeline;
      private Gst.Bus      gst_pipeline_bus;
  
      private Gst.Element? reader;
      private Gst.Element? decoder;
      private Gst.Element? convertor;
      private Gst.Element? output;
  
      /* Read-only values */
  
      private bool    __playing = false;
      private string? __source  = null;
      private int64   __length  = -1;
  
      public bool playing {
          get { return __playing; }
      }
  
      public string? source {
          get { return __source; }
      }
  
      public int64 position {
          get {
              if (this.__source == null)
              {
                  return -1;
              }
              else
              {
                  int64 pos;
                  this.gst_pipeline.query_position(Gst.Format.TIME, out pos);
                  return pos;
              }
          }
      }
  
      public int64 length {
          get { return __length; }
      }
  
      /* Methods */
  
      public Sample()
      {
          this.gst_pipeline = new Gst.Pipeline(null);
  
          /* Create the elements */
          this.reader    = Gst.ElementFactory.make("filesrc", null);
          this.gst_pipeline.add(this.reader);
  
          this.decoder   = Gst.ElementFactory.make("wavparse", null);
          this.gst_pipeline.add(this.decoder);
          this.reader.link(this.decoder);
  
          this.convertor = Gst.ElementFactory.make("audioconvert", null);
          this.gst_pipeline.add(this.convertor);
          this.decoder.link(this.convertor);
  
          this.output    = Gst.ElementFactory.make("alsasink", null);
          this.gst_pipeline.add(this.output);
          this.convertor.link(this.output);
  
          /* Get the bus to send messages down */
          this.gst_pipeline_bus = this.gst_pipeline.get_bus();
          this.gst_pipeline_bus.add_signal_watch();
          this.gst_pipeline_bus.message.connect(this.on_gst_message);
      }
  
      ~Sample()
      {
          this.gst_pipeline.set_state(Gst.State.NULL);
      }
  
      public signal void finished();  // Called when the sample finished playing
      public signal void error(Error err);    // Called when GStreamer passes us an error message
  
      public void load(string path)
      {
          this.__source = path;
  
          /* Stop the playback */
          this.gst_pipeline.set_state(Gst.State.NULL);    // This stops the playback and resets the pipeline
          this.finished();
  
          /* Change the location */
          this.reader.set_property("location", path);
  
          /* Get the sample length */
          this.gst_pipeline.set_state(Gst.State.PAUSED);
          print("\t" + this.gst_pipeline.query_duration(Gst.Format.TIME, out this.__length).to_string() + "\n");
          this.gst_pipeline.set_state(Gst.State.NULL);
      }
  
      public void play()
      {
          this.__playing = true;
          this.gst_pipeline.set_state(Gst.State.PLAYING);
      }
  
      public void pause()
      {
          this.gst_pipeline.set_state(Gst.State.PAUSED);
          this.__playing = false;
      }
  
      private void on_gst_message(Gst.Message message)
      {
          /* Here we handle any messages that GStreamer may send us */
  
          switch (message.type)
          {
              case (Gst.MessageType.EOS): // End Of Stream
              {
                  this.gst_pipeline.set_state(Gst.State.NULL);
                  this.__playing = false;
                  this.finished();
  
                  break;
              }
              case (Gst.MessageType.ERROR):
              {
                  /* Stop playing */
                  this.gst_pipeline.set_state(Gst.State.NULL);
                  this.__playing = false;
  
                  /* Get the error */
                  Error err;
                  message.parse_error(out err, null);
  
                  /* Display the error */
                  this.error(err);
  
                  break;
              }
          }
      }
  }
  </code></pre>
  
  <p>I use the <code>filesrc</code>, <code>wavparse</code>, <code>audioconvert</code>, and <code>alsasink</code> pads to play the file.</p>
  
  <p>In the <code>load</code> method, I try to get the sample's duration by calling <code>Gst.Element.query_duration()</code> on the pipeline that I have created,
  however every time I try to do this, it returns <code>false</code> and sets the value I refer it to to <code>0</code>.</p>
  
  <p>I understand that a pipeline has to be pre-rolled to be able to get its duration, and although I've tried to pre-roll my pipeline by setting its state to <code>Gst.State.PAUSED</code>, <code>Gst.Element.query_duration()</code> keeps failing.</p>
  
  <p><b>What should I change to successfully get the duration of the WAV file I have loaded?</b></p>