2004-12-15 07:30:55 +00:00
|
|
|
<chapter id="chapter-components">
|
|
|
|
<title>Components</title>
|
|
|
|
|
|
|
|
<para>
|
2008-06-24 19:56:51 +00:00
|
|
|
&GStreamer; includes several higher-level components to simplify an
|
|
|
|
application developer's life. All of the components discussed here (for now) are
|
2004-12-15 17:32:49 +00:00
|
|
|
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 <xref
|
|
|
|
linkend="part-advanced"/>.
|
2004-12-15 07:30:55 +00:00
|
|
|
</para>
|
|
|
|
|
2004-12-15 17:32:49 +00:00
|
|
|
<para>
|
|
|
|
We currently recommend people to use either playbin (see <xref
|
|
|
|
linkend="section-components-playbin"/>) or decodebin (see <xref
|
2005-06-30 12:32:17 +00:00
|
|
|
linkend="section-components-decodebin"/>), depending on their needs.
|
|
|
|
Playbin is the recommended solution for everything related to simple
|
|
|
|
playback of media that should just work. Decodebin is a more flexible
|
2008-06-24 19:56:51 +00:00
|
|
|
autoplugger that could be used to add more advanced features, such
|
2005-06-30 12:32:17 +00:00
|
|
|
as playlist support, crossfading of audio tracks and so on. Its
|
|
|
|
programming interface is more low-level than that of playbin, though.
|
2004-12-15 07:30:55 +00:00
|
|
|
</para>
|
|
|
|
|
2004-12-15 17:32:49 +00:00
|
|
|
<sect1 id="section-components-playbin">
|
|
|
|
<title>Playbin</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Playbin is an element that can be created using the standard &GStreamer;
|
|
|
|
API (e.g. <function>gst_element_factory_make ()</function>). The factory
|
|
|
|
is conveniently called <quote>playbin</quote>. By being a
|
2005-06-30 12:32:17 +00:00
|
|
|
<classname>GstPipeline</classname> (and thus a
|
|
|
|
<classname>GstElement</classname>), playbin automatically supports all
|
2004-12-15 17:32:49 +00:00
|
|
|
of the features of this class, including error handling, tag support,
|
|
|
|
state handling, getting stream positions, seeking, and so on.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Setting up a playbin pipeline is as simple as creating an instance of
|
2008-06-24 19:56:51 +00:00
|
|
|
the playbin element, setting a file location using the
|
2004-12-15 17:32:49 +00:00
|
|
|
<quote>uri</quote> property on playbin, and then setting the element
|
2008-06-24 19:56:51 +00:00
|
|
|
to the <classname>GST_STATE_PLAYING</classname> state (the location has to be a valid
|
|
|
|
URI, so <quote><protocol>://<location></quote>, e.g.
|
|
|
|
file:///tmp/my.ogg or http://www.example.org/stream.ogg). Internally,
|
2005-06-30 12:32:17 +00:00
|
|
|
playbin will set up a pipeline to playback the media location.
|
2004-12-15 17:32:49 +00:00
|
|
|
</para>
|
|
|
|
|
2005-06-30 12:32:17 +00:00
|
|
|
<programlisting><!-- example-begin playbin.c a -->
|
2004-12-15 17:32:49 +00:00
|
|
|
#include <gst/gst.h>
|
2005-06-30 12:32:17 +00:00
|
|
|
<!-- example-end playbin.c a -->
|
|
|
|
[.. my_bus_callback goes here ..]<!-- example-begin playbin.c b --><!--
|
|
|
|
static gboolean
|
|
|
|
my_bus_callback (GstBus *bus,
|
|
|
|
GstMessage *message,
|
|
|
|
gpointer data)
|
2004-12-15 17:32:49 +00:00
|
|
|
{
|
2005-06-30 12:32:17 +00:00
|
|
|
GMainLoop *loop = data;
|
|
|
|
|
|
|
|
switch (GST_MESSAGE_TYPE (message)) {
|
|
|
|
case GST_MESSAGE_ERROR: {
|
|
|
|
GError *err;
|
|
|
|
gchar *debug;
|
|
|
|
|
|
|
|
gst_message_parse_error (message, &err, &debug);
|
|
|
|
g_print ("Error: %s\n", err->message);
|
|
|
|
g_error_free (err);
|
|
|
|
g_free (debug);
|
|
|
|
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GST_MESSAGE_EOS:
|
|
|
|
/* end-of-stream */
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* unhandled message */
|
|
|
|
break;
|
|
|
|
}
|
2004-12-15 17:32:49 +00:00
|
|
|
|
2005-06-30 12:32:17 +00:00
|
|
|
/* remove message from the queue */
|
|
|
|
return TRUE;
|
2004-12-15 17:32:49 +00:00
|
|
|
}
|
2005-06-30 12:32:17 +00:00
|
|
|
--><!-- example-end playbin.c b -->
|
|
|
|
<!-- example-begin playbin.c c -->
|
2004-12-15 17:32:49 +00:00
|
|
|
gint
|
|
|
|
main (gint argc,
|
|
|
|
gchar *argv[])
|
|
|
|
{
|
2005-06-30 12:32:17 +00:00
|
|
|
GMainLoop *loop;
|
2004-12-15 17:32:49 +00:00
|
|
|
GstElement *play;
|
2006-06-16 09:39:54 +00:00
|
|
|
GstBus *bus;
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* init GStreamer */
|
|
|
|
gst_init (&argc, &argv);
|
2005-06-30 12:32:17 +00:00
|
|
|
loop = g_main_loop_new (NULL, FALSE);
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* 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);
|
2006-06-16 09:39:54 +00:00
|
|
|
|
|
|
|
bus = gst_pipeline_get_bus (GST_PIPELINE (play));
|
|
|
|
gst_bus_add_watch (bus, my_bus_callback, loop);
|
|
|
|
gst_object_unref (bus);
|
|
|
|
|
2005-06-30 12:32:17 +00:00
|
|
|
gst_element_set_state (play, GST_STATE_PLAYING);
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* now run */
|
2005-06-30 12:32:17 +00:00
|
|
|
g_main_loop_run (loop);
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* also clean up */
|
|
|
|
gst_element_set_state (play, GST_STATE_NULL);
|
|
|
|
gst_object_unref (GST_OBJECT (play));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2005-06-30 12:32:17 +00:00
|
|
|
<!-- example-end playbin.c c --></programlisting>
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
<para>
|
|
|
|
Playbin has several features that have been discussed previously:
|
|
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Settable video and audio output (using the <quote>video-sink</quote>
|
|
|
|
and <quote>audio-sink</quote> properties).
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Mostly controllable and trackable as a
|
|
|
|
<classname>GstElement</classname>, including error handling, eos
|
2005-06-30 12:32:17 +00:00
|
|
|
handling, tag handling, state handling (through the
|
|
|
|
<classname>GstBus</classname>), media position handling and
|
2004-12-15 17:32:49 +00:00
|
|
|
seeking.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2005-06-30 12:32:17 +00:00
|
|
|
Buffers network-sources, with buffer fullness notifications being
|
|
|
|
passed through the <classname>GstBus</classname>.
|
2004-12-15 17:32:49 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Supports visualizations for audio-only media.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
2005-01-17 15:23:53 +00:00
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Supports subtitles, both in the media as well as from separate
|
2005-06-30 12:32:17 +00:00
|
|
|
files. For separate subtitle files, use the <quote>suburi</quote>
|
|
|
|
property.
|
2005-01-17 15:23:53 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Supports stream selection and disabling. If your media has
|
|
|
|
multiple audio or subtitle tracks, you can dynamically choose
|
2011-09-07 11:14:38 +00:00
|
|
|
which one to play back, or decide to turn it off altogether
|
2005-06-30 12:32:17 +00:00
|
|
|
(which is especially useful to turn off subtitles). For each
|
|
|
|
of those, use the <quote>current-text</quote> and other related
|
|
|
|
properties.
|
2005-01-17 15:23:53 +00:00
|
|
|
</para>
|
|
|
|
</listitem>
|
2004-12-15 17:32:49 +00:00
|
|
|
</itemizedlist>
|
2005-06-30 12:32:17 +00:00
|
|
|
<para>
|
|
|
|
For convenience, it is possible to test <quote>playbin</quote> on
|
2005-12-11 17:49:10 +00:00
|
|
|
the commandline, using the command <quote>gst-launch-0.10 playbin
|
2005-06-30 12:32:17 +00:00
|
|
|
uri=file:///path/to/file</quote>.
|
|
|
|
</para>
|
2009-06-03 00:56:10 +00:00
|
|
|
<para>
|
|
|
|
New applications should use playbin2 instead of the old playbin.
|
|
|
|
</para>
|
2004-12-15 17:32:49 +00:00
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="section-components-decodebin">
|
|
|
|
<title>Decodebin</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
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 <quote>new-decoded-pad</quote>
|
|
|
|
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 <quote>unknown-type</quote> signal. The application is then
|
|
|
|
responsible for reporting the error to the user.
|
|
|
|
</para>
|
2005-06-30 12:32:17 +00:00
|
|
|
<programlisting><!-- example-begin decodebin.c a -->
|
2004-12-15 17:32:49 +00:00
|
|
|
#include <gst/gst.h>
|
2005-06-30 12:32:17 +00:00
|
|
|
<!-- example-end decodebin.c a -->
|
|
|
|
[.. my_bus_callback goes here ..]<!-- example-begin decodebin.c b --><!--
|
|
|
|
static gboolean
|
|
|
|
my_bus_callback (GstBus *bus,
|
|
|
|
GstMessage *message,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GMainLoop *loop = data;
|
|
|
|
|
|
|
|
switch (GST_MESSAGE_TYPE (message)) {
|
|
|
|
case GST_MESSAGE_ERROR: {
|
|
|
|
GError *err;
|
|
|
|
gchar *debug;
|
|
|
|
|
|
|
|
gst_message_parse_error (message, &err, &debug);
|
|
|
|
g_print ("Error: %s\n", err->message);
|
|
|
|
g_error_free (err);
|
|
|
|
g_free (debug);
|
|
|
|
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GST_MESSAGE_EOS:
|
|
|
|
/* end-of-stream */
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* unhandled message */
|
|
|
|
break;
|
|
|
|
}
|
2004-12-15 17:32:49 +00:00
|
|
|
|
2005-06-30 12:32:17 +00:00
|
|
|
/* remove message from the queue */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
--><!-- example-end decodebin.c b -->
|
|
|
|
<!-- example-begin decodebin.c c -->
|
2004-12-15 17:32:49 +00:00
|
|
|
GstElement *pipeline, *audio;
|
|
|
|
|
|
|
|
static void
|
|
|
|
cb_newpad (GstElement *decodebin,
|
|
|
|
GstPad *pad,
|
|
|
|
gboolean last,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GstCaps *caps;
|
|
|
|
GstStructure *str;
|
2005-06-30 12:32:17 +00:00
|
|
|
GstPad *audiopad;
|
2004-12-15 17:32:49 +00:00
|
|
|
|
2005-06-30 12:32:17 +00:00
|
|
|
/* only link once */
|
2008-05-21 15:51:25 +00:00
|
|
|
audiopad = gst_element_get_static_pad (audio, "sink");
|
2005-06-30 12:32:17 +00:00
|
|
|
if (GST_PAD_IS_LINKED (audiopad)) {
|
|
|
|
g_object_unref (audiopad);
|
2004-12-15 17:32:49 +00:00
|
|
|
return;
|
2005-06-30 12:32:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check media type */
|
2011-05-16 14:10:49 +00:00
|
|
|
caps = gst_pad_get_caps (pad, NULL);
|
2004-12-15 17:32:49 +00:00
|
|
|
str = gst_caps_get_structure (caps, 0);
|
2005-06-30 12:32:17 +00:00
|
|
|
if (!g_strrstr (gst_structure_get_name (str), "audio")) {
|
|
|
|
gst_caps_unref (caps);
|
|
|
|
gst_object_unref (audiopad);
|
2004-12-15 17:32:49 +00:00
|
|
|
return;
|
2005-06-30 12:32:17 +00:00
|
|
|
}
|
|
|
|
gst_caps_unref (caps);
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* link'n'play */
|
|
|
|
gst_pad_link (pad, audiopad);
|
2009-11-09 11:42:35 +00:00
|
|
|
|
|
|
|
g_object_unref (audiopad);
|
2004-12-15 17:32:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
main (gint argc,
|
|
|
|
gchar *argv[])
|
|
|
|
{
|
2005-06-30 12:32:17 +00:00
|
|
|
GMainLoop *loop;
|
|
|
|
GstElement *src, *dec, *conv, *sink;
|
|
|
|
GstPad *audiopad;
|
2006-06-16 09:39:54 +00:00
|
|
|
GstBus *bus;
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* init GStreamer */
|
|
|
|
gst_init (&argc, &argv);
|
2005-06-30 12:32:17 +00:00
|
|
|
loop = g_main_loop_new (NULL, FALSE);
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* make sure we have input */
|
|
|
|
if (argc != 2) {
|
|
|
|
g_print ("Usage: %s <filename>\n", argv[0]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup */
|
|
|
|
pipeline = gst_pipeline_new ("pipeline");
|
2006-06-16 09:39:54 +00:00
|
|
|
|
|
|
|
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
|
|
|
gst_bus_add_watch (bus, my_bus_callback, loop);
|
|
|
|
gst_object_unref (bus);
|
|
|
|
|
2004-12-15 17:32:49 +00:00
|
|
|
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);
|
2005-06-30 12:32:17 +00:00
|
|
|
gst_bin_add_many (GST_BIN (pipeline), src, dec, NULL);
|
|
|
|
gst_element_link (src, dec);
|
|
|
|
|
|
|
|
/* create audio output */
|
2004-12-15 17:32:49 +00:00
|
|
|
audio = gst_bin_new ("audiobin");
|
|
|
|
conv = gst_element_factory_make ("audioconvert", "aconv");
|
2008-05-21 15:51:25 +00:00
|
|
|
audiopad = gst_element_get_static_pad (conv, "sink");
|
2004-12-15 17:32:49 +00:00
|
|
|
sink = gst_element_factory_make ("alsasink", "sink");
|
2005-06-30 12:32:17 +00:00
|
|
|
gst_bin_add_many (GST_BIN (audio), conv, sink, NULL);
|
|
|
|
gst_element_link (conv, sink);
|
|
|
|
gst_element_add_pad (audio,
|
|
|
|
gst_ghost_pad_new ("sink", audiopad));
|
|
|
|
gst_object_unref (audiopad);
|
|
|
|
gst_bin_add (GST_BIN (pipeline), audio);
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* run */
|
|
|
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
2005-06-30 12:32:17 +00:00
|
|
|
g_main_loop_run (loop);
|
2004-12-15 17:32:49 +00:00
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
|
|
gst_object_unref (GST_OBJECT (pipeline));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2005-06-30 12:32:17 +00:00
|
|
|
<!-- example-end decodebin.c c --></programlisting>
|
2004-12-15 17:32:49 +00:00
|
|
|
|
2004-12-15 21:45:55 +00:00
|
|
|
<para>
|
|
|
|
Decodebin, similar to playbin, supports the following features:
|
|
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Can decode an unlimited number of contained streams to decoded
|
|
|
|
output pads.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Is handled as a <classname>GstElement</classname> in all ways,
|
|
|
|
including tag or error forwarding and state handling.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
2004-12-15 17:32:49 +00:00
|
|
|
<para>
|
|
|
|
Although decodebin is a good autoplugger, there's a whole lot of
|
|
|
|
things that it does not do and is not intended to do:
|
|
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Taking care of input streams with a known media type (e.g. a DVD,
|
|
|
|
an audio-CD or such).
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Selection of streams (e.g. which audio track to play in case of
|
|
|
|
multi-language media streams).
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Overlaying subtitles over a decoded video stream.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
2004-12-15 21:45:55 +00:00
|
|
|
<para>
|
|
|
|
Decodebin can be easily tested on the commandline, e.g. by using the
|
2009-06-03 00:56:10 +00:00
|
|
|
command <command>gst-launch-0.10 filesrc location=file.ogg ! decodebin
|
|
|
|
! audioconvert ! audioresample ! autoaudiosink</command>.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
New applications should use decodebin2 instead of the old decodebin.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The uridecodebin element is very similar to decodebin2, only that it
|
|
|
|
automatically plugs a source plugin based on the protocol of the URI
|
|
|
|
given.
|
2004-12-15 21:45:55 +00:00
|
|
|
</para>
|
2004-12-15 17:32:49 +00:00
|
|
|
</sect1>
|
|
|
|
|
2004-12-15 07:30:55 +00:00
|
|
|
</chapter>
|