# HG changeset patch # User nenolod # Date 1155267558 25200 # Node ID 3a60eafe91c7db76a73c31907e43a94f48e06159 # Parent c4640c88942d8430cc7bf5657ba5b005dbb67716 [svn] - m3u and pls plugin implementation diff -r c4640c88942d -r 3a60eafe91c7 ChangeLog --- a/ChangeLog Thu Aug 10 20:35:10 2006 -0700 +++ b/ChangeLog Thu Aug 10 20:39:18 2006 -0700 @@ -1,3 +1,13 @@ +2006-08-11 03:35:10 +0000 William Pitcock + revision [2040] + - lowlevel plugin stuff + + + Changes: Modified: + +20 -0 trunk/audacious/plugin.h + +27 -0 trunk/audacious/pluginenum.c + + 2006-08-11 03:20:39 +0000 William Pitcock revision [2038] - further progress diff -r c4640c88942d -r 3a60eafe91c7 Plugins/Container/m3u/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Container/m3u/Makefile Thu Aug 10 20:39:18 2006 -0700 @@ -0,0 +1,16 @@ +include ../../../mk/rules.mk +include ../../../mk/objective.mk + +OBJECTIVE_LIBS = libm3u.so + +LIBDIR = $(plugindir)/$(CONTAINER_PLUGIN_DIR) + +SOURCES = m3u.c + +OBJECTS = ${SOURCES:.c=.o} + +CFLAGS += -fPIC -DPIC $(GTK_CFLAGS) $(ARCH_DEFINES) -I../../../intl -I../../.. + +CXXFLAGS = $(CFLAGS) + +LIBADD = $(GTK_LIBS) diff -r c4640c88942d -r 3a60eafe91c7 Plugins/Container/m3u/m3u.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Container/m3u/m3u.c Thu Aug 10 20:39:18 2006 -0700 @@ -0,0 +1,212 @@ +/* + * Audacious: A cross-platform multimedia player + * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill, + * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "audacious/main.h" +#include "audacious/util.h" +#include "audacious/playlist.h" +#include "audacious/playlist_container.h" +#include "audacious/plugin.h" + +static void +parse_extm3u_info(const gchar * info, gchar ** title, gint * length) +{ + gchar *str; + + g_return_if_fail(info != NULL); + g_return_if_fail(title != NULL); + g_return_if_fail(length != NULL); + + *title = NULL; + *length = -1; + + if (!str_has_prefix_nocase(info, "#EXTINF:")) { + g_message("Invalid m3u metadata (%s)", info); + return; + } + + info += 8; + + *length = atoi(info); + if (*length <= 0) + *length = -1; + else + *length *= 1000; + + if ((str = strchr(info, ','))) { + *title = g_strstrip(g_strdup(str + 1)); + if (strlen(*title) < 1) { + g_free(*title); + *title = NULL; + } + } +} + +static void +playlist_load_m3u(const gchar * filename, gint pos) +{ + FILE *file; + gchar *line; + gchar *ext_info = NULL, *ext_title = NULL; + gsize line_len = 1024; + gint ext_len = -1; + gboolean is_extm3u = FALSE; + + if (!(file = fopen(filename, "r"))) + return; + + line = g_malloc(line_len); + while (fgets(line, line_len, file)) { + while (strlen(line) == line_len - 1 && line[strlen(line) - 1] != '\n') { + line_len += 1024; + line = g_realloc(line, line_len); + fgets(&line[strlen(line)], 1024, file); + } + + while (line[strlen(line) - 1] == '\r' || + line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + + if (str_has_prefix_nocase(line, "#EXTM3U")) { + is_extm3u = TRUE; + continue; + } + + if (is_extm3u && str_has_prefix_nocase(line, "#EXTINF:")) { + str_replace_in(&ext_info, g_strdup(line)); + continue; + } + + if (line[0] == '#' || strlen(line) == 0) { + if (ext_info) { + g_free(ext_info); + ext_info = NULL; + } + continue; + } + + if (is_extm3u) { + if (cfg.use_pl_metadata && ext_info) + parse_extm3u_info(ext_info, &ext_title, &ext_len); + g_free(ext_info); + ext_info = NULL; + } + + playlist_load_ins_file(line, filename, pos, ext_title, ext_len); + + str_replace_in(&ext_title, NULL); + ext_len = -1; + + if (pos >= 0) + pos++; + } + + fclose(file); + g_free(line); +} + +static void +playlist_save_m3u(const gchar *filename, gint pos) +{ + GList *node; + gchar *outstr = NULL; + FILE *file; + + g_return_if_fail(filename != NULL); + + file = fopen(filename, "wb"); + + g_return_if_fail(file != NULL); + + if (cfg.use_pl_metadata) + g_fprintf(file, "#EXTM3U\n"); + + PLAYLIST_LOCK(); + + for (node = playlist_get(); node; node = g_list_next(node)) { + PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); + + if (entry->title && cfg.use_pl_metadata) { + gint seconds; + + if (entry->length > 0) + seconds = (entry->length) / 1000; + else + seconds = -1; + + outstr = g_locale_from_utf8(entry->title, -1, NULL, NULL, NULL); + if(outstr) { + g_fprintf(file, "#EXTINF:%d,%s\n", seconds, outstr); + g_free(outstr); + outstr = NULL; + } else { + g_fprintf(file, "#EXTINF:%d,%s\n", seconds, entry->title); + } + } + + g_fprintf(file, "%s\n", entry->filename); + } + + PLAYLIST_UNLOCK(); + + fclose(file); +} + +PlaylistContainer plc_m3u = { + .name = "M3U Playlist Format", + .ext = "m3u", + .plc_read = playlist_load_m3u, + .plc_write = playlist_save_m3u, +}; + +static void init(void) +{ + playlist_container_register(&plc_m3u); +} + +static void cleanup(void) +{ + playlist_container_unregister(&plc_m3u); +} + +LowlevelPlugin llp_m3u = { + NULL, + NULL, + "M3U Playlist Format", + init, + cleanup, +}; + +LowlevelPlugin *get_lplugin_info(void) +{ + return &llp_m3u; +} diff -r c4640c88942d -r 3a60eafe91c7 Plugins/Container/pls/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Container/pls/Makefile Thu Aug 10 20:39:18 2006 -0700 @@ -0,0 +1,16 @@ +include ../../../mk/rules.mk +include ../../../mk/objective.mk + +OBJECTIVE_LIBS = libpls.so + +LIBDIR = $(plugindir)/$(CONTAINER_PLUGIN_DIR) + +SOURCES = pls.c + +OBJECTS = ${SOURCES:.c=.o} + +CFLAGS += -fPIC -DPIC $(GTK_CFLAGS) $(ARCH_DEFINES) -I../../../intl -I../../.. + +CXXFLAGS = $(CFLAGS) + +LIBADD = $(GTK_LIBS) diff -r c4640c88942d -r 3a60eafe91c7 Plugins/Container/pls/pls.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Container/pls/pls.c Thu Aug 10 20:39:18 2006 -0700 @@ -0,0 +1,125 @@ +/* + * Audacious: A cross-platform multimedia player + * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill, + * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "audacious/main.h" +#include "audacious/util.h" +#include "audacious/playlist.h" +#include "audacious/playlist_container.h" +#include "audacious/plugin.h" + +static void +playlist_load_pls(const gchar * filename, gint pos) +{ + guint i, count, added_count = 0; + gchar key[10]; + gchar *line; + + g_return_if_fail(filename != NULL); + + if (!str_has_suffix_nocase(filename, ".pls")) + return; + + if (!(line = read_ini_string(filename, "playlist", "NumberOfEntries"))) + return; + + count = atoi(line); + g_free(line); + + for (i = 1; i <= count; i++) { + g_snprintf(key, sizeof(key), "File%d", i); + if ((line = read_ini_string(filename, "playlist", key))) { + playlist_load_ins_file(line, filename, pos, NULL, -1); + added_count++; + + if (pos >= 0) + pos++; + + g_free(line); + } + } +} + +static void +playlist_save_pls(const gchar *filename, gint pos) +{ + GList *node; + FILE *file = fopen(filename, "wb"); + + g_return_if_fail(file != NULL); + + g_fprintf(file, "[playlist]\n"); + g_fprintf(file, "NumberOfEntries=%d\n", playlist_get_length()); + + PLAYLIST_LOCK(); + + for (node = playlist_get(); node; node = g_list_next(node)) { + PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); + + g_fprintf(file, "File%d=%s\n", g_list_position(playlist_get(), node) + 1, + entry->filename); + } + + PLAYLIST_UNLOCK(); + + fclose(file); +} + +PlaylistContainer plc_pls = { + .name = "Winamp .pls Playlist Format", + .ext = "pls", + .plc_read = playlist_load_pls, + .plc_write = playlist_save_pls, +}; + +static void init(void) +{ + playlist_container_register(&plc_pls); +} + +static void cleanup(void) +{ + playlist_container_unregister(&plc_pls); +} + +LowlevelPlugin llp_pls = { + NULL, + NULL, + "Winamp .pls Playlist Format", + init, + cleanup, +}; + +LowlevelPlugin *get_lplugin_info(void) +{ + return &llp_pls; +}