clapper: Add "Playlistable" interface

An interface for creating enhancers that parse data
into individual media items
This commit is contained in:
Rafał Dzięgiel
2025-06-27 19:04:40 +02:00
parent ff054743e6
commit 4002a63e3a
9 changed files with 180 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
project('clapper', 'c', project('clapper', 'c',
version: '0.9.0', version: '0.9.1',
meson_version: '>= 0.64.0', 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 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: [ default_options: [

View File

@@ -18,7 +18,9 @@
#include "clapper-cache-private.h" #include "clapper-cache-private.h"
#include "clapper-version.h" #include "clapper-version.h"
#include "clapper-extractable.h" #include "clapper-extractable.h"
#include "clapper-playlistable.h"
#include "clapper-reactable.h" #include "clapper-reactable.h"
#define CLAPPER_CACHE_HEADER "CLAPPER" #define CLAPPER_CACHE_HEADER "CLAPPER"
@@ -26,6 +28,7 @@
typedef enum typedef enum
{ {
CLAPPER_CACHE_IFACE_EXTRACTABLE = 1, CLAPPER_CACHE_IFACE_EXTRACTABLE = 1,
CLAPPER_CACHE_IFACE_PLAYLISTABLE,
CLAPPER_CACHE_IFACE_REACTABLE, CLAPPER_CACHE_IFACE_REACTABLE,
} ClapperCacheIfaces; } ClapperCacheIfaces;
@@ -244,6 +247,8 @@ clapper_cache_read_iface (const gchar **data)
switch (iface_id) { switch (iface_id) {
case CLAPPER_CACHE_IFACE_EXTRACTABLE: case CLAPPER_CACHE_IFACE_EXTRACTABLE:
return CLAPPER_TYPE_EXTRACTABLE; return CLAPPER_TYPE_EXTRACTABLE;
case CLAPPER_CACHE_IFACE_PLAYLISTABLE:
return CLAPPER_TYPE_PLAYLISTABLE;
case CLAPPER_CACHE_IFACE_REACTABLE: case CLAPPER_CACHE_IFACE_REACTABLE:
return CLAPPER_TYPE_REACTABLE; return CLAPPER_TYPE_REACTABLE;
default: default:
@@ -436,6 +441,8 @@ clapper_cache_store_iface (GByteArray *bytes, GType iface)
if (iface == CLAPPER_TYPE_EXTRACTABLE) if (iface == CLAPPER_TYPE_EXTRACTABLE)
iface_id = CLAPPER_CACHE_IFACE_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) else if (iface == CLAPPER_TYPE_REACTABLE)
iface_id = CLAPPER_CACHE_IFACE_REACTABLE; iface_id = CLAPPER_CACHE_IFACE_REACTABLE;
else else

View File

@@ -46,12 +46,14 @@
#include "clapper-enhancer-proxy-list.h" #include "clapper-enhancer-proxy-list.h"
#include "clapper-basic-functions.h" #include "clapper-basic-functions.h"
#include "clapper-cache-private.h" #include "clapper-cache-private.h"
#include "clapper-extractable.h"
#include "clapper-reactable.h"
#include "clapper-player-private.h" #include "clapper-player-private.h"
#include "clapper-utils-private.h" #include "clapper-utils-private.h"
#include "clapper-enums.h" #include "clapper-enums.h"
#include "clapper-extractable.h"
#include "clapper-playlistable.h"
#include "clapper-reactable.h"
#include "clapper-functionalities-availability.h" #include "clapper-functionalities-availability.h"
#if CLAPPER_WITH_ENHANCERS_LOADER #if CLAPPER_WITH_ENHANCERS_LOADER
@@ -464,7 +466,7 @@ gboolean
clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *enhancer) clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *enhancer)
{ {
/* NOTE: REACTABLE must be last for "allowed" to work as expected */ /* 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; GType *ifaces;
GParamSpec **pspecs; GParamSpec **pspecs;
GParamFlags enhancer_flags; GParamFlags enhancer_flags;
@@ -1299,7 +1301,7 @@ clapper_enhancer_proxy_class_init (ClapperEnhancerProxyClass *klass)
* *
* This effectively means whether the given enhancer can be used. * 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. * are allowed while enhancers implementing [iface@Clapper.Reactable] are not.
* *
* Value of this property from a `GLOBAL` [class@Clapper.EnhancerProxyList] will carry * Value of this property from a `GLOBAL` [class@Clapper.EnhancerProxyList] will carry

View File

@@ -32,6 +32,7 @@ static HMODULE _enhancers_dll_handle = NULL;
// Supported interfaces // Supported interfaces
#include "clapper-extractable.h" #include "clapper-extractable.h"
#include "clapper-playlistable.h"
#include "clapper-reactable.h" #include "clapper-reactable.h"
#define GST_CAT_DEFAULT clapper_enhancers_loader_debug #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). */ * Otherwise make an instance and fill missing data from it (slow). */
if (!(filled = clapper_enhancer_proxy_fill_from_cache (proxy))) { if (!(filled = clapper_enhancer_proxy_fill_from_cache (proxy))) {
GObject *enhancer; 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; guint j;
/* We cannot ask libpeas for "any" of our main interfaces, so try each one until found */ /* We cannot ask libpeas for "any" of our main interfaces, so try each one until found */

View File

@@ -0,0 +1,31 @@
/* Clapper Playback Library
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
*
* 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
* <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <glib.h>
#include <gio/gio.h>
#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

View File

@@ -0,0 +1,59 @@
/* Clapper Playback Library
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
*
* 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
* <https://www.gnu.org/licenses/>.
*/
/**
* ClapperPlaylistable:
*
* An interface for creating enhancers that parse data into individual media items.
*
* Since: 0.10
*/
#include <gst/gst.h>
#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);
}

View File

@@ -0,0 +1,71 @@
/* Clapper Playback Library
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
*
* 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
* <https://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION)
#error "Only <clapper/clapper.h> can be included directly."
#endif
#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
#include <clapper/clapper-visibility.h>
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

View File

@@ -44,6 +44,7 @@
#include <clapper/clapper-video-stream.h> #include <clapper/clapper-video-stream.h>
#include <clapper/clapper-extractable.h> #include <clapper/clapper-extractable.h>
#include <clapper/clapper-playlistable.h>
#include <clapper/clapper-reactable.h> #include <clapper/clapper-reactable.h>
#include <clapper/clapper-functionalities-availability.h> #include <clapper/clapper-functionalities-availability.h>

View File

@@ -119,6 +119,7 @@ clapper_headers = [
'clapper-marker.h', 'clapper-marker.h',
'clapper-media-item.h', 'clapper-media-item.h',
'clapper-player.h', 'clapper-player.h',
'clapper-playlistable.h',
'clapper-queue.h', 'clapper-queue.h',
'clapper-reactable.h', 'clapper-reactable.h',
'clapper-stream.h', 'clapper-stream.h',
@@ -147,6 +148,7 @@ clapper_sources = [
'clapper-media-item.c', 'clapper-media-item.c',
'clapper-playbin-bus.c', 'clapper-playbin-bus.c',
'clapper-player.c', 'clapper-player.c',
'clapper-playlistable.c',
'clapper-queue.c', 'clapper-queue.c',
'clapper-reactable.c', 'clapper-reactable.c',
'clapper-reactables-manager.c', 'clapper-reactables-manager.c',