Merge pull request #628 from chme/artwork

[jsonapi] Artwork url for non library items and streams
This commit is contained in:
ejurgensen 2018-11-30 10:12:41 +01:00 committed by GitHub
commit 357d346fce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 15 deletions

View File

@ -1724,6 +1724,7 @@ curl --include \
| data_kind | string | Data type of this track: `file`, `url`, `spotify`, `pipe` |
| path | string | Path |
| uri | string | Resource identifier |
| artwork_url | string | *(optional)* [Artwork url](#artwork-urls) |
### `playlist` object
@ -1748,6 +1749,7 @@ curl --include \
| track_count | integer | Number of tracks |
| length_ms | integer | Total length of tracks in milliseconds |
| uri | string | Resource identifier |
| artwork_url | string | *(optional)* [Artwork url](#artwork-urls) |
### `album` object
@ -1762,6 +1764,7 @@ curl --include \
| track_count | integer | Number of tracks |
| length_ms | integer | Total length of tracks in milliseconds |
| uri | string | Resource identifier |
| artwork_url | string | *(optional)* [Artwork url](#artwork-urls) |
### `track` object
@ -1792,6 +1795,7 @@ curl --include \
| data_kind | string | Data type of this track: `file`, `stream`, `spotify`, `pipe` |
| path | string | Path |
| uri | string | Resource identifier |
| artwork_url | string | *(optional)* [Artwork url](#artwork-urls) |
### `paging` object
@ -1810,3 +1814,13 @@ curl --include \
| --------------- | -------- | ----------------------------------------- |
| name | string | Name of genre |
### Artwork urls
Artwork urls in `queue item`, `artist`, `album` and `track` objects can be either relative urls or absolute urls to the artwork image.
Absolute artwork urls are pointing to external artwork images (e. g. for radio streams that provide artwork metadata), while relative artwork urls are served from forked-daapd.
It is possible to add the query parameters `maxwidth` and/or `maxheight` to relative artwork urls, in order to get a smaller image (forked-daapd only scales down never up).
Note that even if a relative artwork url attribute is present, it is not guaranteed to exist.

View File

@ -5,6 +5,9 @@
#define ART_FMT_PNG 1
#define ART_FMT_JPEG 2
#define ART_DEFAULT_HEIGHT 600
#define ART_DEFAULT_WIDTH 600
#include <event2/buffer.h>
/*

View File

@ -4665,13 +4665,13 @@ queue_add_item(struct db_queue_item *item, int pos, int shuffle_pos, int queue_v
"pos, shuffle_pos, path, virtual_path, title, " \
"artist, album_artist, album, genre, songalbumid, " \
"time_modified, artist_sort, album_sort, album_artist_sort, year, " \
"track, disc, queue_version)" \
"track, disc, artwork_url, queue_version)" \
"VALUES" \
"(NULL, %d, %d, %d, %d, " \
"%d, %d, %Q, %Q, %Q, " \
"%Q, %Q, %Q, %Q, %" PRIi64 ", " \
"%d, %Q, %Q, %Q, %d, " \
"%d, %d, %d);"
"%d, %d, %Q, %d);"
char *query;
int ret;
@ -4681,7 +4681,7 @@ queue_add_item(struct db_queue_item *item, int pos, int shuffle_pos, int queue_v
pos, shuffle_pos, item->path, item->virtual_path, item->title,
item->artist, item->album_artist, item->album, item->genre, item->songalbumid,
item->time_modified, item->artist_sort, item->album_sort, item->album_artist_sort, item->year,
item->track, item->disc, queue_version);
item->track, item->disc, item->artwork_url, queue_version);
ret = db_query_run(query, 1, 0);
return ret;

View File

@ -639,7 +639,7 @@ metadata_packet_get(struct http_icy_metadata *metadata, AVFormatContext *fmtctx)
else
metadata->title = strdup(metadata->title);
}
else if ((strncmp(icy_token, "StreamUrl", strlen("StreamUrl")) == 0) && !metadata->artwork_url)
else if ((strncmp(icy_token, "StreamUrl", strlen("StreamUrl")) == 0) && !metadata->artwork_url && strlen(ptr) > 0)
{
metadata->artwork_url = strdup(ptr);
}

View File

@ -1525,7 +1525,8 @@ queue_item_to_json(struct db_queue_item *queue_item, char shuffle)
else
json_object_object_add(item, "position", json_object_new_int(queue_item->pos));
json_object_object_add(item, "track_id", json_object_new_int(queue_item->file_id));
if (queue_item->file_id > 0 && queue_item->file_id != DB_MEDIA_FILE_NON_PERSISTENT_ID)
json_object_object_add(item, "track_id", json_object_new_int(queue_item->file_id));
safe_json_add_string(item, "title", queue_item->title);
safe_json_add_string(item, "artist", queue_item->artist);
@ -1546,21 +1547,27 @@ queue_item_to_json(struct db_queue_item *queue_item, char shuffle)
safe_json_add_string(item, "path", queue_item->path);
if (queue_item->file_id > 0)
if (queue_item->file_id > 0 && queue_item->file_id != DB_MEDIA_FILE_NON_PERSISTENT_ID)
{
ret = snprintf(uri, sizeof(uri), "%s:%s:%d", "library", "track", queue_item->file_id);
if (ret < sizeof(uri))
json_object_object_add(item, "uri", json_object_new_string(uri));
ret = snprintf(artwork_url, sizeof(artwork_url), "/artwork/item/%d", queue_item->file_id);
if (ret < sizeof(artwork_url))
json_object_object_add(item, "artwork_url", json_object_new_string(artwork_url));
}
else
{
safe_json_add_string(item, "uri", queue_item->path);
}
if (queue_item->artwork_url)
{
safe_json_add_string(item, "artwork_url", queue_item->artwork_url);
}
else if (queue_item->file_id > 0 && queue_item->file_id != DB_MEDIA_FILE_NON_PERSISTENT_ID)
{
ret = snprintf(artwork_url, sizeof(artwork_url), "/artwork/item/%d", queue_item->file_id);
if (ret < sizeof(artwork_url))
json_object_object_add(item, "artwork_url", json_object_new_string(artwork_url));
}
return item;
}

View File

@ -4702,7 +4702,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
return;
}
format = artwork_get_item(evbuffer, itemid, 600, 600);
format = artwork_get_item(evbuffer, itemid, ART_DEFAULT_WIDTH, ART_DEFAULT_HEIGHT);
if (format < 0)
{
httpd_send_error(req, HTTP_NOTFOUND, "Document was not found");

View File

@ -894,7 +894,7 @@ raop_metadata_prepare(int id)
goto skip_artwork;
}
ret = artwork_get_item(rmd->artwork, queue_item->file_id, 600, 600);
ret = artwork_get_item(rmd->artwork, queue_item->file_id, ART_DEFAULT_WIDTH, ART_DEFAULT_HEIGHT);
if (ret < 0)
{
DPRINTF(E_INFO, L_RAOP, "Failed to retrieve artwork for file id %d; no artwork will be sent\n", id);

View File

@ -26,6 +26,7 @@
#include <string.h>
#include <time.h>
#include "artwork.h"
#include "cache.h"
#include "conffile.h"
#include "db.h"
@ -53,6 +54,7 @@ struct spotify_album
const char *release_date_precision;
int release_year;
const char *uri;
const char *artwork_url;
};
struct spotify_track
@ -71,6 +73,7 @@ struct spotify_track
const char *name;
int track_number;
const char *uri;
const char *artwork_url;
bool is_playable;
const char *restrictions;
@ -577,12 +580,50 @@ request_pagingobject_endpoint(const char *href, paging_item_cb item_cb, paging_r
return 0;
}
static const char *
get_album_image(json_object *jsonalbum)
{
json_object *jsonimages;
json_object *jsonimage;
int image_count;
int index;
const char *artwork_url;
int width;
int temp;
artwork_url = NULL;
temp = 0;
width = 0;
if (json_object_object_get_ex(jsonalbum, "images", &jsonimages))
{
// Find image closest to ART_DEFAULT_WIDTH
image_count = json_object_array_length(jsonimages);
for (index = 0; index < image_count; index++)
{
jsonimage = json_object_array_get_idx(jsonimages, index);
if (jsonimage)
{
temp = jparse_int_from_obj(jsonimage, "width");
if (temp > width && temp < ART_DEFAULT_WIDTH)
{
artwork_url = jparse_str_from_obj(jsonimage, "url");
width = temp;
}
}
}
}
return artwork_url;
}
static void
parse_metadata_track(json_object *jsontrack, struct spotify_track *track)
{
json_object* jsonalbum;
json_object* jsonartists;
json_object* needle;
json_object *jsonalbum;
json_object *jsonartists;
json_object *needle;
memset(track, 0, sizeof(struct spotify_track));
@ -591,6 +632,8 @@ parse_metadata_track(json_object *jsontrack, struct spotify_track *track)
track->album = jparse_str_from_obj(jsonalbum, "name");
if (json_object_object_get_ex(jsonalbum, "artists", &jsonartists))
track->album_artist = jparse_str_from_array(jsonartists, 0, "name");
track->artwork_url = get_album_image(jsonalbum);
}
if (json_object_object_get_ex(jsontrack, "artists", &jsonartists))
@ -658,6 +701,8 @@ parse_metadata_album(json_object *jsonalbum, struct spotify_album *album)
album->release_date_precision = jparse_str_from_obj(jsonalbum, "release_date_precision");
album->release_year = get_year_from_date(album->release_date);
album->artwork_url = get_album_image(jsonalbum);
// TODO Genre is an array of strings ('genres'), but it is always empty (https://github.com/spotify/web-api/issues/157)
//album->genre = jparse_str_from_obj(jsonalbum, "genre");
}
@ -976,11 +1021,13 @@ map_track_to_queueitem(struct db_queue_item *item, const struct spotify_track *t
{
item->album_artist = safe_strdup(album->artist);
item->album = safe_strdup(album->name);
item->artwork_url = safe_strdup(album->artwork_url);
}
else
{
item->album_artist = safe_strdup(track->album_artist);
item->album = safe_strdup(track->album);
item->artwork_url = safe_strdup(track->artwork_url);
}
item->disc = track->disc_number;