GStreamer hello world

Continuing my previous GStreamer introduction this new tutorial will guide you on your first GStreamer application written in C.

For anxious people the code is here.

The Basics

We first start creating a playbin, which is a GStreamer element:

GstElement *pipeline = gst_element_factory_make("playbin", "player");

Then we specify the URI we want to play, i.e. file://tmp/foobar.mp3

g_object_set(G_OBJECT(pipeline), "uri", uri, NULL);

Now, we would want to play this:

gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);

But nothing would happen if we don’t have a GLib mainloop:

GMainLoop *loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);

And of course, we need to initialize GStreamer:

gst_init(&argc, &argv);

or, if you don’t have argc/argv available:

gst_init(NULL, NULL);

That’s it, at the end you should stop the pipeline and free it:

gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));

Compilation

Nothing complicated here, pkg-config will tell us all we need to know:

gcc `pkg-config --cflags --libs gstreamer-0.10` hello.c -o gst_hello

The Bus

Great! we have something that plays, but it won’t even exit properly, nor show any errors.

In order to get messages, errors, and other important information while the mainloop is running we need a bus watch from this pipeline:

GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
gst_bus_add_watch(bus, bus_call, NULL);
gst_object_unref(bus);
static gboolean
bus_call(GstBus *bus,
	 GstMessage *msg,
	 gpointer user_data)
{
	switch (GST_MESSAGE_TYPE(msg)) {
	case GST_MESSAGE_EOS: break;
	case GST_MESSAGE_ERROR: break;
	default: break;
	}

	return true;
}

When we get the EOS message, we would like to exit the application, right?

g_main_loop_quit(loop);

And if we get an ERROR message, we would like to display it, and exit:

gchar *debug;
GError *err;

gst_message_parse_error(msg, &err, &debug);
g_free(debug);

g_error("%s", err->message);
g_error_free(err);

g_main_loop_quit(loop);

It seems we have everything!

Enjoy

Now you can listen to your music or watch videos with this. And remember, it receives a URI, so “test.avi” won’t work, you need the whole thing:

./gst_hello "file://$PWD/test.avi"

Or even better!

./gst_hello http://www.xiph.org/vorbis/listen/compilation-ogg-q4.ogg

20 thoughts on “GStreamer hello world

  1. Got a few questions:
    1. Can I use plain /dev/dsp to play audio on the tablet? It works on the emulator in the SDK but I am not sure it will work on a real thing.
    2. Could you give an example of how to play one’s own audio (i.e. ring buffer with samples) using GStreamer? The play-from-file example is cute, but it is not a typical usage model.

    Like

  2. 1. No, /dev/dsp is from OSS AFAIK, and the device doesn’t ship with that. There is esd and ALSA support, but I think there’s only an alsasink GStreamer element.

    2. There are many possible examples. I can write an example to play with the stream.

    So, basically you want to generate your own stream of PCM data (not use any GStreamer source element) and play that on the device?

    Like

  3. 1. Too bad 😦 I thought ALSA was also providing /dev/dsp though, wasn’t it?

    2. Correct. Basically, I have a ring buffer and need to stream it to the speaker. Also need to know where the current read position is in that buffer.

    Like

  4. It is in memory. gstappsrc and gstappsink are the keywords. I will dig in that. I want to use this on a Nokia N810, because gstreamer seems the only reliable thing on the N8xx to record audio to a memory buffer.
    But: the appsrc and appsink are in the gstreamer-bad-plugins. Don’t know if they are installed on a plain N8xx with Maemo 4.x

    -Klaus

    Like

  5. Pingback: 100,000 views, and some stats « Felipe Contreras

  6. May I ask about the sample that Luarvique was asking about that data streaming?

    I have a project here that would implement a bluetooth sink.
    I’m using a freescale board and a wifi/bluetooth bundle with A2DP, one of the profile that it has are just bluetooth source so it can only send data to a bluetooth speaker. But my setup here is that the board has a speaker connected in it and I wanted to send data to it and make it able to play the received data so basically its PCM data.

    Any input would be appreciated so much, Thank you.

    Like

  7. @jesus Unfortunately I’m not familiar with such setups, fortunately there’s a pretty good mailing list for asking these questions; gstreamer-devel.

    Like

  8. Your compilation command will not work with most of gcc versions. Try this instead:

    gcc hello.c -o gst_hello `pkg-config –cflags –libs gstreamer-0.10`

    Like

  9. For the compiling line. It did not work for me. Gcc usually expects library flags after the sources.
    -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lxml2 -lglib-2.0
    At least on my PC: gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

    Like

  10. Hello,
    I’d like to know how to play a video using a path that a user would have written before, in the cmd (I’m using windows), just with a cout<> path, and then the video starts.
    Regards,

    Like

  11. Hello ,
    I need your help ,i have a problem when i execute my gstreamer application
    (process:2642): GLib-GObject-CRITICAL **: gtype.c:2458: initialization assertion failed, use IA__g_type_init() prior to this n

    (process:2642): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0′ failed

    (process:2642): GLib-GObject-CRITICAL **: gtype.c:2458: initialization assertion failed, use IA__g_type_init() prior to this n

    (process:2642): GLib-CRITICAL **: g_once_init_leave: assertion `initialization_value != 0′ failed

    (process:2642): GLib-GObject-CRITICAL **: gtype.c:2458: initialization assertion failed, use IA__g_type_init() prior to this n

    Thanks a lot;

    Like

  12. Felipe,

    As I struggled a bit with ubuntu to compile your example, I copy paste the one I used :
    > g++ $(pkg-config –cflags –libs gstreamer-0.10) main.cpp -o gst_hello.exe $(pkg-config –libs glib-2.0) $(pkg-config –cflags –libs gstreamer-0.10)

    In order to avoid a bunch of “undefined reference” error messages. It is important to repeat the pkg-config after main.cpp -o gst_hello.exe

    Nicolas Sauvaget.

    Like

  13. Hello ,
    I have followed the SDK tutorial to build the examples on Windows 7 and visual studio 2010.
    There is no problem while compiling and building but I am not able to view the video from the given URL…it just opens a form but nothing is visible there.
    My internet connection is pretty good.
    Can you help please.

    I also wanted to try the Gstreamer on Ubuntu and followed the SDK installation steps.
    The first step step where we have to download the appropriate definition file for our distribution:
    When i Click on the Link i Get the follwing link opened–>
    deb http://www.freedesktop.org/software/gstreamer-sdk/data/packages/ubuntu/quantal/amd64 ./
    Now , if I take http://www.freedesktop.org/software/gstreamer-sdk/data/packages/ubuntu/quantal/amd64 there are number of packages available.
    So, which file should i take to place it in the /etc/apt/sources.list.d/

    Thanks in Advance 🙂

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.