aab66b826153dcf5519560f0b769eb82b1e4605a
[platform/upstream/gstreamer.git] / manual-metadata.md
1 ---
2 title: Metadata
3 ...
4
5 # Metadata
6
7 GStreamer makes a clear distinction between two types of metadata, and
8 has support for both types. The first is stream tags, which describe the
9 content of a stream in a non-technical way. Examples include the author
10 of a song, the title of that very same song or the album it is a part
11 of. The other type of metadata is stream-info, which is a somewhat
12 technical description of the properties of a stream. This can include
13 video size, audio samplerate, codecs used and so on. Tags are handled
14 using the GStreamer tagging system. Stream-info can be retrieved from a
15 `GstPad` by getting the current (negotiated) `GstCaps` for that pad.
16
17 ## Metadata reading
18
19 Stream information can most easily be read by reading it from a
20 `GstPad`. This has already been discussed before in [Using capabilities
21 for metadata](manual-pads.md#using-capabilities-for-metadata).
22 Therefore, we will skip it here. Note that this requires access to all
23 pads of which you want stream information.
24
25 Tag reading is done through a bus in GStreamer, which has been discussed
26 previously in [Bus](manual-bus.md). You can listen for
27 `GST_MESSAGE_TAG` messages and handle them as you wish.
28
29 Note, however, that the `GST_MESSAGE_TAG` message may be fired multiple
30 times in the pipeline. It is the application's responsibility to put all
31 those tags together and display them to the user in a nice, coherent
32 way. Usually, using `gst_tag_list_merge ()` is a good enough way of
33 doing this; make sure to empty the cache when loading a new song, or
34 after every few minutes when listening to internet radio. Also, make
35 sure you use `GST_TAG_MERGE_PREPEND` as merging mode, so that a new
36 title (which came in later) has a preference over the old one for
37 display.
38
39 The following example will extract tags from a file and print them:
40
41 ``` c
42 /* compile with:
43  * gcc -o tags tags.c `pkg-config --cflags --libs gstreamer-1.0` */
44 #include <gst/gst.h>
45
46 static void
47 print_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data)
48 {
49   int i, num;
50
51   num = gst_tag_list_get_tag_size (list, tag);
52   for (i = 0; i < num; ++i) {
53     const GValue *val;
54
55     /* Note: when looking for specific tags, use the gst_tag_list_get_xyz() API,
56      * we only use the GValue approach here because it is more generic */
57     val = gst_tag_list_get_value_index (list, tag, i);
58     if (G_VALUE_HOLDS_STRING (val)) {
59       g_print ("\t%20s : %s\n", tag, g_value_get_string (val));
60     } else if (G_VALUE_HOLDS_UINT (val)) {
61       g_print ("\t%20s : %u\n", tag, g_value_get_uint (val));
62     } else if (G_VALUE_HOLDS_DOUBLE (val)) {
63       g_print ("\t%20s : %g\n", tag, g_value_get_double (val));
64     } else if (G_VALUE_HOLDS_BOOLEAN (val)) {
65       g_print ("\t%20s : %s\n", tag,
66           (g_value_get_boolean (val)) ? "true" : "false");
67     } else if (GST_VALUE_HOLDS_BUFFER (val)) {
68       GstBuffer *buf = gst_value_get_buffer (val);
69       guint buffer_size = gst_buffer_get_size (buf);
70
71       g_print ("\t%20s : buffer of size %u\n", tag, buffer_size);
72     } else if (GST_VALUE_HOLDS_DATE_TIME (val)) {
73       GstDateTime *dt = g_value_get_boxed (val);
74       gchar *dt_str = gst_date_time_to_iso8601_string (dt);
75
76       g_print ("\t%20s : %s\n", tag, dt_str);
77       g_free (dt_str);
78     } else {
79       g_print ("\t%20s : tag of type '%s'\n", tag, G_VALUE_TYPE_NAME (val));
80     }
81   }
82 }
83
84 static void
85 on_new_pad (GstElement * dec, GstPad * pad, GstElement * fakesink)
86 {
87   GstPad *sinkpad;
88
89   sinkpad = gst_element_get_static_pad (fakesink, "sink");
90   if (!gst_pad_is_linked (sinkpad)) {
91     if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
92       g_error ("Failed to link pads!");
93   }
94   gst_object_unref (sinkpad);
95 }
96
97 int
98 main (int argc, char ** argv)
99 {
100   GstElement *pipe, *dec, *sink;
101   GstMessage *msg;
102   gchar *uri;
103
104   gst_init (&argc, &argv);
105
106   if (argc < 2)
107     g_error ("Usage: %s FILE or URI", argv[0]);
108
109   if (gst_uri_is_valid (argv[1])) {
110     uri = g_strdup (argv[1]);
111   } else {
112     uri = gst_filename_to_uri (argv[1], NULL);
113   }
114
115   pipe = gst_pipeline_new ("pipeline");
116
117   dec = gst_element_factory_make ("uridecodebin", NULL);
118   g_object_set (dec, "uri", uri, NULL);
119   gst_bin_add (GST_BIN (pipe), dec);
120
121   sink = gst_element_factory_make ("fakesink", NULL);
122   gst_bin_add (GST_BIN (pipe), sink);
123
124   g_signal_connect (dec, "pad-added", G_CALLBACK (on_new_pad), sink);
125
126   gst_element_set_state (pipe, GST_STATE_PAUSED);
127
128   while (TRUE) {
129     GstTagList *tags = NULL;
130
131     msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipe),
132         GST_CLOCK_TIME_NONE,
133         GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_TAG | GST_MESSAGE_ERROR);
134
135     if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_TAG) /* error or async_done */
136       break;
137
138     gst_message_parse_tag (msg, &tags);
139
140     g_print ("Got tags from element %s:\n", GST_OBJECT_NAME (msg->src));
141     gst_tag_list_foreach (tags, print_one_tag, NULL);
142     g_print ("\n");
143     gst_tag_list_unref (tags);
144
145     gst_message_unref (msg);
146   }
147
148   if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
149     GError *err = NULL;
150
151     gst_message_parse_error (msg, &err, NULL);
152     g_printerr ("Got error: %s\n", err->message);
153     g_error_free (err);
154   }
155
156   gst_message_unref (msg);
157   gst_element_set_state (pipe, GST_STATE_NULL);
158   gst_object_unref (pipe);
159   g_free (uri);
160   return 0;
161 }
162     
163 ```
164
165 ## Tag writing
166
167 Tag writing is done using the
168 [`GstTagSetter`](http://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagSetter.html)
169 interface. All that's required is a tag-set-supporting element in your
170 pipeline. In order to see if any of the elements in your pipeline
171 supports tag writing, you can use the function
172 `gst_bin_iterate_all_by_interface (pipeline,
173 GST_TYPE_TAG_SETTER)`. On the resulting element, usually an encoder or
174 muxer, you can use `gst_tag_setter_merge
175 ()` (with a taglist) or `gst_tag_setter_add
176 ()` (with individual tags) to set tags on it.
177
178 A nice extra feature in GStreamer tag support is that tags are preserved
179 in pipelines. This means that if you transcode one file containing tags
180 into another media type, and that new media type supports tags too, then
181 the tags will be handled as part of the data stream and be merged into
182 the newly written media file, too.
183