<div dir="ltr">Hello,<div><br></div><div style>I would like to use gst_element_query_duration() for determining the length of music files for use in a larger project that I am using GStreamer for. The problem is, it succeeds for some filetypes and succeeds for others. I've tried with multiple sets of music files and as far as I can tell, the query will fail solely depending on the filetype, not on the specific file that is used. Specifically, it works for MP3 and FLAC, while it fails for Ogg Vorbis and M4A (AAC). I have the proper codecs/plugins installed, as I am able to <i>play</i> all of the files via GStreamer, just not query their duration. Also, I am sure that the pipeline is properly set to GST_STATE_PAUSED in all cases, as my code verifies this. I've written some sample code that reproduces my problem and included it below:</div>
<div style><br></div><div style><div>#include <stdio.h></div><div>#include <gst/gst.h></div><div>#include <gst/app/gstappsink.h></div><div><br></div><div>void on_pad_added(GstElement *dec, GstPad *pad, GstElement *element)</div>
<div>{</div><div> (void) dec;</div><div> GstPad *sinkpad;</div><div><br></div><div> sinkpad = gst_element_get_static_pad(element, "sink");</div><div> if(!gst_pad_is_linked(sinkpad)) {</div><div> if(gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {</div>
<div> // Failed to link pads</div><div> fprintf(stderr, "Failed to link pads!\n");</div><div> }</div><div> }</div><div><br></div><div> gst_object_unref(sinkpad);</div><div>}</div>
<div><br></div><div>int main(int argc, char *argv[]) {</div><div> if (argc != 2) {</div><div> fprintf(stderr, "Error: format should be \"%s path_to_song\"\n", argv[0]);</div><div> exit(1);</div>
<div> }</div><div><br></div><div> GstElement *pipe, *dec, *conv, *sink;</div><div> gst_init(NULL, NULL);</div><div> </div><div> /* Create pipeline and elements */</div><div> pipe = gst_pipeline_new("pipeline");</div>
<div> dec = gst_element_factory_make("uridecodebin", NULL);</div><div> conv = gst_element_factory_make("audioconvert", NULL);</div><div> sink = gst_element_factory_make("appsink", NULL);</div>
<div> </div><div> /* Set up capabilities filtering */</div><div> GstCaps *caps = gst_caps_new_simple("audio/x-raw-float", "width", G_TYPE_INT, sizeof(double)*8, NULL);</div><div> gst_app_sink_set_caps(GST_APP_SINK(sink), caps);</div>
<div> gst_caps_unref(caps);</div><div> </div><div> /* Add everything to the pipeline and link up static pads */</div><div> gst_bin_add_many(GST_BIN(pipe), dec, conv, sink, NULL);</div><div> gst_element_link(conv, sink);</div>
<div> </div><div> /* Set up callback to link the decoder's dynamic pad tot he converter */</div><div> g_signal_connect(dec, "pad_added", G_CALLBACK(on_pad_added), conv);</div><div> </div><div> /* Set the uridecodebin's filename */</div>
<div> gst_element_set_state(pipe, GST_STATE_NULL);</div><div> g_object_set(G_OBJECT(dec), "uri", gst_filename_to_uri(argv[1], NULL), NULL);</div><div> </div><div> gst_element_set_state(pipe, GST_STATE_PAUSED);</div>
<div> GstStateChangeReturn res = gst_element_get_state(pipe, NULL, NULL, ((GstClockTime)1e9));</div><div> if (res != GST_STATE_CHANGE_SUCCESS) {</div><div> fprintf(stderr, "State change failed!\n");</div>
<div> exit(1);</div><div> }</div><div> </div><div> gint64 duration;</div><div> GstFormat format = GST_FORMAT_DEFAULT;</div><div> </div><div> if (gst_element_query_duration(GST_ELEMENT(dec), &format, &duration)) {</div>
<div> printf("duration = %d\n", duration);</div><div> } else {</div><div> printf("The query could not be performed!\n");</div><div> }</div><div>}</div><div><br></div><div><br></div>
<div>I am running Arch Linux and building this example with gstreamer-0.10.<br></div><div><br></div><div style>Thanks for your help,</div><div style>Nate Bogdanowicz</div></div></div>