[rhythmbox] add player 'redirect' signal for dealing with GStreamer redirects (bug #581885)
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] add player 'redirect' signal for dealing with GStreamer redirects (bug #581885)
- Date: Tue, 22 Jun 2010 09:50:38 +0000 (UTC)
commit 4ae911249b516b59e80c434fda102cb352e805ea
Author: Robert Ancell <robert ancell gmail com>
Date: Tue Jun 22 19:41:33 2010 +1000
add player 'redirect' signal for dealing with GStreamer redirects (bug #581885)
The main use for these at present is for redirects from mms:// URIs to rtsp://,
which happens when mmssrc fails to connect to an mms stream. We handle the redirect
by stopping the current stream, updating the URI for the database entry, then trying to
play it again.
backends/gstreamer/rb-player-gst.c | 5 +++-
backends/rb-player.c | 35 ++++++++++++++++++++++++++++++++++
backends/rb-player.h | 4 +++
lib/rb-marshal.list | 1 +
shell/rb-shell-player.c | 37 +++++++++++++++++++++++++++++++++--
5 files changed, 78 insertions(+), 4 deletions(-)
---
diff --git a/backends/gstreamer/rb-player-gst.c b/backends/gstreamer/rb-player-gst.c
index 2cb42c5..671395c 100644
--- a/backends/gstreamer/rb-player-gst.c
+++ b/backends/gstreamer/rb-player-gst.c
@@ -613,6 +613,9 @@ bus_cb (GstBus *bus, GstMessage *message, RBPlayerGst *mp)
rb_debug ("got playbin2-stream-changed message");
mp->priv->playbin_stream_changing = FALSE;
emit_playing_stream_and_tags (mp, TRUE);
+ } else if (gst_structure_has_name (structure, "redirect")) {
+ const char *uri = gst_structure_get_string (structure, "new-location");
+ _rb_player_emit_redirect (RB_PLAYER (mp), mp->priv->stream_data, uri);
}
break;
@@ -786,7 +789,7 @@ impl_close (RBPlayer *player, const char *uri, GError **error)
}
if (mp->priv->playbin != NULL) {
- start_state_change (mp, GST_STATE_READY, PLAYER_SHUTDOWN);
+ start_state_change (mp, GST_STATE_NULL, PLAYER_SHUTDOWN);
}
return TRUE;
}
diff --git a/backends/rb-player.c b/backends/rb-player.c
index 41d3016..08a8f5f 100644
--- a/backends/rb-player.c
+++ b/backends/rb-player.c
@@ -44,6 +44,7 @@ enum {
PLAYING_STREAM,
VOLUME_CHANGED,
IMAGE,
+ REDIRECT,
LAST_SIGNAL
};
@@ -274,6 +275,25 @@ rb_player_interface_init (RBPlayerIface *iface)
G_TYPE_NONE,
2,
G_TYPE_POINTER, GDK_TYPE_PIXBUF);
+
+ /**
+ * RBPlayer::redirect:
+ * @player: the #RBPlayer
+ * @stream_data: data associated with the stream
+ * @uri: URI to redirect to
+ *
+ * The 'redirect' signal is emitted to indicate when a stream has change URI.
+ */
+ signals[REDIRECT] =
+ g_signal_new ("redirect",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (RBPlayerIface, redirect),
+ NULL, NULL,
+ rb_marshal_VOID__POINTER_STRING,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_POINTER, G_TYPE_STRING);
}
GType
@@ -691,6 +711,21 @@ _rb_player_emit_image (RBPlayer *player, gpointer stream_data, GdkPixbuf *image)
g_signal_emit (player, signals[IMAGE], 0, stream_data, image);
}
+/**
+ * _rb_player_emit_redirect:
+ * @player: a #RBPlayer implementation
+ * @stream_data: data associated with the stream
+ * @uri: URI to redirect to
+ *
+ * Emits the 'redirect' signal to notify listeners that the stream has been
+ * redirected. To be used by implementations only.
+ */
+void
+_rb_player_emit_redirect (RBPlayer *player, gpointer stream_data, const char *uri)
+{
+ g_signal_emit (player, signals[REDIRECT], 0, stream_data, uri);
+}
+
GQuark
rb_player_error_quark (void)
{
diff --git a/backends/rb-player.h b/backends/rb-player.h
index f03a414..24f001f 100644
--- a/backends/rb-player.h
+++ b/backends/rb-player.h
@@ -130,6 +130,9 @@ struct _RBPlayerIface
void (*image) (RBPlayer *player,
gpointer stream_data,
GdkPixbuf *image);
+ void (*redirect) (RBPlayer *player,
+ gpointer stream_data,
+ const gchar *uri);
};
GType rb_player_get_type (void);
@@ -172,6 +175,7 @@ void _rb_player_emit_event (RBPlayer *player, gpointer stream_data, const char *
void _rb_player_emit_playing_stream (RBPlayer *player, gpointer stream_data);
void _rb_player_emit_volume_changed (RBPlayer *player, float volume);
void _rb_player_emit_image (RBPlayer *player, gpointer stream_data, GdkPixbuf *image);
+void _rb_player_emit_redirect (RBPlayer *player, gpointer stream_data, const char *uri);
G_END_DECLS
diff --git a/lib/rb-marshal.list b/lib/rb-marshal.list
index 2e1a9fe..73fa151 100644
--- a/lib/rb-marshal.list
+++ b/lib/rb-marshal.list
@@ -41,6 +41,7 @@ VOID:POINTER,LONG,LONG
VOID:POINTER,OBJECT
VOID:POINTER,POINTER
VOID:POINTER,POINTER,POINTER
+VOID:POINTER,STRING
VOID:POINTER,UINT
VOID:POINTER,ULONG
VOID:STRING,DOUBLE
diff --git a/shell/rb-shell-player.c b/shell/rb-shell-player.c
index 1157b78..7a36201 100644
--- a/shell/rb-shell-player.c
+++ b/shell/rb-shell-player.c
@@ -183,6 +183,10 @@ static void rb_shell_player_extra_metadata_cb (RhythmDB *db,
GValue *metadata,
RBShellPlayer *player);
+static gboolean rb_shell_player_open_location (RBShellPlayer *player,
+ RhythmDBEntry *entry,
+ RBPlayerPlayType play_type,
+ GError **error);
static gboolean rb_shell_player_do_next_internal (RBShellPlayer *player,
gboolean from_eos,
gboolean allow_stop,
@@ -956,6 +960,31 @@ rb_shell_player_handle_eos (RBPlayer *player,
GDK_THREADS_LEAVE ();
}
+
+static void
+rb_shell_player_handle_redirect (RBPlayer *player,
+ RhythmDBEntry *entry,
+ const gchar *uri,
+ RBShellPlayer *shell_player)
+{
+ GValue val = { 0 };
+
+ rb_debug ("redirect to %s", uri);
+
+ /* Stop existing stream */
+ rb_player_close (shell_player->priv->mmplayer, NULL, NULL);
+
+ /* Update entry */
+ g_value_init (&val, G_TYPE_STRING);
+ g_value_set_string (&val, uri);
+ rhythmdb_entry_set (shell_player->priv->db, entry, RHYTHMDB_PROP_LOCATION, &val);
+ g_value_unset (&val);
+ rhythmdb_commit (shell_player->priv->db);
+
+ /* Play new URI */
+ rb_shell_player_open_location (shell_player, entry, RB_PLAYER_PLAY_REPLACE, NULL);
+}
+
static void
rb_shell_player_init (RBShellPlayer *player)
{
@@ -1004,6 +1033,11 @@ rb_shell_player_init (RBShellPlayer *player)
player, 0);
g_signal_connect_object (player->priv->mmplayer,
+ "redirect",
+ G_CALLBACK (rb_shell_player_handle_redirect),
+ player, 0);
+
+ g_signal_connect_object (player->priv->mmplayer,
"tick",
G_CALLBACK (tick_cb),
player, 0);
@@ -1565,7 +1599,6 @@ rb_shell_player_open_location (RBShellPlayer *player,
GError **error)
{
char *location;
- gboolean was_playing;
gboolean ret = TRUE;
/* dispose of any existing playlist urls */
@@ -1585,8 +1618,6 @@ rb_shell_player_open_location (RBShellPlayer *player,
return FALSE;
}
- was_playing = rb_player_playing (player->priv->mmplayer);
-
if (rb_source_try_playlist (player->priv->source)) {
OpenLocationThreadData *data;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]