From 50d7ae4b2aa0e40c2e582ba9b9b3b9ceff137bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Sun, 23 Nov 2025 14:23:17 +0100 Subject: [PATCH] clapper: Add readable "redirect-uri" property to media item Allow applications to inspect permanent redirect URIs of media items in a similar manner as done for "cache-location" property --- src/lib/clapper/clapper-enums.h | 4 +- src/lib/clapper/clapper-media-item.c | 120 ++++++++++++++++++--------- src/lib/clapper/clapper-media-item.h | 3 + 3 files changed, 89 insertions(+), 38 deletions(-) diff --git a/src/lib/clapper/clapper-enums.h b/src/lib/clapper/clapper-enums.h index 16236db6..12f12984 100644 --- a/src/lib/clapper/clapper-enums.h +++ b/src/lib/clapper/clapper-enums.h @@ -173,6 +173,7 @@ typedef enum * @CLAPPER_REACTABLE_ITEM_UPDATED_DURATION: Media item duration was updated. * @CLAPPER_REACTABLE_ITEM_UPDATED_TIMELINE: Media item timeline was updated. * @CLAPPER_REACTABLE_ITEM_UPDATED_TAGS: Media item tags were updated. + * @CLAPPER_REACTABLE_ITEM_UPDATED_REDIRECT_URI: Media item redirect URI was updated. * @CLAPPER_REACTABLE_ITEM_UPDATED_CACHE_LOCATION: Media item cache location was updated. * * Flags informing which properties were updated within [class@Clapper.MediaItem]. @@ -185,7 +186,8 @@ typedef enum CLAPPER_REACTABLE_ITEM_UPDATED_DURATION = 1 << 1, CLAPPER_REACTABLE_ITEM_UPDATED_TIMELINE = 1 << 2, CLAPPER_REACTABLE_ITEM_UPDATED_TAGS = 1 << 3, - CLAPPER_REACTABLE_ITEM_UPDATED_CACHE_LOCATION = 1 << 4, + CLAPPER_REACTABLE_ITEM_UPDATED_REDIRECT_URI = 1 << 4, + CLAPPER_REACTABLE_ITEM_UPDATED_CACHE_LOCATION = 1 << 5, } ClapperReactableItemUpdatedFlags; G_END_DECLS diff --git a/src/lib/clapper/clapper-media-item.c b/src/lib/clapper/clapper-media-item.c index c4fc41ea..cc36909c 100644 --- a/src/lib/clapper/clapper-media-item.c +++ b/src/lib/clapper/clapper-media-item.c @@ -75,6 +75,7 @@ enum PROP_ID, PROP_URI, PROP_SUBURI, + PROP_REDIRECT_URI, PROP_CACHE_LOCATION, PROP_TAGS, PROP_TITLE, @@ -203,12 +204,6 @@ clapper_media_item_get_id (ClapperMediaItem *self) return self->id; } -/* FIXME: 1.0: - * Consider change to be transfer-full and just return latest redirect URI - * (alternatively expose redirect URI). This should make it possible to work - * with enhancers that would benefit from knowledge about URI changes - * (e.g "Recall" could read actual media instead of playlist file). - */ /** * clapper_media_item_get_uri: * @item: a #ClapperMediaItem @@ -278,6 +273,30 @@ clapper_media_item_get_suburi (ClapperMediaItem *self) return suburi; } +/** + * clapper_media_item_get_redirect_uri: + * @item: a #ClapperMediaItem + * + * Get permanent redirect URI of #ClapperMediaItem. + * + * Returns: (transfer full) (nullable): a redirected URI of #ClapperMediaItem. + * + * Since: 0.10 + */ +gchar * +clapper_media_item_get_redirect_uri (ClapperMediaItem *self) +{ + gchar *redirect_uri; + + g_return_val_if_fail (CLAPPER_IS_MEDIA_ITEM (self), NULL); + + GST_OBJECT_LOCK (self); + redirect_uri = g_strdup (self->redirect_uri); + GST_OBJECT_UNLOCK (self); + + return redirect_uri; +} + /** * clapper_media_item_get_cache_location: * @item: a #ClapperMediaItem @@ -711,6 +730,7 @@ clapper_media_item_set_redirect_uri (ClapperMediaItem *self, const gchar *redire GstObject *redirect_src) { GType src_type; + gboolean changed; /* Safety checks */ if (G_UNLIKELY (!redirect_uri)) { @@ -734,11 +754,14 @@ clapper_media_item_set_redirect_uri (ClapperMediaItem *self, const gchar *redire return FALSE; } - g_set_str (&self->redirect_uri, redirect_uri); - GST_DEBUG_OBJECT (self, "Set redirect URI: \"%s\", source: %s", - self->redirect_uri, G_OBJECT_TYPE_NAME (redirect_src)); + GST_OBJECT_LOCK (self); + changed = g_set_str (&self->redirect_uri, redirect_uri); + GST_OBJECT_UNLOCK (self); - return TRUE; + GST_DEBUG_OBJECT (self, "Set redirect URI: \"%s\", source: %s", + redirect_uri, G_OBJECT_TYPE_NAME (redirect_src)); + + return changed; } gboolean @@ -747,38 +770,41 @@ clapper_media_item_update_from_parsed_playlist (ClapperMediaItem *self, GListSto { ClapperMediaItem *other_item; const gchar *redirect_uri; - gboolean title_changed = FALSE; + gboolean success, title_changed = FALSE; + /* First playlist item URI becomes a redirect URI for item to be updated */ other_item = g_list_model_get_item (G_LIST_MODEL (playlist), 0); redirect_uri = clapper_media_item_get_uri (other_item); - if (!clapper_media_item_set_redirect_uri (self, redirect_uri, playlist_src)) { - gst_object_unref (other_item); - return FALSE; - } - - GST_OBJECT_LOCK (other_item); - - if (other_item->tags) - clapper_media_item_update_from_tag_list (self, other_item->tags, player); - - /* Since its redirect now, we have to update title to describe new file instead of - * being a playlist title. If other item had parsed title, it also means that tags - * did not contain it, thus we have to manually update it and notify. */ - if (other_item->title_is_parsed) { - GST_OBJECT_LOCK (self); - title_changed = g_set_str (&self->title, other_item->title); - self->title_is_parsed = TRUE; - GST_OBJECT_UNLOCK (self); - } - - GST_OBJECT_UNLOCK (other_item); - - if (title_changed) { - ClapperReactableItemUpdatedFlags flags = CLAPPER_REACTABLE_ITEM_UPDATED_TITLE; + if ((success = clapper_media_item_set_redirect_uri (self, redirect_uri, playlist_src))) { ClapperFeaturesManager *features_manager; + ClapperReactableItemUpdatedFlags flags = CLAPPER_REACTABLE_ITEM_UPDATED_REDIRECT_URI; - clapper_app_bus_post_prop_notify (player->app_bus, GST_OBJECT_CAST (self), param_specs[PROP_TITLE]); + /* Notify about URI change before other properties */ + clapper_app_bus_post_prop_notify (player->app_bus, GST_OBJECT_CAST (self), + param_specs[PROP_REDIRECT_URI]); + + GST_OBJECT_LOCK (other_item); + + if (other_item->tags) + clapper_media_item_update_from_tag_list (self, other_item->tags, player); + + /* Since its redirect now, we have to update title to describe new file instead of + * being a playlist title. If other item had parsed title, it also means that tags + * did not contain it, thus we have to manually update it and notify. */ + if (other_item->title_is_parsed) { + GST_OBJECT_LOCK (self); + title_changed = g_set_str (&self->title, other_item->title); + self->title_is_parsed = TRUE; + GST_OBJECT_UNLOCK (self); + } + + GST_OBJECT_UNLOCK (other_item); + + if (title_changed) { + flags |= CLAPPER_REACTABLE_ITEM_UPDATED_TITLE; + clapper_app_bus_post_prop_notify (player->app_bus, GST_OBJECT_CAST (self), param_specs[PROP_TITLE]); + } if (player->reactables_manager) clapper_reactables_manager_trigger_item_updated (player->reactables_manager, self, flags); @@ -788,7 +814,7 @@ clapper_media_item_update_from_parsed_playlist (ClapperMediaItem *self, GListSto gst_object_unref (other_item); - return TRUE; + return success; } /* XXX: Must be set from player thread or upon construction */ @@ -962,6 +988,9 @@ clapper_media_item_get_property (GObject *object, guint prop_id, case PROP_SUBURI: g_value_take_string (value, clapper_media_item_get_suburi (self)); break; + case PROP_REDIRECT_URI: + g_value_take_string (value, clapper_media_item_get_redirect_uri (self)); + break; case PROP_CACHE_LOCATION: g_value_take_string (value, clapper_media_item_get_cache_location (self)); break; @@ -1026,6 +1055,23 @@ clapper_media_item_class_init (ClapperMediaItemClass *klass) NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + /** + * ClapperMediaItem:redirect-uri: + * + * Media permanent redirect URI. + * + * Changes when player determines a new redirect for given media item. + * This will also happen when item URI leads to a playlist. Once playlist + * is parsed, item is merged with the first item on that playlist and the + * remaining items are appended to the playback queue after that item position. + * + * Once redirect URI in item is present, player will use that URI instead + * of the default one. Cache location takes precedence over both URIs through. + */ + param_specs[PROP_REDIRECT_URI] = g_param_spec_string ("redirect-uri", + NULL, NULL, NULL, + G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + /** * ClapperMediaItem:cache-location: * diff --git a/src/lib/clapper/clapper-media-item.h b/src/lib/clapper/clapper-media-item.h index f2daf488..1c77a807 100644 --- a/src/lib/clapper/clapper-media-item.h +++ b/src/lib/clapper/clapper-media-item.h @@ -60,6 +60,9 @@ void clapper_media_item_set_suburi (ClapperMediaItem *item, const gchar *suburi) CLAPPER_API gchar * clapper_media_item_get_suburi (ClapperMediaItem *item); +CLAPPER_API +gchar * clapper_media_item_get_redirect_uri (ClapperMediaItem *item); + CLAPPER_API gchar * clapper_media_item_get_cache_location (ClapperMediaItem *item);