From 4002a63e3a3778a80e1685f4464c1dcfac1ea77c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Fri, 27 Jun 2025 19:04:40 +0200 Subject: [PATCH] clapper: Add "Playlistable" interface An interface for creating enhancers that parse data into individual media items --- meson.build | 2 +- src/lib/clapper/clapper-cache.c | 7 ++ src/lib/clapper/clapper-enhancer-proxy.c | 10 +-- src/lib/clapper/clapper-enhancers-loader.c | 3 +- .../clapper/clapper-playlistable-private.h | 31 ++++++++ src/lib/clapper/clapper-playlistable.c | 59 +++++++++++++++ src/lib/clapper/clapper-playlistable.h | 71 +++++++++++++++++++ src/lib/clapper/clapper.h | 1 + src/lib/clapper/meson.build | 2 + 9 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 src/lib/clapper/clapper-playlistable-private.h create mode 100644 src/lib/clapper/clapper-playlistable.c create mode 100644 src/lib/clapper/clapper-playlistable.h diff --git a/meson.build b/meson.build index 5f893f76..dc8fcc9a 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('clapper', 'c', - version: '0.9.0', + version: '0.9.1', meson_version: '>= 0.64.0', license: 'LGPL-2.1-or-later AND GPL-3.0-or-later', # LGPL-2.1+ for libs and gst-plugin, GPL-3.0+ for app default_options: [ diff --git a/src/lib/clapper/clapper-cache.c b/src/lib/clapper/clapper-cache.c index 86d7589c..63cd10b3 100644 --- a/src/lib/clapper/clapper-cache.c +++ b/src/lib/clapper/clapper-cache.c @@ -18,7 +18,9 @@ #include "clapper-cache-private.h" #include "clapper-version.h" + #include "clapper-extractable.h" +#include "clapper-playlistable.h" #include "clapper-reactable.h" #define CLAPPER_CACHE_HEADER "CLAPPER" @@ -26,6 +28,7 @@ typedef enum { CLAPPER_CACHE_IFACE_EXTRACTABLE = 1, + CLAPPER_CACHE_IFACE_PLAYLISTABLE, CLAPPER_CACHE_IFACE_REACTABLE, } ClapperCacheIfaces; @@ -244,6 +247,8 @@ clapper_cache_read_iface (const gchar **data) switch (iface_id) { case CLAPPER_CACHE_IFACE_EXTRACTABLE: return CLAPPER_TYPE_EXTRACTABLE; + case CLAPPER_CACHE_IFACE_PLAYLISTABLE: + return CLAPPER_TYPE_PLAYLISTABLE; case CLAPPER_CACHE_IFACE_REACTABLE: return CLAPPER_TYPE_REACTABLE; default: @@ -436,6 +441,8 @@ clapper_cache_store_iface (GByteArray *bytes, GType iface) if (iface == CLAPPER_TYPE_EXTRACTABLE) iface_id = CLAPPER_CACHE_IFACE_EXTRACTABLE; + else if (iface == CLAPPER_TYPE_PLAYLISTABLE) + iface_id = CLAPPER_CACHE_IFACE_PLAYLISTABLE; else if (iface == CLAPPER_TYPE_REACTABLE) iface_id = CLAPPER_CACHE_IFACE_REACTABLE; else diff --git a/src/lib/clapper/clapper-enhancer-proxy.c b/src/lib/clapper/clapper-enhancer-proxy.c index a7f7c8a2..76cbe4a0 100644 --- a/src/lib/clapper/clapper-enhancer-proxy.c +++ b/src/lib/clapper/clapper-enhancer-proxy.c @@ -46,12 +46,14 @@ #include "clapper-enhancer-proxy-list.h" #include "clapper-basic-functions.h" #include "clapper-cache-private.h" -#include "clapper-extractable.h" -#include "clapper-reactable.h" #include "clapper-player-private.h" #include "clapper-utils-private.h" #include "clapper-enums.h" +#include "clapper-extractable.h" +#include "clapper-playlistable.h" +#include "clapper-reactable.h" + #include "clapper-functionalities-availability.h" #if CLAPPER_WITH_ENHANCERS_LOADER @@ -464,7 +466,7 @@ gboolean clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *enhancer) { /* NOTE: REACTABLE must be last for "allowed" to work as expected */ - const GType enhancer_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_REACTABLE }; + const GType enhancer_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_PLAYLISTABLE, CLAPPER_TYPE_REACTABLE }; GType *ifaces; GParamSpec **pspecs; GParamFlags enhancer_flags; @@ -1299,7 +1301,7 @@ clapper_enhancer_proxy_class_init (ClapperEnhancerProxyClass *klass) * * This effectively means whether the given enhancer can be used. * - * By default all enhancers that work on-demand such as [iface@Clapper.Extractable] + * By default all enhancers that work on-demand ([iface@Clapper.Extractable], [iface@Clapper.Playlistable]) * are allowed while enhancers implementing [iface@Clapper.Reactable] are not. * * Value of this property from a `GLOBAL` [class@Clapper.EnhancerProxyList] will carry diff --git a/src/lib/clapper/clapper-enhancers-loader.c b/src/lib/clapper/clapper-enhancers-loader.c index 1418642a..4b608968 100644 --- a/src/lib/clapper/clapper-enhancers-loader.c +++ b/src/lib/clapper/clapper-enhancers-loader.c @@ -32,6 +32,7 @@ static HMODULE _enhancers_dll_handle = NULL; // Supported interfaces #include "clapper-extractable.h" +#include "clapper-playlistable.h" #include "clapper-reactable.h" #define GST_CAT_DEFAULT clapper_enhancers_loader_debug @@ -140,7 +141,7 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies) * Otherwise make an instance and fill missing data from it (slow). */ if (!(filled = clapper_enhancer_proxy_fill_from_cache (proxy))) { GObject *enhancer; - const GType main_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_REACTABLE }; + const GType main_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_PLAYLISTABLE, CLAPPER_TYPE_REACTABLE }; guint j; /* We cannot ask libpeas for "any" of our main interfaces, so try each one until found */ diff --git a/src/lib/clapper/clapper-playlistable-private.h b/src/lib/clapper/clapper-playlistable-private.h new file mode 100644 index 00000000..1deabf83 --- /dev/null +++ b/src/lib/clapper/clapper-playlistable-private.h @@ -0,0 +1,31 @@ +/* Clapper Playback Library + * Copyright (C) 2025 Rafał Dzięgiel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * . + */ + +#pragma once + +#include +#include + +#include "clapper-playlistable.h" + +G_BEGIN_DECLS + +G_GNUC_INTERNAL +gboolean clapper_playlistable_parse (ClapperPlaylistable *playlistable, GUri *uri, GBytes *bytes, GListStore *playlist, GCancellable *cancellable, GError **error); + +G_END_DECLS diff --git a/src/lib/clapper/clapper-playlistable.c b/src/lib/clapper/clapper-playlistable.c new file mode 100644 index 00000000..2cb1beba --- /dev/null +++ b/src/lib/clapper/clapper-playlistable.c @@ -0,0 +1,59 @@ +/* Clapper Playback Library + * Copyright (C) 2025 Rafał Dzięgiel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * . + */ + +/** + * ClapperPlaylistable: + * + * An interface for creating enhancers that parse data into individual media items. + * + * Since: 0.10 + */ + +#include + +#include "clapper-playlistable-private.h" + +G_DEFINE_INTERFACE (ClapperPlaylistable, clapper_playlistable, G_TYPE_OBJECT); + +static gboolean +clapper_playlistable_default_parse (ClapperPlaylistable *self, GUri *uri, GBytes *bytes, + GListStore *playlist, GCancellable *cancellable, GError **error) +{ + if (*error == NULL) { + g_set_error (error, GST_CORE_ERROR, + GST_CORE_ERROR_NOT_IMPLEMENTED, + "Playlistable object did not implement parse function"); + } + + return FALSE; +} + +static void +clapper_playlistable_default_init (ClapperPlaylistableInterface *iface) +{ + iface->parse = clapper_playlistable_default_parse; +} + +gboolean +clapper_playlistable_parse (ClapperPlaylistable *self, GUri *uri, GBytes *bytes, + GListStore *playlist, GCancellable *cancellable, GError **error) +{ + ClapperPlaylistableInterface *iface = CLAPPER_PLAYLISTABLE_GET_IFACE (self); + + return iface->parse (self, uri, bytes, playlist, cancellable, error); +} diff --git a/src/lib/clapper/clapper-playlistable.h b/src/lib/clapper/clapper-playlistable.h new file mode 100644 index 00000000..444888df --- /dev/null +++ b/src/lib/clapper/clapper-playlistable.h @@ -0,0 +1,71 @@ +/* Clapper Playback Library + * Copyright (C) 2025 Rafał Dzięgiel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * . + */ + +#pragma once + +#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +#include + +G_BEGIN_DECLS + +#define CLAPPER_TYPE_PLAYLISTABLE (clapper_playlistable_get_type()) +#define CLAPPER_PLAYLISTABLE_CAST(obj) ((ClapperPlaylistable *)(obj)) + +CLAPPER_API +G_DECLARE_INTERFACE (ClapperPlaylistable, clapper_playlistable, CLAPPER, PLAYLISTABLE, GObject) + +/** + * ClapperPlaylistableInterface: + * @parent_iface: The parent interface structure. + * @parse: Parse bytes and fill playlist. + */ +struct _ClapperPlaylistableInterface +{ + GTypeInterface parent_iface; + + /** + * ClapperPlaylistableInterface::parse: + * @playlistable: a #ClapperPlaylistable + * @uri: a source #GUri + * @bytes: a #GBytes + * @playlist: a #GListStore for media items + * @cancellable: a #GCancellable object + * @error: a #GError + * + * Parse @bytes and fill @playlist with [class@Clapper.MediaItem] objects. + * + * If implementation returns %FALSE, whole @playlist content will be discarded. + * + * Returns: whether parsing was successful. + * + * Since: 0.10 + */ + gboolean (* parse) (ClapperPlaylistable *playlistable, GUri *uri, GBytes *bytes, GListStore *playlist, GCancellable *cancellable, GError **error); + + /*< private >*/ + gpointer padding[8]; +}; + +G_END_DECLS diff --git a/src/lib/clapper/clapper.h b/src/lib/clapper/clapper.h index 4ef91391..cf176f4b 100644 --- a/src/lib/clapper/clapper.h +++ b/src/lib/clapper/clapper.h @@ -44,6 +44,7 @@ #include #include +#include #include #include diff --git a/src/lib/clapper/meson.build b/src/lib/clapper/meson.build index 655ea4df..1c01467e 100644 --- a/src/lib/clapper/meson.build +++ b/src/lib/clapper/meson.build @@ -119,6 +119,7 @@ clapper_headers = [ 'clapper-marker.h', 'clapper-media-item.h', 'clapper-player.h', + 'clapper-playlistable.h', 'clapper-queue.h', 'clapper-reactable.h', 'clapper-stream.h', @@ -147,6 +148,7 @@ clapper_sources = [ 'clapper-media-item.c', 'clapper-playbin-bus.c', 'clapper-player.c', + 'clapper-playlistable.c', 'clapper-queue.c', 'clapper-reactable.c', 'clapper-reactables-manager.c',