[Rhythmbox-devel] monkey-media error handling and spider bits



So for completeness, here is the rest of the differences my local
monkey-media tree has.  As discussed a bit on IRC, I added the ability
to use spider instead of the typefind bits for specific URI schemes
(like "http").  This is very useful for iradio.  Until the new gstreamer
stuff is in, I would really like to have this in monkey-media.  After
that comes out we can dump/adapt it to use the new gstreamer stuff, and
require the latest gstreamer version.

Secondly, the patch adds the ability to do error handling.
Index: tests/test-cmdline.c
===================================================================
RCS file: /cvs/gnome/monkey-media/tests/test-cmdline.c,v
retrieving revision 1.7
diff -u -d -I$Id: -r1.7 test-cmdline.c
--- tests/test-cmdline.c	25 Jan 2003 12:34:18 -0000	1.7
+++ tests/test-cmdline.c	26 Jan 2003 08:22:01 -0000
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <stdlib.h>
 #include <glib.h>
 #include <monkey-media.h>
 
@@ -37,10 +38,18 @@
 	GEnumValue *enumvalue = g_enum_get_value(g_type_class_peek(MONKEY_MEDIA_TYPE_STREAM_INFO_FIELD),
 						 field);
 	char *str = g_strdup_value_contents(value);
-	fprintf(stdout, "info: %s: %s\n", enumvalue->value_name, str);
+	fprintf (stdout, "info: %s: %s\n", enumvalue->value_name, str);
 	g_free(str);
 }
 
+void
+error_cb (MonkeyMediaPlayer *player, char *errmsg, gpointer data)
+{
+	fprintf (stderr, "Error: %s\n", errmsg);
+	monkey_media_main_quit ();
+	exit (1);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -64,6 +73,9 @@
 		  fprintf (stderr, "Unable to load %s: %s\n", argv[1], error->message);
 		  g_error_free (error);
 	}
+
+	g_signal_connect (G_OBJECT (player), "error",
+	                  G_CALLBACK (error_cb), NULL);
 
 	g_signal_connect (G_OBJECT (player), "info",
 	                  G_CALLBACK (info), NULL);
Index: src/monkey-media-player.h
===================================================================
RCS file: /cvs/gnome/monkey-media/src/monkey-media-player.h,v
retrieving revision 1.6
diff -u -d -I$Id: -r1.6 monkey-media-player.h
--- src/monkey-media-player.h	25 Jan 2003 12:34:17 -0000	1.6
+++ src/monkey-media-player.h	26 Jan 2003 08:22:01 -0000
@@ -64,6 +64,7 @@
 	void (*eos)  (MonkeyMediaPlayer *mp);
 	void (*info) (MonkeyMediaPlayer *mp, MonkeyMediaStreamInfoField field,
 		      GValue *value);
+	void (*error)(MonkeyMediaPlayer *mp, const char *errmsg);
 	void (*tick) (MonkeyMediaPlayer *mp, long elapsed);
 } MonkeyMediaPlayerClass;
 
Index: src/monkey-media-player-gst.c
===================================================================
RCS file: /cvs/gnome/monkey-media/src/monkey-media-player-gst.c,v
retrieving revision 1.6
diff -u -d -I$Id: -r1.6 monkey-media-player-gst.c
--- src/monkey-media-player-gst.c	25 Jan 2003 20:12:26 -0000	1.6
+++ src/monkey-media-player-gst.c	26 Jan 2003 08:22:02 -0000
@@ -26,6 +26,7 @@
 #include <gst/control/control.h>
 #include <gst/control/dparam_smooth.h>
 #include <math.h>
+#include <string.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
 
 #include "monkey-media.h"
@@ -68,6 +69,7 @@
 {
 	EOS,
 	INFO,
+	ERROR,
 	TICK,
 	LAST_SIGNAL
 } MonkeyMediaPlayerSignalType;
@@ -77,7 +79,10 @@
 	GObject *object;
 	MonkeyMediaStreamInfoField info_field;
 	GValue *info;
-} MonkeyMediaPlayerInfoSignal;
+	char *error;
+} MonkeyMediaPlayerSignal;
+
+const char *typefind_excluded_uris[] = {"http", NULL};
 
 static guint monkey_media_player_signals[LAST_SIGNAL] = { 0 };
 
@@ -139,6 +144,16 @@
 			      2,
 			      MONKEY_MEDIA_TYPE_STREAM_INFO_FIELD,
 			      G_TYPE_POINTER);
+	monkey_media_player_signals[ERROR] =
+		g_signal_new ("error",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (MonkeyMediaPlayerClass, error),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE,
+			      1,
+			      G_TYPE_POINTER);
 	monkey_media_player_signals[TICK] =
 		g_signal_new ("tick",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -207,6 +222,28 @@
 	g_idle_add ((GSourceFunc) eos_signal_idle, mp);
 }
 
+static gboolean
+error_signal_idle (MonkeyMediaPlayerSignal *signal)
+{
+	g_signal_emit (G_OBJECT (signal->object), monkey_media_player_signals[ERROR], 0,
+		       signal->error);
+	g_free (signal->error);
+	g_free (signal);
+	return FALSE;
+}
+
+static void
+error_cb (GstElement *element,
+	  GObject *arg1,
+	  char *errmsg,
+	  MonkeyMediaPlayer *mp)
+{
+	MonkeyMediaPlayerSignal *signal = g_new0 (MonkeyMediaPlayerSignal, 1);
+	signal->object = G_OBJECT (mp);
+	signal->error = g_strdup (errmsg);
+	g_idle_add ((GSourceFunc) error_signal_idle, signal);
+}
+
 static void
 have_type_cb (GstElement *element,
 	      GstCaps *caps,
@@ -217,7 +254,7 @@
 }
 
 static gboolean
-info_signal_idle (MonkeyMediaPlayerInfoSignal *signal)
+info_signal_idle (MonkeyMediaPlayerSignal *signal)
 {
 	g_signal_emit (signal->object, monkey_media_player_signals[INFO], 0,
 		       signal->info_field, signal->info);
@@ -263,9 +300,9 @@
 
 	if (ev != NULL)
 	{
-		MonkeyMediaPlayerInfoSignal *signal;
+		MonkeyMediaPlayerSignal *signal;
 
-		signal = g_new0 (MonkeyMediaPlayerInfoSignal, 1);
+		signal = g_new0 (MonkeyMediaPlayerSignal, 1);
 
 		signal->info_field = ev->value;
 		signal->info = value;
@@ -318,6 +355,11 @@
 	mp->priv->pipeline = gst_thread_new ("pipeline");
 
 	g_signal_connect (G_OBJECT (mp->priv->pipeline),
+			  "error",
+			  G_CALLBACK (error_cb),
+			  mp);
+
+	g_signal_connect (G_OBJECT (mp->priv->pipeline),
 			  "deep_notify",
 			  G_CALLBACK (deep_notify_cb),
 			  mp);
@@ -413,6 +455,75 @@
 	return quark;
 }
 
+static void
+get_decoder (MonkeyMediaPlayer *mp, const char *uri,
+	     GError **error)
+{
+	gboolean typefind_is_excluded = FALSE;;
+	int i;
+
+	mp->priv->have_type = FALSE;
+
+	for (i = 0; typefind_excluded_uris[i]; i++)
+	{
+		if (!strncmp (typefind_excluded_uris[i], uri, strlen(typefind_excluded_uris[i])))
+		{
+			typefind_is_excluded = TRUE;
+			break;
+		}
+	}
+
+	if (typefind_is_excluded)
+	{
+		mp->priv->decoder = gst_element_factory_make ("spider", "decoder");
+		return;
+	}
+
+	gst_element_set_state (mp->priv->typefind_pipeline,
+			       GST_STATE_PLAYING);
+	
+	while (!mp->priv->have_type) {
+		if (!gst_bin_iterate (GST_BIN (mp->priv->typefind_pipeline))) {
+			char *unesc = gnome_vfs_unescape_string_for_display (uri);
+			g_set_error (error,
+				     MONKEY_MEDIA_PLAYER_ERROR,
+				     MONKEY_MEDIA_PLAYER_ERROR_NO_DEMUX_PLUGIN,
+				     _("Failed to find a decoder plugin for %s; check your installation"),
+				     unesc);
+			g_free (unesc);
+			return;
+		}
+	}
+
+	gst_element_set_state (mp->priv->typefind_pipeline,
+			       GST_STATE_NULL);
+
+	mp->priv->decoder = NULL;
+
+	if (strstr (mp->priv->type, "mp3")) {
+		mp->priv->decoder = gst_element_factory_make ("mad", "decoder");
+	} else if (strstr (mp->priv->type, "x-ogg")) {
+		mp->priv->decoder = gst_element_factory_make ("vorbisfile", "decoder");
+	} else if (strstr (mp->priv->type, "x-flac")) {
+		mp->priv->decoder = gst_element_factory_make ("flacdec", "decoder");
+	} else if (strstr (mp->priv->type, "x-wav")) {
+		mp->priv->decoder = gst_element_factory_make ("wavparse", "decoder");
+	} else if (strstr (mp->priv->type, "x-mod") || strstr (mp->priv->type, "x-s3m") ||
+		   strstr (mp->priv->type, "x-xm")  || strstr (mp->priv->type, "x-it")) {
+		mp->priv->decoder = gst_element_factory_make ("modplug", "decoder");
+	}
+
+	if (mp->priv->decoder == NULL) {
+		g_set_error (error,
+			     MONKEY_MEDIA_PLAYER_ERROR,
+			     MONKEY_MEDIA_PLAYER_ERROR_NO_DEMUX_PLUGIN,
+			     _("Mime type %s not handled; check your installation"),
+			     mp->priv->type);
+	}
+
+	g_free (mp->priv->type);
+}
+
 void
 monkey_media_player_open (MonkeyMediaPlayer *mp,
 			  const char *uri,
@@ -450,8 +561,6 @@
 		gst_bin_remove (GST_BIN (mp->priv->pipeline), mp->priv->decoder);
 	}
 
-	mp->priv->have_type = FALSE;
-
 	/* Internet radio support */
 	iradio_mode = !strncmp ("http", uri, 4);
 	g_object_set (G_OBJECT (mp->priv->src),
@@ -464,51 +573,9 @@
 	g_object_set (G_OBJECT (mp->priv->typefind_src),
 		      "location", uri, NULL);
 
-	gst_element_set_state (mp->priv->typefind_pipeline,
-			       GST_STATE_PLAYING);
-
-	while (!mp->priv->have_type) {
-		if (!gst_bin_iterate (GST_BIN (mp->priv->typefind_pipeline))) {
-			char *unesc = gnome_vfs_unescape_string_for_display (uri);
-			g_set_error (error,
-				     MONKEY_MEDIA_PLAYER_ERROR,
-				     MONKEY_MEDIA_PLAYER_ERROR_NO_DEMUX_PLUGIN,
-				     _("Failed to find a decoder plugin for %s; check your installation"),
-				     unesc);
-			g_free (unesc);
-			return;
-		}
-	}
-
-	gst_element_set_state (mp->priv->typefind_pipeline,
-			       GST_STATE_NULL);
-
-	mp->priv->decoder = NULL;
-
-	if (strstr (mp->priv->type, "mp3")) {
-		mp->priv->decoder = gst_element_factory_make ("mad", "decoder");
-	} else if (strstr (mp->priv->type, "x-ogg")) {
-		mp->priv->decoder = gst_element_factory_make ("vorbisfile", "decoder");
-	} else if (strstr (mp->priv->type, "x-flac")) {
-		mp->priv->decoder = gst_element_factory_make ("flacdec", "decoder");
-	} else if (strstr (mp->priv->type, "x-wav")) {
-		mp->priv->decoder = gst_element_factory_make ("wavparse", "decoder");
-	} else if (strstr (mp->priv->type, "x-mod") || strstr (mp->priv->type, "x-s3m") ||
-		   strstr (mp->priv->type, "x-xm")  || strstr (mp->priv->type, "x-it")) {
-		mp->priv->decoder = gst_element_factory_make ("modplug", "decoder");
-	}
-
-	if (mp->priv->decoder == NULL) {
-		g_set_error (error,
-			     MONKEY_MEDIA_PLAYER_ERROR,
-			     MONKEY_MEDIA_PLAYER_ERROR_NO_DEMUX_PLUGIN,
-			     _("Mime type %s not handled; check your installation"),
-			     mp->priv->type);
-		g_free (mp->priv->type);
+	get_decoder (mp, uri, error);
+	if (*error != NULL)
 		return;
-	}
-
-	g_free (mp->priv->type);
 
 	mp->priv->uri = g_strdup (uri);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]