Pipeline with audio format detection

Pipeline with audio format detection

For MP3 I load the following GstElements into the pipeline.

  • ‘filesrc’, ‘mpegaudioparse’, ‘mpg123audiodec’, ‘audioconvert’, ‘audioresample’, ‘volume’, ‘autoaudiosink’

And for Flac the following

  • ‘filesrc’, ‘flacparse’, ‘flacdec’, ‘audioconvert’, ‘audioresample’, ‘volume’, ‘autoaudiosink’

Now to the question, is there a universal parser and decoder that recognizes the audio format itself?

The only universal one that I know of is the following.

gst_parse_launch ("playbin uri=file:/home/tux/desk/test.mp3", NULL);

You may try using decodebin (or decodebin3):

gst-launch-1.0 filesrc location=/home/tux/desk/test.mp3 ! decodebin ! audioconvert ! volume ! autoaudiosink
1 Like

Thanks, it works with playbin.
It makes the whole thing a lot easier.

pipeline = gst_parse_launch("filesrc location=test.flac ! decodebin ! audioconvert ! volume ! autoaudiosink", NULL);

From what I saw, you left out audioresample.
It seems that it is not necessary for normal playback?

I just removed it when trying simplest case and it worked without.

Not sure, there might be cases where it would be required, so you might want to add it into the pipeline, it shouldn’t result into a significant overhead if there is no resampling to be done.

1 Like

I put it back in.
It’s important to me that it works.
It’s a huge relief for me that you don’t have to create a separate pipeline for each format.

If you want to manage network streams as well as files, you may use element uridecodebin that can further handle many network formats:

uridecodebin uri=file:///home/user/Music/test.flac ! audioconvert ! audioresample ! autoaudiosink

uridecodebin uri=rtsp://<your_rtsp_server_IP>:<rtsp_port>/your_stream ! audioconvert ! audioresample ! autoaudiosink

Not all audio sinks (e.g. soundcards) can handle all sample rates. If there is a mismatch between what the sink can handle and what the rest of the pipeline is using, you need the audioresample. Same principle for audioconvert. Usually you want to keep these elements in and ensure your pipeline is robust, as mentioned, there’s no perf penalty in the cases they’re not needed.

I’ve encountered a problem with decodebin. As soon as I use it, GST_STATE_READY and GST_STATE_PLAYING no longer work.

If I upload my piece of music like this, I can do READY, PLAYING and PAUSED as much as I want. Even when the piece has finished playing, I can go to READY and then PLAYING and it starts again from the beginning.

pipeline = gst_parse_launch("filesrc location=test.wav ! wavparse ! audioconvert ! volume ! autoaudiosink", NULL);

If I do it with decodebin, only PAUSED and PLAYING work. As soon as I go to READY or the piece is over, nothing works anymore.

pipeline = gst_parse_launch("filesrc location=test.wav ! decodebin ! audioconvert ! volume ! autoaudiosink", NULL);

What could be the reason for this?

Here is the whole code:

// gcc main.c -o main `pkg-config --cflags --libs gstreamer-1.0 gstreamer-audio-1.0`

#include <stdio.h>
#include <stdlib.h>
#include <gst/gst.h>
#include <glib.h>

int main(int argc, char *argv[]) {
    GstElement *pipeline;
    gboolean quit = FALSE;
    char ch;

    gst_init(&argc, &argv);

//    pipeline = gst_parse_launch("filesrc location=test.wav ! decodebin ! audioconvert ! autoaudiosink", NULL);

    pipeline = gst_parse_launch("filesrc location=test.wav ! wavparse ! audioconvert ! volume ! autoaudiosink", NULL);
    
    printf("<1> = stop;  <2> = play;  <3> = pause  <CTRL+C> = break\n");

    while (!quit) {
        ch = getchar(); 
        switch (ch) {
            case '1':
                gst_element_set_state(pipeline, GST_STATE_READY);
                break;
            case '2':
                gst_element_set_state(pipeline, GST_STATE_PLAYING);
                break;
            case '3':
                gst_element_set_state(pipeline, GST_STATE_PAUSED);
                break;
        }
    }

    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}