playlist: added CUE playlist plugin

This plugin is the groundwork for MPD's future generic CUE sheet
support.  That's not complete yet, e.g. there is no way for a playlist
plugin to address an arbitrary position within a music file.
This commit is contained in:
Max Kellermann 2009-12-16 20:04:36 +01:00
parent c128f2dd7e
commit 3679d5bd7a
4 changed files with 177 additions and 0 deletions

View File

@ -160,6 +160,7 @@ mpd_headers = \
src/playlist/xspf_playlist_plugin.h \
src/playlist/asx_playlist_plugin.h \
src/playlist/lastfm_playlist_plugin.h \
src/playlist/cue_playlist_plugin.h \
src/poison.h \
src/riff.h \
src/aiff.h \
@ -707,6 +708,10 @@ if ENABLE_LASTFM
PLAYLIST_SRC += src/playlist/lastfm_playlist_plugin.c
endif
if HAVE_CUE
PLAYLIST_SRC += src/playlist/cue_playlist_plugin.c
endif
#
# Filter plugins
@ -782,9 +787,11 @@ test_run_input_SOURCES = test/run_input.c \
$(INPUT_SRC)
test_dump_playlist_CPPFLAGS = $(AM_CPPFLAGS) \
$(CUE_CFLAGS) \
$(ARCHIVE_CFLAGS) \
$(INPUT_CFLAGS)
test_dump_playlist_LDADD = $(MPD_LIBS) \
$(CUE_LIBS) \
$(ARCHIVE_LIBS) \
$(INPUT_LIBS) \
$(GLIB_LIBS)
@ -798,6 +805,10 @@ test_dump_playlist_SOURCES = test/dump_playlist.c \
$(INPUT_SRC) \
$(PLAYLIST_SRC)
if HAVE_CUE
test_dump_playlist_SOURCES += src/cue/cue_tag.c
endif
test_run_decoder_CPPFLAGS = $(AM_CPPFLAGS) \
$(TAG_CFLAGS) \
$(ARCHIVE_CFLAGS) \

View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* 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 "config.h"
#include "playlist/cue_playlist_plugin.h"
#include "playlist_plugin.h"
#include "tag.h"
#include "song.h"
#include "cue/cue_tag.h"
#include <glib.h>
#include <libcue/libcue.h>
#include <assert.h>
#include <string.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "cue"
struct cue_playlist {
struct playlist_provider base;
struct Cd *cd;
unsigned next;
char *path;
};
static struct playlist_provider *
cue_playlist_open_uri(const char *uri)
{
struct cue_playlist *playlist;
FILE *file;
struct Cd *cd;
file = fopen(uri, "rt");
if (file == NULL)
return NULL;
cd = cue_parse_file(file);
fclose(file);
if (cd == NULL)
return NULL;
playlist = g_new(struct cue_playlist, 1);
playlist_provider_init(&playlist->base, &cue_playlist_plugin);
playlist->cd = cd;
playlist->next = 1;
playlist->path = g_path_get_dirname(uri);
return &playlist->base;
}
static void
cue_playlist_close(struct playlist_provider *_playlist)
{
struct cue_playlist *playlist = (struct cue_playlist *)_playlist;
g_free(playlist->path);
cd_delete(playlist->cd);
g_free(playlist);
}
static struct song *
cue_playlist_read(struct playlist_provider *_playlist)
{
struct cue_playlist *playlist = (struct cue_playlist *)_playlist;
struct Track *track;
struct tag *tag;
const char *filename;
char *uri;
struct song *song;
track = cd_get_track(playlist->cd, playlist->next);
if (track == NULL)
return NULL;
tag = cue_tag(playlist->cd, playlist->next);
if (tag == NULL)
return NULL;
++playlist->next;
filename = track_get_filename(track);
if (*filename == 0 || filename[0] == '.' ||
strchr(filename, '/') != NULL) {
/* unsafe characters found, bail out */
tag_free(tag);
return NULL;
}
uri = g_strconcat(playlist->path, "/", filename, NULL);
song = song_file_new(uri, NULL);
song->tag = tag;
g_free(uri);
return song;
}
static const char *const cue_playlist_suffixes[] = {
"cue",
NULL
};
static const char *const cue_playlist_mime_types[] = {
"application/x-cue",
NULL
};
const struct playlist_plugin cue_playlist_plugin = {
.name = "cue",
.open_uri = cue_playlist_open_uri,
.close = cue_playlist_close,
.read = cue_playlist_read,
.suffixes = cue_playlist_suffixes,
.mime_types = cue_playlist_mime_types,
};

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* 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.
*/
#ifndef MPD_PLAYLIST_CUE_PLAYLIST_PLUGIN_H
#define MPD_PLAYLIST_CUE_PLAYLIST_PLUGIN_H
extern const struct playlist_plugin cue_playlist_plugin;
#endif

View File

@ -26,6 +26,7 @@
#include "playlist/lastfm_playlist_plugin.h"
#include "playlist/pls_playlist_plugin.h"
#include "playlist/asx_playlist_plugin.h"
#include "playlist/cue_playlist_plugin.h"
#include "input_stream.h"
#include "uri.h"
#include "utils.h"
@ -45,6 +46,9 @@ static const struct playlist_plugin *const playlist_plugins[] = {
&asx_playlist_plugin,
#ifdef ENABLE_LASTFM
&lastfm_playlist_plugin,
#endif
#ifdef HAVE_CUE
&cue_playlist_plugin,
#endif
NULL
};