[totem] Add authentication support for RTSP streams
- From: Bastien Nocera <hadess src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [totem] Add authentication support for RTSP streams
- Date: Thu, 12 Nov 2009 18:40:41 +0000 (UTC)
commit 7ece79aa5aec0977778e28b39bc1c9e225158ed4
Author: Bastien Nocera <hadess hadess net>
Date: Thu Nov 12 17:58:37 2009 +0000
Add authentication support for RTSP streams
Using GtkMountOperation to request a username and password
from the user.
src/backend/bacon-video-widget-gst-0.10.c | 106 ++++++++++++++++++++++++++++-
1 files changed, 105 insertions(+), 1 deletions(-)
---
diff --git a/src/backend/bacon-video-widget-gst-0.10.c b/src/backend/bacon-video-widget-gst-0.10.c
index 94adf0d..6110d32 100644
--- a/src/backend/bacon-video-widget-gst-0.10.c
+++ b/src/backend/bacon-video-widget-gst-0.10.c
@@ -252,6 +252,10 @@ struct BaconVideoWidgetPrivate
GCancellable *mount_cancellable;
gboolean mount_in_progress;
+ /* for auth */
+ GMountOperation *auth_dialog;
+ GMountOperationResult auth_last_result;
+
/* Bacon resize */
BaconResize *bacon_resize;
};
@@ -1264,6 +1268,8 @@ bacon_video_widget_init (BaconVideoWidget * bvw)
bvw->priv->mount_cancellable = NULL;
bvw->priv->mount_in_progress = FALSE;
+ bvw->priv->auth_last_result = G_MOUNT_OPERATION_HANDLED;
+ bvw->priv->auth_dialog = NULL;
bacon_video_widget_gst_missing_plugins_blacklist ();
}
@@ -1620,6 +1626,100 @@ bvw_emit_missing_plugins_signal (BaconVideoWidget * bvw, gboolean prerolled)
return handled;
}
+static void
+bvw_auth_reply_cb (GMountOperation *op,
+ GMountOperationResult result,
+ BaconVideoWidget *bvw)
+{
+ GST_DEBUG ("Got authentication reply %d", result);
+ bvw->priv->auth_last_result = result;
+
+ if (result == G_MOUNT_OPERATION_HANDLED) {
+ const char *username, *password;
+ char *new_mrl;
+
+ username = g_mount_operation_get_username (op);
+ password = g_mount_operation_get_password (op);
+
+ /* Crappy! */
+ new_mrl = g_strdup_printf ("rtsp://%s:%s %s",
+ username, password, bvw->priv->mrl + strlen ("rtsp://"));
+ g_object_set (bvw->priv->play, "uri", new_mrl, NULL);
+ GST_DEBUG ("Set new MRL for RTSP source '%s'!", new_mrl);
+ g_free (new_mrl);
+ }
+
+ g_object_unref (bvw->priv->auth_dialog);
+ bvw->priv->auth_dialog = NULL;
+
+ if (bvw->priv->target_state == GST_STATE_PLAYING) {
+ GST_DEBUG ("Starting deferred playback after authentication");
+ bacon_video_widget_play (bvw, NULL);
+ }
+}
+
+/* returns TRUE if the error should be ignored */
+static gboolean
+bvw_check_missing_auth (BaconVideoWidget * bvw, GstMessage * err_msg)
+{
+ gboolean retval;
+
+ retval = FALSE;
+
+ if (bvw->priv->use_type != BVW_USE_TYPE_VIDEO ||
+ GTK_WIDGET_REALIZED (bvw) == FALSE)
+ return retval;
+
+ /* The user already tried, and we aborted */
+ if (bvw->priv->auth_last_result == G_MOUNT_OPERATION_ABORTED) {
+ GST_DEBUG ("Not authenticating, the user aborted the last auth attempt");
+ return retval;
+ }
+ /* There's already an auth on-going, ignore */
+ if (bvw->priv->auth_dialog != NULL) {
+ GST_DEBUG ("Ignoring error, we're doing authentication");
+ return TRUE;
+ }
+
+ /* RTSP source and auth problem? */
+ if (g_strcmp0 ("GstRTSPSrc", G_OBJECT_TYPE_NAME (err_msg->src)) == 0) {
+ GError *err = NULL;
+ gchar *dbg = NULL;
+
+ gst_message_parse_error (err_msg, &err, &dbg);
+
+ if (err != NULL && dbg != NULL &&
+ is_error (err, RESOURCE, READ) &&
+ strstr (dbg, "401") != NULL) {
+ GtkWidget *toplevel;
+ GMountOperationClass *klass;
+
+ GST_DEBUG ("Trying to get auth for location '%s'", GST_STR_NULL (bvw->priv->mrl));
+
+ if (bvw->priv->auth_dialog == NULL) {
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (bvw));
+ bvw->priv->auth_dialog = gtk_mount_operation_new (GTK_WINDOW (toplevel));
+ g_signal_connect (G_OBJECT (bvw->priv->auth_dialog), "reply",
+ G_CALLBACK (bvw_auth_reply_cb), bvw);
+ }
+
+ /* And popup the dialogue! */
+ klass = (GMountOperationClass *) G_OBJECT_GET_CLASS (bvw->priv->auth_dialog);
+ klass->ask_password (bvw->priv->auth_dialog,
+ _("Password requested for RTSP server"),
+ g_get_user_name (),
+ NULL,
+ G_ASK_PASSWORD_NEED_PASSWORD | G_ASK_PASSWORD_NEED_USERNAME);
+ retval = TRUE;
+ }
+ if (err != NULL)
+ g_error_free (err);
+ g_free (dbg);
+ }
+
+ return retval;
+}
+
/* returns TRUE if the error has been handled and should be ignored */
static gboolean
bvw_check_missing_plugins_error (BaconVideoWidget * bvw, GstMessage * err_msg)
@@ -1906,7 +2006,8 @@ bvw_bus_message_cb (GstBus * bus, GstMessage * message, gpointer data)
case GST_MESSAGE_ERROR: {
bvw_error_msg (bvw, message);
- if (!bvw_check_missing_plugins_error (bvw, message)) {
+ if (!bvw_check_missing_plugins_error (bvw, message) &&
+ !bvw_check_missing_auth (bvw, message)) {
GError *error;
error = bvw_error_from_gst_error (bvw, message);
@@ -3576,6 +3677,9 @@ bacon_video_widget_play (BaconVideoWidget * bvw, GError ** error)
} else if (bvw->priv->mount_in_progress) {
GST_DEBUG ("Mounting in progress, not playing");
return TRUE;
+ } else if (bvw->priv->auth_dialog != NULL) {
+ GST_DEBUG ("Authentication in progress, not playing");
+ return TRUE;
}
GST_DEBUG ("play");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]