mirror of
https://github.com/owntone/owntone-server.git
synced 2025-11-30 13:42:58 -05:00
Support for live ICY metadata for streams (incl. artwork)
This commit is contained in:
127
src/artwork.c
127
src/artwork.c
@@ -38,6 +38,7 @@
|
||||
#include "logger.h"
|
||||
#include "conffile.h"
|
||||
#include "cache.h"
|
||||
#include "player.h"
|
||||
|
||||
#if LIBAVFORMAT_VERSION_MAJOR >= 53
|
||||
# include "avio_evbuffer.h"
|
||||
@@ -725,6 +726,127 @@ artwork_get(char *path, int max_w, int max_h, struct evbuffer *evbuf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
artwork_get_player_image(char *path, int max_w, int max_h, struct evbuffer *evbuf)
|
||||
{
|
||||
AVFormatContext *src_ctx;
|
||||
AVPacket pkt;
|
||||
char *url;
|
||||
int len;
|
||||
int s;
|
||||
int target_w;
|
||||
int target_h;
|
||||
int format_ok;
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_DBG, L_ART, "Trying internet stream artwork in %s\n", path);
|
||||
|
||||
player_icy_artwork_url(&url, path);
|
||||
if (!url)
|
||||
return 0;
|
||||
|
||||
len = strlen(url);
|
||||
if ((len < 14) || (len > PATH_MAX)) // Can't be shorter than http://a/1.jpg
|
||||
return 0;
|
||||
|
||||
src_ctx = NULL;
|
||||
ret = avformat_open_input(&src_ctx, url, NULL, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_WARN, L_ART, "Cannot open artwork file '%s': %s\n", url, strerror(AVUNERROR(ret)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
free(url);
|
||||
|
||||
format_ok = 0;
|
||||
for (s = 0; s < src_ctx->nb_streams; s++)
|
||||
{
|
||||
if (src_ctx->streams[s]->codec->codec_id == AV_CODEC_ID_PNG)
|
||||
{
|
||||
format_ok = ART_FMT_PNG;
|
||||
break;
|
||||
}
|
||||
else if (src_ctx->streams[s]->codec->codec_id == AV_CODEC_ID_MJPEG)
|
||||
{
|
||||
format_ok = ART_FMT_JPEG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s == src_ctx->nb_streams)
|
||||
{
|
||||
DPRINTF(E_LOG, L_ART, "Artwork file '%s' not a PNG or JPEG file\n", path);
|
||||
|
||||
avformat_close_input(&src_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
while (av_read_frame(src_ctx, &pkt) == 0)
|
||||
{
|
||||
if (pkt.stream_index != s)
|
||||
{
|
||||
av_free_packet(&pkt);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
DPRINTF(E_LOG, L_ART, "Could not read artwork: '%s'\n", path);
|
||||
|
||||
avformat_close_input(&src_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = rescale_needed(src_ctx->streams[s]->codec, max_w, max_h, &target_w, &target_h);
|
||||
|
||||
/* Fastpath */
|
||||
if (!ret && format_ok)
|
||||
{
|
||||
DPRINTF(E_DBG, L_ART, "Artwork not too large, using original image\n");
|
||||
|
||||
ret = evbuffer_expand(evbuf, pkt.size);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_ART, "Out of memory for artwork\n");
|
||||
|
||||
av_free_packet(&pkt);
|
||||
avformat_close_input(&src_ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = evbuffer_add(evbuf, pkt.data, pkt.size);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_ART, "Could not add image to event buffer\n");
|
||||
}
|
||||
else
|
||||
ret = format_ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_DBG, L_ART, "Artwork too large, rescaling image\n");
|
||||
|
||||
ret = artwork_rescale(src_ctx, s, target_w, target_h, evbuf);
|
||||
}
|
||||
|
||||
av_free_packet(&pkt);
|
||||
avformat_close_input(&src_ctx);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
if (evbuffer_get_length(evbuf) > 0)
|
||||
evbuffer_drain(evbuf, evbuffer_get_length(evbuf));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if LIBAVFORMAT_VERSION_MAJOR >= 55 || (LIBAVFORMAT_VERSION_MAJOR == 54 && LIBAVFORMAT_VERSION_MINOR >= 6)
|
||||
static int
|
||||
artwork_get_embedded_image(char *path, int max_w, int max_h, struct evbuffer *evbuf)
|
||||
@@ -786,7 +908,7 @@ artwork_get_embedded_image(char *path, int max_w, int max_h, struct evbuffer *ev
|
||||
|
||||
if (s == src_ctx->nb_streams)
|
||||
{
|
||||
DPRINTF(E_SPAM, L_ART, "Did not find embedded artwork in '%s'\n", path);
|
||||
DPRINTF(E_DBG, L_ART, "Did not find embedded artwork in '%s'\n", path);
|
||||
|
||||
avformat_close_input(&src_ctx);
|
||||
return -1;
|
||||
@@ -1062,6 +1184,9 @@ artwork_get_item_path(char *in_path, int artwork, int max_w, int max_h, char *ou
|
||||
ret = artwork_get_embedded_image(in_path, max_w, max_h, evbuf);
|
||||
break;
|
||||
#endif
|
||||
case ARTWORK_HTTP:
|
||||
ret = artwork_get_player_image(in_path, max_w, max_h, evbuf);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user