From 6a70746e903ce9d50df8a5ddabf97a2950d4788e Mon Sep 17 00:00:00 2001 From: waker Date: Fri, 3 Dec 2010 20:48:21 +0100 Subject: added new playlist plugin API added new M3U plugin (also supports loading PLS playlists) --- configure.ac | 10 +++++++++- deadbeef.h | 13 +++++++++++++ playlist.c | 20 ++++++++++++++++++++ plugins.c | 17 +++++++++++++++++ plugins.h | 3 +++ plugins/gtkui/gtkui.c | 31 ++++++++++++++++++++++++++++++- scripts/quickinstall.sh | 2 +- 7 files changed, 93 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 2804183a..2a3c5c62 100644 --- a/configure.ac +++ b/configure.ac @@ -108,6 +108,7 @@ AC_ARG_ENABLE(ao, [AS_HELP_STRING([--disable-ao ], [disable audio ove AC_ARG_ENABLE(staticlink, [AS_HELP_STRING([--enable-staticlink], [link everything statically (default: disabled)])], [enable_staticlink=$enableval], [enable_staticlink=no]) AC_ARG_ENABLE(portable, [AS_HELP_STRING([--enable-portable ], [make portable build (default: disabled, opts: yes,no,full)])], [enable_portable=$enableval], [enable_portable=no]) AC_ARG_ENABLE(src, [AS_HELP_STRING([--enable-src ], [build libsamplerate (SRC) plugin (default: auto)])], [enable_src=$enableval], [enable_src=yes]) +AC_ARG_ENABLE(m3u, [AS_HELP_STRING([--enable-m3u ], [build m3u plugin (default: auto)])], [enable_m3u=$enableval], [enable_m3u=yes]) if test "x$enable_staticlink" != "xno" ; then AC_DEFINE_UNQUOTED([STATICLINK], [1], [Define if building static version]) @@ -498,7 +499,11 @@ if test "x$enable_ao" != "xno" ; then fi fi -PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec plugins/dsp_libsrc" +if test "x$enable_m3u" != "xno" ; then + HAVE_M3U=yes +fi + +PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec plugins/dsp_libsrc plugins/m3u" AM_CONDITIONAL(HAVE_VORBIS, test "x$HAVE_VORBISPLUGIN" = "xyes") AM_CONDITIONAL(HAVE_FLAC, test "x$HAVE_FLACPLUGIN" = "xyes") @@ -537,6 +542,7 @@ AM_CONDITIONAL(STATICLINK, test "x$STATICLINK" = "xyes") AM_CONDITIONAL(PORTABLE, test "x$PORTABLE" = "xyes") AM_CONDITIONAL(PORTABLE_FULL, test "x$PORTABLE_FULL" = "xyes") AM_CONDITIONAL(HAVE_DSP_SRC, test "x$HAVE_DSP_SRC" = "xyes") +AM_CONDITIONAL(HAVE_M3U, test "x$HAVE_M3U" = "xyes") AC_SUBST(PLUGINS_DIRS) @@ -598,6 +604,7 @@ PRINT_PLUGIN_INFO([mms],[mms streaming support],[test "x$HAVE_MMS" = "xyes"]) PRINT_PLUGIN_INFO([shn],[shorten player based on xmms-shn],[test "x$HAVE_SHN" = "xyes"]) PRINT_PLUGIN_INFO([ao],[psf1/psf2/spu/ssf player using Audio Overload],[test "x$HAVE_AO" = "xyes"]) PRINT_PLUGIN_INFO([dsp_src],[High quality samplerate conversion using libsamplerate],[test "x$HAVE_DSP_SRC" = "xyes"]) +PRINT_PLUGIN_INFO([m3u],[M3U and PLS playlist support],[test "x$HAVE_M3U" = "xyes"]) echo @@ -639,6 +646,7 @@ plugins/mms/Makefile plugins/shn/Makefile plugins/ao/Makefile plugins/dsp_libsrc/Makefile +plugins/m3u/Makefile intl/Makefile po/Makefile.in deadbeef.desktop diff --git a/deadbeef.h b/deadbeef.h index d65a0dd9..7108fbcb 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -168,6 +168,7 @@ enum { DB_PLUGIN_DSP = 3, DB_PLUGIN_MISC = 4, DB_PLUGIN_VFS = 5, + DB_PLUGIN_PLAYLIST = 6, }; // output plugin states @@ -520,6 +521,7 @@ typedef struct { struct DB_decoder_s **(*plug_get_decoder_list) (void); struct DB_output_s **(*plug_get_output_list) (void); struct DB_dsp_s **(*plug_get_dsp_list) (void); + struct DB_playlist_s **(*plug_get_playlist_list) (void); struct DB_plugin_s **(*plug_get_list) (void); int (*plug_activate) (struct DB_plugin_s *p, int activate); const char * (*plug_get_decoder_id) (const char *id); @@ -815,6 +817,17 @@ typedef struct DB_gui_s { DB_plugin_t plugin; } DB_gui_t; +// playlist plugin +typedef struct DB_playlist_s { + DB_plugin_t plugin; + + DB_playItem_t * (*load) (DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data); + + DB_playItem_t * (*save) (DB_playItem_t *first, DB_playItem_t *last, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data); + + const char **extensions; // NULL-terminated list of supported file extensions, e.g. {"m3u", "pls", NULL} +} DB_playlist_t; + #ifdef __cplusplus } #endif diff --git a/playlist.c b/playlist.c index 23c55650..cf8d259a 100644 --- a/playlist.c +++ b/playlist.c @@ -2090,6 +2090,26 @@ pl_load (const char *fname) { } GLOBAL_LOCK; pl_clear (); + + // try plugins 1st + const char *ext = strrchr (fname, '.'); + if (ext) { + ext++; + DB_playlist_t **plug = plug_get_playlist_list (); + int p, e; + for (p = 0; plug[p]; p++) { + for (e = 0; plug[p]->extensions[e]; e++) { + if (plug[p]->load && !strcasecmp (ext, plug[p]->extensions[e])) { + DB_playItem_t *it = plug[p]->load (it, fname, NULL, NULL, NULL); + if (it) { + GLOBAL_UNLOCK; + return 0; + } + } + } + } + } + uint8_t majorver; uint8_t minorver; playItem_t *it = NULL; diff --git a/plugins.c b/plugins.c index 537230c0..bc26713e 100644 --- a/plugins.c +++ b/plugins.c @@ -256,6 +256,7 @@ static DB_functions_t deadbeef_api = { .plug_get_decoder_list = plug_get_decoder_list, .plug_get_output_list = plug_get_output_list, .plug_get_dsp_list = plug_get_dsp_list, + .plug_get_playlist_list = plug_get_playlist_list, .plug_get_list = plug_get_list, .plug_activate = plug_activate, .plug_get_decoder_id = plug_get_decoder_id, @@ -323,6 +324,9 @@ DB_dsp_t *g_dsp_plugins[MAX_DSP_PLUGINS+1]; DB_output_t *g_output_plugins[MAX_OUTPUT_PLUGINS+1]; DB_output_t *output_plugin = NULL; +#define MAX_PLAYLIST_PLUGINS 10 +DB_playlist_t *g_playlist_plugins[MAX_PLAYLIST_PLUGINS+1]; + void plug_md5 (uint8_t sig[16], const char *in, int len) { md5_state_t st; @@ -739,6 +743,7 @@ plug_load_all (void) { int numvfs = 0; int numoutput = 0; int numdsp = 0; + int numplaylist = 0; for (plug = plugins; plug; plug = plug->next) { g_plugins[numplugins++] = plug->plugin; if (plug->plugin->type == DB_PLUGIN_DECODER) { @@ -769,6 +774,12 @@ plug_load_all (void) { } g_dsp_plugins[numdsp++] = (DB_dsp_t *)plug->plugin; } + else if (plug->plugin->type == DB_PLUGIN_PLAYLIST) { + if (numplaylist >= MAX_PLAYLIST_PLUGINS) { + break; + } + g_playlist_plugins[numplaylist++] = (DB_playlist_t *)plug->plugin; + } } // start plugins for (plug = plugins; plug; plug = plug->next) { @@ -783,6 +794,7 @@ plug_load_all (void) { g_decoder_plugins[numdecoders] = NULL; g_vfs_plugins[numvfs] = NULL; g_output_plugins[numoutput] = NULL; + g_playlist_plugins[numplaylist] = NULL; // select output plugin if (plug_select_output () < 0) { @@ -860,6 +872,11 @@ plug_get_dsp_list (void) { return g_dsp_plugins; } +struct DB_playlist_s ** +plug_get_playlist_list (void) { + return g_playlist_plugins; +} + struct DB_plugin_s ** plug_get_list (void) { return g_plugins; diff --git a/plugins.h b/plugins.h index 325d8a1f..431a75a7 100644 --- a/plugins.h +++ b/plugins.h @@ -108,6 +108,9 @@ plug_get_vfs_list (void); struct DB_dsp_s ** plug_get_dsp_list (void); +struct DB_playlist_s ** +plug_get_playlist_list (void); + void plug_volume_set_db (float db); diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index e6a31da0..3bdab517 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -723,6 +723,29 @@ on_playlist_save_as_activate (GtkMenuItem *menuitem, save_playlist_as (); } +static gboolean +playlist_filter_func (const GtkFileFilterInfo *filter_info, gpointer data) { + // get ext + const char *p = strrchr (filter_info->filename, '.'); + if (!p) { + return FALSE; + } + p++; + DB_playlist_t **plug = deadbeef->plug_get_playlist_list (); + for (int i = 0; plug[i]; i++) { + if (plug[i]->extensions && plug[i]->load) { + const char **exts = plug[i]->extensions; + if (exts) { + for (int e = 0; exts[e]; e++) { + if (!strcasecmp (exts[e], p)) { + return TRUE; + } + } + } + } + } + return FALSE; +} void on_playlist_load_activate (GtkMenuItem *menuitem, @@ -735,9 +758,15 @@ on_playlist_load_activate (GtkMenuItem *menuitem, GtkFileFilter* flt; flt = gtk_file_filter_new (); - gtk_file_filter_set_name (flt, _("DeaDBeeF playlist files (*.dbpl)")); + gtk_file_filter_set_name (flt, "Supported playlist formats"); + gtk_file_filter_add_custom (flt, GTK_FILE_FILTER_FILENAME, playlist_filter_func, NULL, NULL); gtk_file_filter_add_pattern (flt, "*.dbpl"); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt); + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dlg), flt); + flt = gtk_file_filter_new (); + gtk_file_filter_set_name (flt, _("Other files (*)")); + gtk_file_filter_add_pattern (flt, "*"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt); int res = gtk_dialog_run (GTK_DIALOG (dlg)); // store folder diff --git a/scripts/quickinstall.sh b/scripts/quickinstall.sh index 3806e3db..7b6ff655 100755 --- a/scripts/quickinstall.sh +++ b/scripts/quickinstall.sh @@ -35,4 +35,4 @@ cp ./plugins/shn/.libs/shn.so /usr/local/lib/deadbeef/ cp ./plugins/ao/.libs/ao.so /usr/local/lib/deadbeef/ cp ./plugins/shellexec/.libs/shellexec.so /usr/local/lib/deadbeef/ cp ./plugins/dsp_libsrc/.libs/dsp_libsrc.so /usr/local/lib/deadbeef/ - +cp ./plugins/m3u/.libs/m3u.so /usr/local/lib/deadbeef/ -- cgit v1.2.3