mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-26 23:25:56 -05:00
[pipe/artwork] Support for artwork via Shairport metadata pipes
This implementation uses the cache for storage. Might change that to use a tmpfile instead.
This commit is contained in:
parent
2e149273e5
commit
69fafd873d
@ -138,6 +138,7 @@ static int source_item_cache_get(struct artwork_ctx *ctx);
|
||||
static int source_item_embedded_get(struct artwork_ctx *ctx);
|
||||
static int source_item_own_get(struct artwork_ctx *ctx);
|
||||
static int source_item_stream_get(struct artwork_ctx *ctx);
|
||||
static int source_item_pipe_get(struct artwork_ctx *ctx);
|
||||
static int source_item_spotify_get(struct artwork_ctx *ctx);
|
||||
static int source_item_spotifywebapi_get(struct artwork_ctx *ctx);
|
||||
static int source_item_ownpl_get(struct artwork_ctx *ctx);
|
||||
@ -196,6 +197,12 @@ static struct artwork_source artwork_item_source[] =
|
||||
.data_kinds = (1 << DATA_KIND_HTTP),
|
||||
.cache = NEVER,
|
||||
},
|
||||
{
|
||||
.name = "pipe",
|
||||
.handler = source_item_pipe_get,
|
||||
.data_kinds = (1 << DATA_KIND_PIPE),
|
||||
.cache = NEVER,
|
||||
},
|
||||
{
|
||||
.name = "Spotify",
|
||||
.handler = source_item_spotify_get,
|
||||
@ -836,6 +843,26 @@ source_item_stream_get(struct artwork_ctx *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are playing a pipe and there is also a metadata pipe, then
|
||||
* input/pipe.c may have saved the incoming artwork via cache_artwork_stash()
|
||||
*
|
||||
*/
|
||||
static int
|
||||
source_item_pipe_get(struct artwork_ctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
int format;
|
||||
|
||||
DPRINTF(E_SPAM, L_ART, "Trying pipe metadata from %s.metadata\n", ctx->dbmfi->path);
|
||||
|
||||
ret = cache_artwork_read(ctx->evbuf, "pipe://metadata", &format);
|
||||
if (ret < 0)
|
||||
return ART_E_NONE;
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SPOTIFY_H
|
||||
static int
|
||||
source_item_spotify_get(struct artwork_ctx *ctx)
|
||||
|
@ -62,6 +62,8 @@
|
||||
#include "conffile.h"
|
||||
#include "listener.h"
|
||||
#include "player.h"
|
||||
#include "artwork.h"
|
||||
#include "cache.h"
|
||||
#include "worker.h"
|
||||
#include "commands.h"
|
||||
#include "mxml-compat.h"
|
||||
@ -72,6 +74,8 @@
|
||||
#define PIPE_READ_MAX 65536
|
||||
// Max number of bytes to buffer from metadata pipes
|
||||
#define PIPE_METADATA_BUFLEN_MAX 262144
|
||||
// Ignore pictures with larger size than this
|
||||
#define PIPE_PICTURE_SIZE_MAX 262144
|
||||
|
||||
enum pipetype
|
||||
{
|
||||
@ -353,6 +357,34 @@ handle_volume(const char *volume)
|
||||
DPRINTF(E_LOG, L_PLAYER, "Shairport airplay volume out of range (-144.0, [-30.0 - 0.0]): %.2f\n", airplay_volume);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_picture(struct input_metadata *m, uint8_t *data, int data_len)
|
||||
{
|
||||
struct evbuffer *evbuf;
|
||||
int format;
|
||||
|
||||
if (data_len < 2 || data_len > PIPE_PICTURE_SIZE_MAX)
|
||||
goto error;
|
||||
|
||||
if (data[0] == 0xff && data[1] == 0xd8)
|
||||
format = ART_FMT_JPEG;
|
||||
else if (data[0] == 0x89 && data[1] == 0x50)
|
||||
format = ART_FMT_PNG;
|
||||
else
|
||||
goto error;
|
||||
|
||||
CHECK_NULL(L_PLAYER, evbuf = evbuffer_new());
|
||||
|
||||
evbuffer_add(evbuf, data, data_len);
|
||||
cache_artwork_stash(evbuf, "pipe://metadata", format);
|
||||
evbuffer_free(evbuf);
|
||||
return;
|
||||
|
||||
error:
|
||||
DPRINTF(E_LOG, L_PLAYER, "Unsupported picture size (%d) or format from Shairport metadata pipe\n", data_len);
|
||||
cache_artwork_stash(NULL, NULL, 0); // Clear the artwork stash
|
||||
}
|
||||
|
||||
// returns 1 on metadata found, 0 on nothing, -1 on error
|
||||
static int
|
||||
handle_item(struct input_metadata *m, const char *item)
|
||||
@ -366,6 +398,7 @@ handle_item(struct input_metadata *m, const char *item)
|
||||
char **dstptr;
|
||||
char *progress;
|
||||
char *volume;
|
||||
char *picture;
|
||||
uint8_t *data;
|
||||
int data_len;
|
||||
int ret;
|
||||
@ -412,6 +445,8 @@ handle_item(struct input_metadata *m, const char *item)
|
||||
dstptr = &progress;
|
||||
else if (code == dmapval("pvol"))
|
||||
dstptr = &volume;
|
||||
else if (code == dmapval("PICT"))
|
||||
dstptr = &picture;
|
||||
else
|
||||
goto out_nothing;
|
||||
|
||||
@ -429,7 +464,7 @@ handle_item(struct input_metadata *m, const char *item)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
DPRINTF(E_DBG, L_PLAYER, "Read Shairport metadata (type=%8x, code=%8x, len=%d): '%s'\n", type, code, data_len, (char *)data);
|
||||
DPRINTF(E_DBG, L_PLAYER, "Read Shairport metadata (type=%8x, code=%8x, len=%d)\n", type, code, data_len);
|
||||
|
||||
if (dstptr == &progress)
|
||||
{
|
||||
@ -443,6 +478,11 @@ handle_item(struct input_metadata *m, const char *item)
|
||||
handle_volume(volume);
|
||||
free(data);
|
||||
}
|
||||
else if (dstptr == &picture)
|
||||
{
|
||||
handle_picture(m, data, data_len);
|
||||
free(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(*dstptr); // If m->x is already set, free it
|
||||
|
Loading…
Reference in New Issue
Block a user