[filescanner] Add http stream to the library prior to adding to a

persistent playlist
This commit is contained in:
chme 2018-04-12 20:43:05 +02:00 committed by ejurgensen
parent 60ebac076b
commit 7dd8955a92
6 changed files with 76 additions and 63 deletions

View File

@ -78,6 +78,9 @@ enum query_type {
/* Max value for media_file_info->rating (valid range is from 0 to 100) */
#define DB_FILES_RATING_MAX 100
/* Magic id for media_file_info objects that are not stored in the files database table */
#define DB_MEDIA_FILE_NON_PERSISTENT_ID 9999999
struct query_params {
/* Query parameters, filled in by caller */
enum query_type type;

View File

@ -143,7 +143,7 @@ static int seek_target;
/* If an item is removed from the library while in the queue, we replace it with this */
static struct media_file_info dummy_mfi =
{
.id = 9999999,
.id = DB_MEDIA_FILE_NON_PERSISTENT_ID,
.title = "(unknown title)",
.artist = "(unknown artist)",
.album = "(unknown album)",
@ -151,7 +151,7 @@ static struct media_file_info dummy_mfi =
};
static struct db_queue_item dummy_queue_item =
{
.file_id = 9999999,
.file_id = DB_MEDIA_FILE_NON_PERSISTENT_ID,
.title = "(unknown title)",
.artist = "(unknown artist)",
.album = "(unknown album)",

View File

@ -1651,7 +1651,7 @@ map_media_file_to_queue_item(struct db_queue_item *queue_item, struct media_file
if (mfi->id)
queue_item->file_id = mfi->id;
else
queue_item->file_id = 9999999;
queue_item->file_id = DB_MEDIA_FILE_NON_PERSISTENT_ID;
queue_item->title = safe_strdup(mfi->title);
queue_item->artist = safe_strdup(mfi->artist);
@ -1679,43 +1679,13 @@ static int
queue_add_stream(const char *path)
{
struct media_file_info mfi;
char *pos;
struct db_queue_item item;
struct db_queue_add_info queue_add_info;
int ret;
memset(&mfi, 0, sizeof(struct media_file_info));
mfi.path = strdup(path);
mfi.virtual_path = safe_asprintf("/%s", mfi.path);
pos = strchr(path, '#');
if (pos)
mfi.fname = strdup(pos+1);
else
mfi.fname = strdup(filename_from_path(mfi.path));
mfi.data_kind = DATA_KIND_HTTP;
mfi.directory_id = DIR_HTTP;
ret = scan_metadata_ffmpeg(path, &mfi);
if (ret < 0)
{
DPRINTF(E_LOG, L_SCAN, "Playlist URL '%s' is unavailable for probe/metadata, assuming MP3 encoding\n", path);
mfi.type = strdup("mp3");
mfi.codectype = strdup("mpeg");
mfi.description = strdup("MPEG audio file");
}
if (!mfi.title)
mfi.title = strdup(mfi.fname);
if (!mfi.virtual_path)
mfi.virtual_path = strdup(mfi.path);
if (!mfi.item_kind)
mfi.item_kind = 2; /* music */
if (!mfi.media_kind)
mfi.media_kind = MEDIA_KIND_MUSIC; /* music */
scan_metadata_stream(path, &mfi);
unicode_fixup_mfi(&mfi);
map_media_file_to_queue_item(&item, &mfi);
@ -1891,6 +1861,8 @@ playlist_add_files(FILE *fp, int pl_id, const char *virtual_path)
struct query_params qp;
struct db_media_file_info dbmfi;
uint32_t data_kind;
const char *path;
struct media_file_info mfi;
int ret;
memset(&qp, 0, sizeof(struct query_params));
@ -1901,28 +1873,45 @@ playlist_add_files(FILE *fp, int pl_id, const char *virtual_path)
ret = db_query_start(&qp);
if (ret < 0)
{
db_query_end(&qp);
free(qp.filter);
return -1;
}
goto out;
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
if (qp.results > 0)
{
if ((safe_atou32(dbmfi.data_kind, &data_kind) < 0)
|| (data_kind == DATA_KIND_PIPE))
{
DPRINTF(E_WARN, L_SCAN, "Item '%s' not added to playlist (id = %d), unsupported data kind\n", dbmfi.path, pl_id);
continue;
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
{
if ((safe_atou32(dbmfi.data_kind, &data_kind) < 0)
|| (data_kind == DATA_KIND_PIPE))
{
DPRINTF(E_WARN, L_SCAN, "Item '%s' not added to playlist (id = %d), unsupported data kind\n", dbmfi.path, pl_id);
continue;
}
ret = playlist_add_path(fp, pl_id, dbmfi.path);
if (ret < 0)
break;
DPRINTF(E_DBG, L_SCAN, "Item '%s' added to playlist (id = %d)\n", dbmfi.path, pl_id);
}
}
else if (strncasecmp(virtual_path, "/http://", strlen("/http://")) == 0)
{
path = (virtual_path + 1);
ret = playlist_add_path(fp, pl_id, dbmfi.path);
DPRINTF(E_DBG, L_SCAN, "Scan stream '%s' and add to playlist (id = %d)\n", path, pl_id);
memset(&mfi, 0, sizeof(struct media_file_info));
scan_metadata_stream(path, &mfi);
library_add_media(&mfi);
free_mfi(&mfi, 1);
ret = playlist_add_path(fp, pl_id, path);
if (ret < 0)
break;
DPRINTF(E_DBG, L_SCAN, "Item '%s' added to playlist (id = %d)\n", dbmfi.path, pl_id);
DPRINTF(E_LOG, L_SCAN, "Failed to add stream '%s' to playlist (id = %d)\n", path, pl_id);
else
DPRINTF(E_DBG, L_SCAN, "Item '%s' added to playlist (id = %d)\n", path, pl_id);
}
out:
db_query_end(&qp);
free(qp.filter);
@ -2017,6 +2006,7 @@ queue_save(const char *virtual_path)
FILE *fp;
struct query_params query_params;
struct db_queue_item queue_item;
struct media_file_info mfi;
int pl_id;
int ret;
@ -2058,6 +2048,25 @@ queue_save(const char *virtual_path)
continue;
}
if (queue_item.file_id == DB_MEDIA_FILE_NON_PERSISTENT_ID)
{
// If the queue item is not in the library and it is a http stream, scan and add to the library prior to saving to the playlist file.
if (queue_item.data_kind == DATA_KIND_HTTP)
{
DPRINTF(E_DBG, L_SCAN, "Scan stream '%s' and add to playlist (id = %d)\n", queue_item.path, pl_id);
memset(&mfi, 0, sizeof(struct media_file_info));
scan_metadata_stream(queue_item.path, &mfi);
library_add_media(&mfi);
free_mfi(&mfi, 1);
}
else
{
DPRINTF(E_LOG, L_SCAN, "Unsupported item for playlist file '%s' ignoring item '%s'\n", virtual_path, queue_item.path);
continue;
}
}
ret = fprintf(fp, "%s\n", queue_item.path);
if (ret < 0)
{

View File

@ -10,6 +10,9 @@
int
scan_metadata_ffmpeg(const char *file, struct media_file_info *mfi);
void
scan_metadata_stream(const char *path, struct media_file_info *mfi);
void
scan_playlist(const char *file, time_t mtime, int dir_id);

View File

@ -72,18 +72,14 @@ extinf_get(char *string, struct media_file_info *mfi, int *extinf)
return 1;
}
static int
process_url(int pl_id, const char *path, time_t mtime, int extinf, struct media_file_info *mfi)
void
scan_metadata_stream(const char *path, struct media_file_info *mfi)
{
char virtual_path[PATH_MAX];
char *pos;
int ret;
if (extinf)
DPRINTF(E_INFO, L_SCAN, "Playlist has EXTINF metadata, artist is '%s', title is '%s'\n", mfi->artist, mfi->title);
mfi->id = db_file_id_bypath(path);
mfi->path = strdup(path);
mfi->virtual_path = safe_asprintf("/%s", mfi->path);
pos = strchr(path, '#');
if (pos)
@ -92,7 +88,7 @@ process_url(int pl_id, const char *path, time_t mtime, int extinf, struct media_
mfi->fname = strdup(filename_from_path(mfi->path));
mfi->data_kind = DATA_KIND_HTTP;
mfi->time_modified = mtime;
mfi->time_modified = time(NULL);
mfi->directory_id = DIR_HTTP;
ret = scan_metadata_ffmpeg(path, mfi);
@ -106,12 +102,14 @@ process_url(int pl_id, const char *path, time_t mtime, int extinf, struct media_
if (!mfi->title)
mfi->title = strdup(mfi->fname);
}
snprintf(virtual_path, sizeof(virtual_path), "/%s", mfi->path);
mfi->virtual_path = strdup(virtual_path);
static int
process_url(int pl_id, const char *path, struct media_file_info *mfi)
{
mfi->id = db_file_id_bypath(path);
scan_metadata_stream(path, mfi);
library_add_media(mfi);
return db_pl_add_item_bypath(pl_id, path);
}
@ -341,7 +339,7 @@ scan_playlist(const char *file, time_t mtime, int dir_id)
/* Check if line is an URL, will be added to library, otherwise it should already be there */
if (strncasecmp(path, "http://", 7) == 0)
ret = process_url(pl_id, path, sb.st_mtime, extinf, &mfi);
ret = process_url(pl_id, path, &mfi);
else
ret = process_regular_file(pl_id, path);

View File

@ -2510,7 +2510,7 @@ mpd_command_playlistadd(struct evbuffer *evbuf, int argc, char **argv, char **er
free(vp_item);
if (ret < 0)
{
*errmsg = safe_asprintf("Error saving queue to file '%s'", argv[1]);
*errmsg = safe_asprintf("Error adding item to file '%s'", argv[1]);
return ACK_ERROR_ARG;
}