From 00d84a3bed357c8efc88affc3c0e100e915699c5 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Wed, 21 Apr 2010 19:44:31 +0200 Subject: improved icy metadata handling; separate artist and title fields --- deadbeef.h | 6 +-- plugins.c | 3 +- plugins/mpgmad/mpgmad.c | 39 +-------------- plugins/vfs_curl/vfs_curl.c | 113 +++++++++++++++++--------------------------- vfs.c | 24 ++++------ vfs.h | 3 +- 6 files changed, 58 insertions(+), 130 deletions(-) diff --git a/deadbeef.h b/deadbeef.h index d3500f8c..53059d89 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -490,8 +490,7 @@ typedef struct { void (*rewind) (DB_FILE *stream); int64_t (*fgetlength) (DB_FILE *stream); const char *(*fget_content_type) (DB_FILE *stream); - const char *(*fget_content_name) (DB_FILE *stream); - const char *(*fget_content_genre) (DB_FILE *stream); + void (*fset_track) (DB_FILE *stream, DB_playItem_t *it); void (*fstop) (DB_FILE *stream); // message passing int (*sendmessage) (uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2); @@ -664,6 +663,7 @@ typedef struct { typedef struct DB_vfs_s { DB_plugin_t plugin; DB_FILE* (*open) (const char *fname); + void (*set_track) (DB_FILE *f, DB_playItem_t *it); void (*close) (DB_FILE *f); size_t (*read) (void *ptr, size_t size, size_t nmemb, DB_FILE *stream); int (*seek) (DB_FILE *stream, int64_t offset, int whence); @@ -671,8 +671,6 @@ typedef struct DB_vfs_s { void (*rewind) (DB_FILE *stream); int64_t (*getlength)(DB_FILE *stream); const char * (*get_content_type) (DB_FILE *stream); - const char * (*get_content_name) (DB_FILE *stream); - const char * (*get_content_genre) (DB_FILE *stream); const char **scheme_names; // NULL-terminated list of supported schemes, e.g. {"http", "ftp", NULL} unsigned streaming : 1; } DB_vfs_t; diff --git a/plugins.c b/plugins.c index d0b2e4cb..4dfa1747 100644 --- a/plugins.c +++ b/plugins.c @@ -222,8 +222,7 @@ static DB_functions_t deadbeef_api = { .rewind = vfs_rewind, .fgetlength = vfs_fgetlength, .fget_content_type = vfs_get_content_type, - .fget_content_name = vfs_get_content_name, - .fget_content_genre = vfs_get_content_genre, + .fset_track = (void (*) (DB_FILE *stream, DB_playItem_t *it))vfs_set_track, // message passing .sendmessage = messagepump_push, // configuration access diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c index 218f32c5..cfd1f47e 100644 --- a/plugins/mpgmad/mpgmad.c +++ b/plugins/mpgmad/mpgmad.c @@ -596,30 +596,17 @@ cmp3_init (DB_playItem_t *it) { } } else { + deadbeef->fset_track (info->buffer.file, it); info->buffer.it->filetype = NULL; int len = deadbeef->fgetlength (info->buffer.file); - const char *name = deadbeef->fget_content_name (info->buffer.file); - const char *genre = deadbeef->fget_content_genre (info->buffer.file); if (len > 0) { deadbeef->pl_delete_all_meta (it); int v2err = deadbeef->junk_id3v2_read (it, info->buffer.file); - deadbeef->pl_add_meta (it, "title", NULL); if (v2err != 0) { deadbeef->fseek (info->buffer.file, 0, SEEK_SET); } } - else { - deadbeef->pl_delete_all_meta (it); - if (name) { - deadbeef->pl_add_meta (it, "title", name); - } - else { - deadbeef->pl_add_meta (it, "title", NULL); - } - if (genre) { - deadbeef->pl_add_meta (it, "genre", genre); - } - } + deadbeef->pl_add_meta (it, "title", NULL); int res = cmp3_scan_stream (&info->buffer, 0); if (res < 0) { trace ("mpgmad: cmp3_init: initial cmp3_scan_stream failed\n"); @@ -873,28 +860,6 @@ cmp3_stream_frame (mpgmad_info_t *info) { break; } - if (!eof) { - if (info->buffer.file->vfs->streaming && info->buffer.currentsample - info->buffer.last_comment_update > 5 * info->info.samplerate) { - if (info->buffer.it) { - info->buffer.last_comment_update = info->buffer.currentsample; - const char *vfs_tit = deadbeef->fget_content_name (info->buffer.file); - if (vfs_tit) { - const char *cs = deadbeef->junk_detect_charset (vfs_tit); - if (cs) { - char out[1024]; - deadbeef->junk_recode (vfs_tit, strlen (vfs_tit), out, sizeof (out), cs); - deadbeef->pl_replace_meta (info->buffer.it, "title", out); - deadbeef->plug_trigger_event_trackinfochanged (info->buffer.it); - } - else { - deadbeef->pl_replace_meta (info->buffer.it, "title", vfs_tit); - deadbeef->plug_trigger_event_trackinfochanged (info->buffer.it); - } - } - } - } - } - return eof; } diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c index 320b60f0..6dd417bd 100644 --- a/plugins/vfs_curl/vfs_curl.c +++ b/plugins/vfs_curl/vfs_curl.c @@ -48,6 +48,7 @@ typedef struct { DB_vfs_t *vfs; char *url; uint8_t buffer[BUFFER_SIZE]; + DB_playItem_t *track; long pos; // position in stream; use "& BUFFER_MASK" to make it index into ringbuffer int64_t length; int32_t remaining; // remaining bytes in buffer read from stream @@ -56,8 +57,8 @@ typedef struct { intptr_t mutex; uint8_t nheaderpackets; char *content_type; - char *content_name; - char *content_genre; +// char *content_name; +// char *content_genre; CURL *curl; struct timeval last_read_time; uint8_t status; @@ -127,6 +128,20 @@ http_curl_write_wrapper (HTTP_FILE *fp, void *ptr, size_t size) { return size - avail; } +void +vfs_curl_set_meta (DB_playItem_t *it, const char *meta, const char *value) { + const char *cs = deadbeef->junk_detect_charset (value); + if (cs) { + char out[1024]; + deadbeef->junk_recode (value, strlen (value), out, sizeof (out), cs); + deadbeef->pl_replace_meta (it, meta, out); + } + else { + deadbeef->pl_replace_meta (it, meta, value); + } + deadbeef->plug_trigger_event_trackinfochanged (it); +} + int http_parse_shoutcast_meta (HTTP_FILE *fp, const char *meta, int size) { trace ("reading %d bytes of metadata\n", size); @@ -150,10 +165,18 @@ http_parse_shoutcast_meta (HTTP_FILE *fp, const char *meta, int size) { memcpy (title, meta, s); title[s] = 0; trace ("got stream title: %s\n", title); - if (fp->content_name) { - free (fp->content_name); + if (fp->track) { + char *tit = strstr (title, " - "); + if (tit) { + *tit = 0; + tit += 3; + vfs_curl_set_meta (fp->track, "artist", title); + vfs_curl_set_meta (fp->track, "title", tit); + } + else { + vfs_curl_set_meta (fp->track, "title", title); + } } - fp->content_name = strdup (title); return 0; } while (meta < e && *meta != ';') { @@ -343,16 +366,14 @@ http_content_header_handler (void *ptr, size_t size, size_t nmemb, void *stream) fp->length = atoi (value); } else if (!strcasecmp (key, "icy-name")) { - if (fp->content_name) { - free (fp->content_name); + if (fp->track) { + vfs_curl_set_meta (fp->track, "title", value); } - fp->content_name = strdup (value); } else if (!strcasecmp (key, "icy-genre")) { - if (fp->content_genre) { - free (fp->content_genre); + if (fp->track) { + vfs_curl_set_meta (fp->track, "genre", value); } - fp->content_genre = strdup (value); } else if (!strcasecmp (key, "icy-metaint")) { //printf ("icy-metaint: %d\n", atoi (value)); @@ -483,14 +504,6 @@ http_thread_func (void *ctx) { free (fp->content_type); fp->content_type = NULL; } - if (fp->content_name) { - free (fp->content_name); - fp->content_name = NULL; - } - if (fp->content_genre) { - free (fp->content_genre); - fp->content_genre = NULL; - } fp->seektoend = 0; fp->gotheader = 0; fp->icyheader = 0; @@ -529,6 +542,14 @@ http_open (const char *fname) { fp->url = strdup (fname); return (DB_FILE*)fp; } +static void +http_set_track (DB_FILE *f, DB_playItem_t *it) { + HTTP_FILE *fp = (HTTP_FILE *)f; + fp->track = it; + if (it) { + deadbeef->pl_item_ref (it); + } +} static void http_close (DB_FILE *stream) { @@ -545,11 +566,8 @@ http_close (DB_FILE *stream) { if (fp->content_type) { free (fp->content_type); } - if (fp->content_name) { - free (fp->content_name); - } - if (fp->content_genre) { - free (fp->content_genre); + if (fp->track) { + deadbeef->pl_item_unref (fp->track); } if (fp->url) { free (fp->url); @@ -748,49 +766,6 @@ http_get_content_type (DB_FILE *stream) { return fp->content_type; } -static const char * -http_get_content_name (DB_FILE *stream) { - trace ("http_get_content_name\n"); - assert (stream); - HTTP_FILE *fp = (HTTP_FILE *)stream; - if (fp->status == STATUS_ABORTED) { - return NULL; - } - if (fp->gotheader) { - trace ("returning %s\n", fp->content_name); - return fp->content_name; - } - if (!fp->tid) { - http_start_streamer (fp); - } - trace ("http_get_content_name waiting for response...\n"); - while (fp->status != STATUS_FINISHED && fp->status != STATUS_ABORTED && !fp->gotheader && !vfs_curl_abort) { - usleep (3000); - } - return fp->content_name; -} - -static const char * -http_get_content_genre (DB_FILE *stream) { - trace ("http_get_content_genre\n"); - assert (stream); - HTTP_FILE *fp = (HTTP_FILE *)stream; - if (fp->status == STATUS_ABORTED) { - return NULL; - } - if (fp->gotheader) { - return fp->content_genre; - } - if (!fp->tid) { - http_start_streamer (fp); - } - trace ("http_get_content_genre waiting for response...\n"); - while (fp->status != STATUS_FINISHED && fp->status != STATUS_ABORTED && !fp->gotheader && !vfs_curl_abort) { - usleep (3000); - } - return fp->content_genre; -} - static int vfs_curl_on_abort (DB_event_t *ev, uintptr_t data) { trace ("vfs_curl: got abort signal (vfs_curl_count=%d)!\n", vfs_curl_count); @@ -829,6 +804,7 @@ static DB_vfs_t plugin = { .plugin.version_major = 0, .plugin.version_minor = 1, .plugin.type = DB_PLUGIN_VFS, + .plugin.id = "vfs_curl", .plugin.name = "cURL vfs", .plugin.descr = "http and ftp streaming module using libcurl, with ICY protocol support", .plugin.author = "Alexey Yakovenko", @@ -837,6 +813,7 @@ static DB_vfs_t plugin = { .plugin.start = vfs_curl_start, .plugin.stop = vfs_curl_stop, .open = http_open, + .set_track = http_set_track, .close = http_close, .read = http_read, .seek = http_seek, @@ -844,8 +821,6 @@ static DB_vfs_t plugin = { .rewind = http_rewind, .getlength = http_getlength, .get_content_type = http_get_content_type, - .get_content_name = http_get_content_name, - .get_content_genre = http_get_content_genre, .scheme_names = scheme_names, .streaming = 1 }; diff --git a/vfs.c b/vfs.c index 432e844f..f676c38c 100644 --- a/vfs.c +++ b/vfs.c @@ -21,8 +21,8 @@ #include "vfs.h" #include "plugins.h" -#define trace(...) { fprintf(stderr, __VA_ARGS__); } -//#define trace(fmt,...) +//#define trace(...) { fprintf(stderr, __VA_ARGS__); } +#define trace(fmt,...) DB_FILE * vfs_fopen (const char *fname) { @@ -50,6 +50,12 @@ vfs_fopen (const char *fname) { return NULL; } +void vfs_set_track (DB_FILE *stream, DB_playItem_t *it) { + if (stream->vfs->set_track) { + stream->vfs->set_track (stream, it); + } +} + void vfs_fclose (DB_FILE *stream) { return stream->vfs->close (stream); @@ -85,17 +91,3 @@ vfs_get_content_type (DB_FILE *stream) { return stream->vfs->get_content_type (stream); } -const char * -vfs_get_content_name (DB_FILE *stream) { - if (stream->vfs->get_content_name) { - return stream->vfs->get_content_name (stream); - } - return NULL; -} -const char * -vfs_get_content_genre (DB_FILE *stream) { - if (stream->vfs->get_content_genre) { - return stream->vfs->get_content_genre (stream); - } - return NULL; -} diff --git a/vfs.h b/vfs.h index af00cb29..66e44315 100644 --- a/vfs.h +++ b/vfs.h @@ -23,6 +23,7 @@ #include "deadbeef.h" DB_FILE* vfs_fopen (const char *fname); +void vfs_set_track (DB_FILE *stream, DB_playItem_t *it); void vfs_fclose (DB_FILE *f); size_t vfs_fread (void *ptr, size_t size, size_t nmemb, DB_FILE *stream); int vfs_fseek (DB_FILE *stream, int64_t offset, int whence); @@ -30,8 +31,6 @@ int64_t vfs_ftell (DB_FILE *stream); void vfs_rewind (DB_FILE *stream); int64_t vfs_fgetlength (DB_FILE *stream); const char *vfs_get_content_type (DB_FILE *stream); -const char *vfs_get_content_name (DB_FILE *stream); -const char *vfs_get_content_genre (DB_FILE *stream); void vfs_fstop (DB_FILE *stream); #endif // __VFS_H -- cgit v1.2.3