Components
&GStreamer; includes several higher-level components to simplify your
applications life. All of the components discussed here (for now) are
targetted at media playback. The idea of each of these components is
to integrate as closely as possible with a &GStreamer; pipeline, but
to hide the complexity of media type detection and several other
rather complex topics that have been discussed in .
We currently recommend people to use either playbin (see ) or decodebin (see ), depending on their needs. The
other components discussed here are either outdated or deprecated. The
documentation is provided for legacy purposes. Use of those other
components is not recommended.
Playbin
Playbin is an element that can be created using the standard &GStreamer;
API (e.g. gst_element_factory_make ()). The factory
is conveniently called playbin
. By being a
GstElement, playbin automatically supports all
of the features of this class, including error handling, tag support,
state handling, getting stream positions, seeking, and so on.
Setting up a playbin pipeline is as simple as creating an instance of
the playbin element, setting a file location (this has to be a valid
URI, so <protocol>://<location>
, e.g.
file:///tmp/my.ogg or http://www.example.org/stream.ogg) using the
uri
property on playbin, and then setting the element
to the GST_STATE_PLAYING state. Internally,
playbin uses threads, so there's no need to iterate the element or
anything. However, one thing to keep in mind is that signals fired
by playbin might come from another than the main thread, so be sure
to keep this in mind in your signal handles. Most application
programmers will want to use a function such as g_idle_add
() to make sure that the signal is handled in the main
thread.
#include <gst/gst.h>
static void
cb_eos (GstElement *play,
gpointer data)
{
gst_main_quit ();
}
static void
cb_error (GstElement *play,
GstElement *src,
GError *err,
gchar *debug,
gpointer data)
{
g_print ("Error: %s\n", err->message);
}
gint
main (gint argc,
gchar *argv[])
{
GstElement *play;
/* init GStreamer */
gst_init (&argc, &argv);
/* make sure we have a URI */
if (argc != 2) {
g_print ("Usage: %s <URI>\n", argv[0]);
return -1;
}
/* set up */
play = gst_element_factory_make ("playbin", "play");
g_object_set (G_OBJECT (play), "uri", argv[1], NULL);
g_signal_connect (play, "eos", G_CALLBACK (cb_eos), NULL);
g_signal_connect (play, "error", G_CALLBACK (cb_error), NULL);
if (gst_element_set_state (play, GST_STATE_PLAYING) != GST_STATE_SUCCESS) {
g_print ("Failed to play\n");
return -1;
}
/* now run */
gst_main ();
/* also clean up */
gst_element_set_state (play, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (play));
return 0;
}
Playbin has several features that have been discussed previously:
Settable video and audio output (using the video-sink
and audio-sink
properties).
Mostly controllable and trackable as a
GstElement, including error handling, eos
handling, tag handling, state handling, media position handling and
seeking.
Buffers network-sources.
Supports visualizations for audio-only media.
Supports subtitles, both in the media as well as from separate
files.
Supports stream selection and disabling. If your media has
multiple audio or subtitle tracks, you can dynamically choose
which one to play back, or decide to turn it off alltogther
(which is especially useful to turn off subtitles).
Decodebin
Decodebin is the actual autoplugger backend of playbin, which was
discussed in the previous section. Decodebin will, in short, accept
input from a source that is linked to its sinkpad and will try to
detect the media type contained in the stream, and set up decoder
routines for each of those. It will automatically select decoders.
For each decoded stream, it will emit the new-decoded-pad
signal, to let the client know about the newly found decoded stream.
For unknown streams (which might be the whole stream), it will emit
the unknown-type
signal. The application is then
responsible for reporting the error to the user.
The example code below will play back an audio stream of an input
file. For readability, it does not include any error handling of
any sort.
#include <gst/gst.h>
GstElement *pipeline, *audio;
GstPad *audiopad;
static void
cb_newpad (GstElement *decodebin,
GstPad *pad,
gboolean last,
gpointer data)
{
GstCaps *caps;
GstStructure *str;
/* only link audio; only link once */
if (GST_PAD_IS_LINKED (audiopad))
return;
caps = gst_pad_get_caps (pad);
str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), "audio"))
return;
/* link'n'play */
gst_pad_link (pad, audiopad);
gst_bin_add (GST_BIN (pipeline), audio);
gst_bin_sync_children_state (GST_BIN (pipeline));
}
gint
main (gint argc,
gchar *argv[])
{
GstElement *src, *dec, *conv, *scale, *sink;
/* init GStreamer */
gst_init (&argc, &argv);
/* make sure we have input */
if (argc != 2) {
g_print ("Usage: %s <filename>\n", argv[0]);
return -1;
}
/* setup */
pipeline = gst_pipeline_new ("pipeline");
src = gst_element_factory_make ("filesrc", "source");
g_object_set (G_OBJECT (src), "location", argv[1], NULL);
dec = gst_element_factory_make ("decodebin", "decoder");
g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL);
audio = gst_bin_new ("audiobin");
conv = gst_element_factory_make ("audioconvert", "aconv");
audiopad = gst_element_get_pad (conv, "sink");
scale = gst_element_factory_make ("audioscale", "scale");
sink = gst_element_factory_make ("alsasink", "sink");
gst_bin_add_many (GST_BIN (audio), conv, scale, sink, NULL);
gst_element_link_many (conv, scale, sink, NULL);
gst_bin_add_many (GST_BIN (pipeline), src, dec, NULL);
gst_element_link (src, dec);
/* run */
gst_element_set_state (audio, GST_STATE_PAUSED);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
while (gst_bin_iterate (GST_BIN (pipeline))) ;
/* cleanup */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
Decodebin, similar to playbin, supports the following features:
Can decode an unlimited number of contained streams to decoded
output pads.
Is handled as a GstElement in all ways,
including tag or error forwarding and state handling.
Although decodebin is a good autoplugger, there's a whole lot of
things that it does not do and is not intended to do:
Taking care of input streams with a known media type (e.g. a DVD,
an audio-CD or such).
Selection of streams (e.g. which audio track to play in case of
multi-language media streams).
Overlaying subtitles over a decoded video stream.
Decodebin can be easily tested on the commandline, e.g. by using the
command gst-launch-0.8 filesrc location=file.ogg ! decodebin
! audioconvert ! audioscale ! alsasink.
Spider
Spider is an autoplugger that looks and feels very much like decodebin.
On the commandline, you can literally switch between spider and
decodebin and it'll mostly just work. Try, for example,
gst-launch-0.8 filesrc location=file.ogg ! spider !
audioconvert ! audioscale ! alsasink. Although the two may
seem very much alike from the outside, they are very different from
the inside. Those internal differences are the main reason why spider
is currently considered deprecated (along with the fact that it was
hard to maintain).
As opposed to decodebin, spider does not decode pads and emit signals
for each detected stream. Instead, you have to add output sinks to
spider by create source request pads and connecting those to sink
elements. This means that streams decoded by spider cannot be dynamic.
Also, spider uses many loop-based elements internally, which is rather
heavy scheduler-wise.
Code for using spider would look almost identical to the code of
decodebin, and is therefore omitted. Also, featureset and limitations
are very much alike, except for the above-mentioned extra limitations
for spider with respect to decodebin.
GstPlay
GstPlay is a GtkWidget with a simple API to play, pause and stop a media file.
GstEditor
GstEditor is a set of widgets to display a graphical representation of a
pipeline.