1 /* GStreamer
2 * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 #include <stdlib.h> /* exit() */
23 #include <gst/gst.h>
24
25 #define UPDATE_INTERVAL 500
26
27 static int arg_count;
28 static int max_count;
29
30 static gboolean
update_scale(GstElement * element)31 update_scale (GstElement * element)
32 {
33 gint64 duration = -1;
34 gint64 position = -1;
35 gchar dur_str[32], pos_str[32];
36
37 if (gst_element_query_position (element, GST_FORMAT_TIME, &position) &&
38 position != -1) {
39 g_snprintf (pos_str, 32, "%" GST_TIME_FORMAT, GST_TIME_ARGS (position));
40 } else {
41 g_snprintf (pos_str, 32, "-:--:--.---------");
42 }
43
44 if (gst_element_query_duration (element, GST_FORMAT_TIME, &duration) &&
45 duration != -1) {
46 g_snprintf (dur_str, 32, "%" GST_TIME_FORMAT, GST_TIME_ARGS (duration));
47 } else {
48 g_snprintf (dur_str, 32, "-:--:--.---------");
49 }
50
51 g_print ("%s / %s\n", pos_str, dur_str);
52
53 return TRUE;
54 }
55
56 static void
warning_cb(GstBus * bus,GstMessage * msg,gpointer foo)57 warning_cb (GstBus * bus, GstMessage * msg, gpointer foo)
58 {
59 GError *err = NULL;
60 gchar *dbg = NULL;
61
62 gst_message_parse_warning (msg, &err, &dbg);
63
64 g_printerr ("WARNING: %s (%s)\n", err->message, (dbg) ? dbg : "no details");
65
66 g_error_free (err);
67 g_free (dbg);
68 }
69
70 static void
error_cb(GstBus * bus,GstMessage * msg,GMainLoop * main_loop)71 error_cb (GstBus * bus, GstMessage * msg, GMainLoop * main_loop)
72 {
73 GError *err = NULL;
74 gchar *dbg = NULL;
75
76 gst_message_parse_error (msg, &err, &dbg);
77
78 g_printerr ("ERROR: %s (%s)\n", err->message, (dbg) ? dbg : "no details");
79
80 g_main_loop_quit (main_loop);
81
82 g_error_free (err);
83 g_free (dbg);
84 }
85
86 static void
eos_cb(GstBus * bus,GstMessage * msg,GMainLoop * main_loop)87 eos_cb (GstBus * bus, GstMessage * msg, GMainLoop * main_loop)
88 {
89 g_print ("EOS\n");
90 g_main_loop_quit (main_loop);
91 }
92
93 static void
new_clock_cb(GstBus * bus,GstMessage * msg,gpointer nothing)94 new_clock_cb (GstBus * bus, GstMessage * msg, gpointer nothing)
95 {
96 GstClock *clock;
97
98 gst_message_parse_new_clock (msg, &clock);
99 g_print ("NEW CLOCK: %s\n", GST_OBJECT_NAME (clock));
100 }
101
102 static void
clock_lost_cb(GstBus * bus,GstMessage * msg,GstElement * playbin)103 clock_lost_cb (GstBus * bus, GstMessage * msg, GstElement * playbin)
104 {
105 GstClock *clock;
106
107 gst_message_parse_clock_lost (msg, &clock);
108 g_print ("CLOCK LOST: %s\n", GST_OBJECT_NAME (clock));
109
110 gst_element_set_state (playbin, GST_STATE_PAUSED);
111 gst_element_set_state (playbin, GST_STATE_PLAYING);
112 }
113
114 static void
about_to_finish_cb(GstElement * element,gchar * uri[])115 about_to_finish_cb (GstElement * element, gchar * uri[])
116 {
117 if (arg_count < max_count) {
118 g_object_set (G_OBJECT (element), "uri", uri[arg_count], NULL);
119 arg_count++;
120 }
121 }
122
123 gint
main(gint argc,gchar * argv[])124 main (gint argc, gchar * argv[])
125 {
126 GstStateChangeReturn res;
127 GstElement *player;
128 GMainLoop *loop;
129 GstBus *bus;
130
131 gst_init (&argc, &argv);
132
133 loop = g_main_loop_new (NULL, TRUE);
134
135 if (argc < 2) {
136 g_print ("usage: %s <uri> [<uri> ... ]\n", argv[0]);
137 exit (-1);
138 }
139
140 player = gst_element_factory_make ("playbin", "player");
141 g_assert (player);
142
143 bus = gst_pipeline_get_bus (GST_PIPELINE (player));
144 gst_bus_add_signal_watch (bus);
145
146 g_signal_connect (bus, "message::eos", G_CALLBACK (eos_cb), loop);
147 g_signal_connect (bus, "message::error", G_CALLBACK (error_cb), loop);
148 g_signal_connect (bus, "message::warning", G_CALLBACK (warning_cb), NULL);
149 g_signal_connect (bus, "message::new-clock", G_CALLBACK (new_clock_cb), NULL);
150 g_signal_connect (bus, "message::clock-lost", G_CALLBACK (clock_lost_cb),
151 player);
152
153 g_object_set (G_OBJECT (player), "uri", argv[1], NULL);
154
155 arg_count = 2;
156 max_count = argc;
157 g_signal_connect (player, "about-to-finish", G_CALLBACK (about_to_finish_cb),
158 argv);
159
160 res = gst_element_set_state (player, GST_STATE_PLAYING);
161 if (res == GST_STATE_CHANGE_FAILURE) {
162 g_print ("could not play\n");
163 return -1;
164 }
165
166 g_timeout_add (UPDATE_INTERVAL, (GSourceFunc) update_scale, player);
167
168 g_main_loop_run (loop);
169
170 /* tidy up */
171 gst_element_set_state (player, GST_STATE_NULL);
172 gst_object_unref (player);
173 gst_object_unref (bus);
174
175 return 0;
176 }
177