GStreamer Playback API

Update: the code is now also available on GitHub which probably makes it easier for a few people to use it and contribute. Just send pull requests or create issues in the issue tracker of GitHub.

Over the last years I noticed that I was copying too much code to create simple GStreamer based playback applications. After talking to other people at GUADEC this year it was clear that this wasn’t only a problem on my side but a general problem. So here it is, a convenience API for creating GStreamer based playback applications: GstPlayer.

The API is really simple but is still missing many features:

GstPlayer *  gst_player_new       (void);

void         gst_player_play      (GstPlayer * player);
void         gst_player_pause     (GstPlayer * player);
void         gst_player_stop      (GstPlayer * player);
void         gst_player_seek      (GstPlayer * player, GstClockTime position);
void         gst_player_set_uri   (GstPlayer * player, const gchar * uri);

Additionally to that there are a few other properties (which are not only exposed as setters/getters but also as GObject properties), and signals to be notified about position changes, errors, end-of-stream and other useful information. You can find the complete API documentation here. In general the API is modeled similar to other existing APIs like Android’s MediaPlayer and iOS’ AVPlayer.

Included are also some very, very simple commandline, GTK+, Android (including nice Java bindings) and iOS apps. An APK for the Android app can also be found here. It provides no way to start a player, but whenever there is a video or audio file to be played it will be proposed as a possible application via the Android intent system.

In the end the goal is to have a replacement for most of the GStreamer code in e.g. GNOME‘s Totem video player, Enlightenment‘s Emotion or really any other playback application, and then have it integrated in a gst-plugins-base library (or a separate module with other convenience APIs).

While this is all clearly only the start, I hope that people already take a look at this and consider using it for their projects, provide patches, or help making the included sample apps really useful and nice-looking. Apps for other platforms (e.g. a Qt app, or one written in other languages like C# or Python) would also be nice to have. And if you’re an Android or iOS or Qt developer and have no idea about GStreamer you can still help by creating an awesome user interface 🙂 Ideally I would like to get the Android and iOS app into such a good shape that we can upload them to the app stores as useful GStreamer playback applications, which we could then also use to point people to a good demo.

If you’re interested and have some time to work on it or try it, please get in contact with me.

12 thoughts on “GStreamer Playback API”

  1. Fantastic work. I can’t believe this hadn’t been made earlier.
    I hope to see some more sophisticated functionality eventually introduced such as alternate scaling options, audio/video delay for syncing, etc. I’m not sure I’ve ever seen a gstreamer based player with the vlc/mplayer-like knobs for tweaking.

    1. What do you mean with alternative scaling options? To e.g. force-scaling the video to 16:9 although it is 4:3, letterboxing, …?

      That, and a/v delay tweaking could definitely be added later once the basics are there. It’s all relatively simple to implement 🙂

  2. Thanks, great to see these works on Mobile platform.
    Using the downloaded APK had Experienced some lags by comparing with the VLC player for a wmv file, is going to check with the build.

    1. Write me a mail if you need some help with this or have further details to share. Ideally we’d like to have this working as good as VLC or even better 🙂

  3. Thank you for developing the Playback API. I am studying the API codes and have some questions below. Hope you kindly answer my questions 🙂

    1) Why do play and pause APIs use g_main_context_invoke_full() to invoke another internal function?

    2) The stop API uses g_main_context_invoke_full() to invoke gst_player_stop_internal_dispatch() and the dispatch function simply calls gst_player_stop_internal(). Why the dispatch function is needed?

    3) In gst_player_set_property(), g_main_context_invoke_full() is also used to invoke another internal function for properities uri and suburi. Why gst_player_set_rate_internal() is directly called to set rate property without using g_main_context_invoke_full()?

    4) The other getter and setter APIs do not use g_main_context_invoke_full() to invoke another internal function. Is this because their tasks are pretty simple?


    1. The reason is that all those things are potentially blocking operations, so they get dispatched to the player’s main thread instead. It also has to do a bit with simplifying multithreading though (all operations happen from the player’s main thread, not arbitrary application threads, so fewer mutexes are needed).

      1. Thank you for your explanation. I realized that the principle is to perform these potentially blocking operations in the player’s main context as well as the player’s thread. These can be seen in play and pause APIs.

        But the stop API invokes another gst_player_stop_internal_dispatch() instead of invoking gst_player_stop_internal() directly in the player’s context. The dispatch function simply calls the stop internal function and removes the idle source. I do not understand why the dispatch function is needed.

      2. Stopping could also block for a while, so stop() calls stop_internal_dispatch() from the main loop, and from there calls stop_internal() and removes the GSource from the main loop (so this is done only once). stop_internal() itself is also called from other places.

Leave a Reply

Your email address will not be published.

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