summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-04-21 19:44:31 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-04-21 19:44:45 +0200
commit00d84a3bed357c8efc88affc3c0e100e915699c5 (patch)
tree01fb0ee6535456d24b92775ecccc3a2b6b7522a1
parent34a244ee1a02423a867bc86efe8b9f21d9a208b0 (diff)
improved icy metadata handling; separate artist and title fields
-rw-r--r--deadbeef.h6
-rw-r--r--plugins.c3
-rw-r--r--plugins/mpgmad/mpgmad.c39
-rw-r--r--plugins/vfs_curl/vfs_curl.c113
-rw-r--r--vfs.c24
-rw-r--r--vfs.h3
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