mirror of
https://github.com/owntone/owntone-server.git
synced 2025-05-04 00:40:35 -04:00
Merge branch 'podcast'
Conflicts: src/conffile.c
This commit is contained in:
commit
862cde3849
@ -25,9 +25,24 @@ library {
|
|||||||
|
|
||||||
# Directories to index
|
# Directories to index
|
||||||
directories = { "/srv/music" }
|
directories = { "/srv/music" }
|
||||||
# Directories containing compilations
|
|
||||||
# Matches anywhere in the path (not a regexp, though)
|
# Directories containing podcasts
|
||||||
# compilations = { "/compilations/" }
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# podcasts. Eg. if you index /srv/music, and your podcasts are in
|
||||||
|
# /srv/music/Podcasts, you can set this to "/Podcasts".
|
||||||
|
podcasts = { "/Podcasts" }
|
||||||
|
|
||||||
|
# Directories containing compilations (eg soundtracks)
|
||||||
|
# For each directory that is indexed the path is matched against these
|
||||||
|
# names. If there is a match all items in the directory are marked as
|
||||||
|
# compilations.
|
||||||
|
compilations = { "/Compilations" }
|
||||||
|
|
||||||
|
# Compilations usually have many artists, and if you don't want every
|
||||||
|
# artist to be listed when artist browsing in Remote, you can set
|
||||||
|
# a single name which will be used for all music in the compilation dir
|
||||||
|
compilation_artist = "Various artists"
|
||||||
|
|
||||||
# Artwork file names (without file type extension)
|
# Artwork file names (without file type extension)
|
||||||
# forked-daapd will look for jpg and png files with these base names
|
# forked-daapd will look for jpg and png files with these base names
|
||||||
|
@ -60,7 +60,9 @@ static cfg_opt_t sec_library[] =
|
|||||||
CFG_INT("port", 3689, CFGF_NONE),
|
CFG_INT("port", 3689, CFGF_NONE),
|
||||||
CFG_STR("password", NULL, CFGF_NONE),
|
CFG_STR("password", NULL, CFGF_NONE),
|
||||||
CFG_STR_LIST("directories", NULL, CFGF_NONE),
|
CFG_STR_LIST("directories", NULL, CFGF_NONE),
|
||||||
|
CFG_STR_LIST("podcasts", NULL, CFGF_NONE),
|
||||||
CFG_STR_LIST("compilations", NULL, CFGF_NONE),
|
CFG_STR_LIST("compilations", NULL, CFGF_NONE),
|
||||||
|
CFG_STR("compilation_artist", NULL, CFGF_NONE),
|
||||||
CFG_STR_LIST("artwork_basenames", "{artwork,cover,Folder}", CFGF_NONE),
|
CFG_STR_LIST("artwork_basenames", "{artwork,cover,Folder}", CFGF_NONE),
|
||||||
CFG_STR_LIST("filetypes_ignore", "{.db,.ini}", CFGF_NONE),
|
CFG_STR_LIST("filetypes_ignore", "{.db,.ini}", CFGF_NONE),
|
||||||
CFG_BOOL("itunes_overrides", cfg_false, CFGF_NONE),
|
CFG_BOOL("itunes_overrides", cfg_false, CFGF_NONE),
|
||||||
|
@ -35,6 +35,7 @@ struct dmap_query_field_map;
|
|||||||
"daap.songtime", "f.song_length", 1
|
"daap.songtime", "f.song_length", 1
|
||||||
"daap.songtrackcount", "f.total_tracks", 1
|
"daap.songtrackcount", "f.total_tracks", 1
|
||||||
"daap.songtracknumber", "f.track", 1
|
"daap.songtracknumber", "f.track", 1
|
||||||
|
"daap.songuserplaycount", "f.play_count", 1
|
||||||
"daap.songyear", "f.year", 1
|
"daap.songyear", "f.year", 1
|
||||||
"com.apple.itunes.mediakind", "f.media_kind", 1
|
"com.apple.itunes.mediakind", "f.media_kind", 1
|
||||||
"com.apple.itunes.extended-media-kind", "f.media_kind", 1
|
"com.apple.itunes.extended-media-kind", "f.media_kind", 1
|
||||||
|
6
src/db.c
6
src/db.c
@ -4122,9 +4122,12 @@ db_perthread_deinit(void)
|
|||||||
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
" VALUES(4, 'TV Shows', 1, 'f.media_kind = 64', 0, '', 0, 5);"
|
" VALUES(4, 'TV Shows', 1, 'f.media_kind = 64', 0, '', 0, 5);"
|
||||||
|
|
||||||
|
#define Q_PL5 \
|
||||||
|
"INSERT INTO playlists (id, title, type, query, db_timestamp, path, idx, special_id)" \
|
||||||
|
" VALUES(5, 'Podcasts', 1, 'f.media_kind = 4', 0, '', 0, 1);"
|
||||||
|
|
||||||
/* These are the remaining automatically-created iTunes playlists, but
|
/* These are the remaining automatically-created iTunes playlists, but
|
||||||
* their query is unknown
|
* their query is unknown
|
||||||
" VALUES(5, 'Podcasts', 0, 'media_kind = 128 ', 0, '', 0, 1);"
|
|
||||||
" VALUES(6, 'iTunes U', 0, 'media_kind = 256', 0, '', 0, 13);"
|
" VALUES(6, 'iTunes U', 0, 'media_kind = 256', 0, '', 0, 13);"
|
||||||
" VALUES(7, 'Audiobooks', 0, 'media_kind = 512', 0, '', 0, 7);"
|
" VALUES(7, 'Audiobooks', 0, 'media_kind = 512', 0, '', 0, 7);"
|
||||||
" VALUES(8, 'Purchased', 0, 'media_kind = 1024', 0, '', 0, 8);"
|
" VALUES(8, 'Purchased', 0, 'media_kind = 1024', 0, '', 0, 8);"
|
||||||
@ -4177,6 +4180,7 @@ static const struct db_init_query db_init_queries[] =
|
|||||||
{ Q_PL2, "create default smart playlist 'Music'" },
|
{ Q_PL2, "create default smart playlist 'Music'" },
|
||||||
{ Q_PL3, "create default smart playlist 'Movies'" },
|
{ Q_PL3, "create default smart playlist 'Movies'" },
|
||||||
{ Q_PL4, "create default smart playlist 'TV Shows'" },
|
{ Q_PL4, "create default smart playlist 'TV Shows'" },
|
||||||
|
{ Q_PL5, "create default smart playlist 'Podcasts'" },
|
||||||
|
|
||||||
{ Q_SCVER, "set schema version" },
|
{ Q_SCVER, "set schema version" },
|
||||||
};
|
};
|
||||||
|
@ -79,6 +79,7 @@ static const struct dmap_field_map dfm_dmap_aseq = { -1,
|
|||||||
static const struct dmap_field_map dfm_dmap_asfm = { dbmfi_offsetof(type), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_asfm = { dbmfi_offsetof(type), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_asgn = { dbmfi_offsetof(genre), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_asgn = { dbmfi_offsetof(genre), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_asdt = { dbmfi_offsetof(description), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_asdt = { dbmfi_offsetof(description), -1, -1 };
|
||||||
|
static const struct dmap_field_map dfm_dmap_aspc = { dbmfi_offsetof(play_count), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_asrv = { -1, -1, -1 };
|
static const struct dmap_field_map dfm_dmap_asrv = { -1, -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_assr = { dbmfi_offsetof(samplerate), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_assr = { dbmfi_offsetof(samplerate), -1, -1 };
|
||||||
static const struct dmap_field_map dfm_dmap_assz = { dbmfi_offsetof(file_size), -1, -1 };
|
static const struct dmap_field_map dfm_dmap_assz = { dbmfi_offsetof(file_size), -1, -1 };
|
||||||
@ -198,6 +199,7 @@ struct dmap_field;
|
|||||||
"daap.songgenre", "asgn", &dfm_dmap_asgn, DMAP_TYPE_STRING
|
"daap.songgenre", "asgn", &dfm_dmap_asgn, DMAP_TYPE_STRING
|
||||||
"daap.songkeywords", "asky", &dfm_dmap_asky, DMAP_TYPE_STRING
|
"daap.songkeywords", "asky", &dfm_dmap_asky, DMAP_TYPE_STRING
|
||||||
"daap.songlongcontentdescription", "aslc", &dfm_dmap_aslc, DMAP_TYPE_STRING
|
"daap.songlongcontentdescription", "aslc", &dfm_dmap_aslc, DMAP_TYPE_STRING
|
||||||
|
"daap.songuserplaycount", "aspc", &dfm_dmap_aspc, DMAP_TYPE_UINT
|
||||||
"daap.songrelativevolume", "asrv", &dfm_dmap_asrv, DMAP_TYPE_BYTE
|
"daap.songrelativevolume", "asrv", &dfm_dmap_asrv, DMAP_TYPE_BYTE
|
||||||
"daap.sortartist", "assa", &dfm_dmap_assa, DMAP_TYPE_STRING
|
"daap.sortartist", "assa", &dfm_dmap_assa, DMAP_TYPE_STRING
|
||||||
"daap.sortcomposer", "assc", &dfm_dmap_assc, DMAP_TYPE_STRING
|
"daap.sortcomposer", "assc", &dfm_dmap_assc, DMAP_TYPE_STRING
|
||||||
|
@ -174,9 +174,11 @@ normalize_fixup_tag(char **tag, char *src_tag)
|
|||||||
static void
|
static void
|
||||||
fixup_tags(struct media_file_info *mfi)
|
fixup_tags(struct media_file_info *mfi)
|
||||||
{
|
{
|
||||||
|
cfg_t *lib;
|
||||||
size_t len;
|
size_t len;
|
||||||
char *tag;
|
char *tag;
|
||||||
char *sep = " - ";
|
char *sep = " - ";
|
||||||
|
char *ca;
|
||||||
|
|
||||||
if (mfi->genre && (strlen(mfi->genre) == 0))
|
if (mfi->genre && (strlen(mfi->genre) == 0))
|
||||||
{
|
{
|
||||||
@ -290,16 +292,36 @@ fixup_tags(struct media_file_info *mfi)
|
|||||||
normalize_fixup_tag(&mfi->album_sort, mfi->album);
|
normalize_fixup_tag(&mfi->album_sort, mfi->album);
|
||||||
normalize_fixup_tag(&mfi->title_sort, mfi->title);
|
normalize_fixup_tag(&mfi->title_sort, mfi->title);
|
||||||
|
|
||||||
/* If we don't have an album_artist, set it to artist */
|
/* We need to set album_artist according to media type and config */
|
||||||
if (!mfi->album_artist)
|
if (mfi->compilation) /* Compilation */
|
||||||
{
|
{
|
||||||
if (mfi->compilation)
|
lib = cfg_getsec(cfg, "library");
|
||||||
|
ca = cfg_getstr(lib, "compilation_artist");
|
||||||
|
if (ca && mfi->album_artist)
|
||||||
|
{
|
||||||
|
free(mfi->album_artist);
|
||||||
|
mfi->album_artist = strdup(ca);
|
||||||
|
}
|
||||||
|
else if (ca && !mfi->album_artist)
|
||||||
|
{
|
||||||
|
mfi->album_artist = strdup(ca);
|
||||||
|
}
|
||||||
|
else if (!ca && !mfi->album_artist)
|
||||||
{
|
{
|
||||||
mfi->album_artist = strdup("");
|
mfi->album_artist = strdup("");
|
||||||
mfi->album_artist_sort = strdup("");
|
mfi->album_artist_sort = strdup("");
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
mfi->album_artist = strdup(mfi->artist);
|
else if (mfi->media_kind == 4) /* Podcast */
|
||||||
|
{
|
||||||
|
if (mfi->album_artist)
|
||||||
|
free(mfi->album_artist);
|
||||||
|
mfi->album_artist = strdup("");
|
||||||
|
mfi->album_artist_sort = strdup("");
|
||||||
|
}
|
||||||
|
else if (!mfi->album_artist) /* Regular media without album_artist */
|
||||||
|
{
|
||||||
|
mfi->album_artist = strdup(mfi->artist);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mfi->album_artist_sort && (strcmp(mfi->album_artist, mfi->artist) == 0))
|
if (!mfi->album_artist_sort && (strcmp(mfi->album_artist, mfi->artist) == 0))
|
||||||
@ -314,7 +336,7 @@ fixup_tags(struct media_file_info *mfi)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
process_media_file(char *file, time_t mtime, off_t size, int compilation, int url, struct extinf_ctx *extinf)
|
process_media_file(char *file, time_t mtime, off_t size, int type, struct extinf_ctx *extinf)
|
||||||
{
|
{
|
||||||
struct media_file_info mfi;
|
struct media_file_info mfi;
|
||||||
char *filename;
|
char *filename;
|
||||||
@ -391,7 +413,7 @@ process_media_file(char *file, time_t mtime, off_t size, int compilation, int ur
|
|||||||
mfi.time_modified = mtime;
|
mfi.time_modified = mtime;
|
||||||
mfi.file_size = size;
|
mfi.file_size = size;
|
||||||
|
|
||||||
if (!url)
|
if (!(type & F_SCAN_TYPE_URL))
|
||||||
{
|
{
|
||||||
mfi.data_kind = 0; /* real file */
|
mfi.data_kind = 0; /* real file */
|
||||||
ret = scan_metadata_ffmpeg(file, &mfi);
|
ret = scan_metadata_ffmpeg(file, &mfi);
|
||||||
@ -415,7 +437,10 @@ process_media_file(char *file, time_t mtime, off_t size, int compilation, int ur
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mfi.compilation = compilation;
|
if (type & F_SCAN_TYPE_COMPILATION)
|
||||||
|
mfi.compilation = 1;
|
||||||
|
if (type & F_SCAN_TYPE_PODCAST)
|
||||||
|
mfi.media_kind = 4; /* podcast */
|
||||||
|
|
||||||
if (!mfi.item_kind)
|
if (!mfi.item_kind)
|
||||||
mfi.item_kind = 2; /* music */
|
mfi.item_kind = 2; /* music */
|
||||||
@ -509,7 +534,7 @@ process_deferred_playlists(void)
|
|||||||
|
|
||||||
/* Thread: scan */
|
/* Thread: scan */
|
||||||
static void
|
static void
|
||||||
process_file(char *file, time_t mtime, off_t size, int compilation, int flags)
|
process_file(char *file, time_t mtime, off_t size, int type, int flags)
|
||||||
{
|
{
|
||||||
char *ext;
|
char *ext;
|
||||||
|
|
||||||
@ -538,9 +563,28 @@ process_file(char *file, time_t mtime, off_t size, int compilation, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Not any kind of special file, so let's see if it's a media file */
|
/* Not any kind of special file, so let's see if it's a media file */
|
||||||
process_media_file(file, mtime, size, compilation, 0, NULL);
|
process_media_file(file, mtime, size, type, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Thread: scan */
|
||||||
|
static int
|
||||||
|
check_podcast(char *path)
|
||||||
|
{
|
||||||
|
cfg_t *lib;
|
||||||
|
int ndirs;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
lib = cfg_getsec(cfg, "library");
|
||||||
|
ndirs = cfg_size(lib, "podcasts");
|
||||||
|
|
||||||
|
for (i = 0; i < ndirs; i++)
|
||||||
|
{
|
||||||
|
if (strstr(path, cfg_getnstr(lib, "podcasts", i)))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Thread: scan */
|
/* Thread: scan */
|
||||||
static int
|
static int
|
||||||
@ -577,7 +621,7 @@ process_directory(char *path, int flags)
|
|||||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
struct kevent kev;
|
struct kevent kev;
|
||||||
#endif
|
#endif
|
||||||
int compilation;
|
int type;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (flags & F_SCAN_BULK)
|
if (flags & F_SCAN_BULK)
|
||||||
@ -608,8 +652,12 @@ process_directory(char *path, int flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a compilation directory */
|
/* Check if compilation and/or podcast directory */
|
||||||
compilation = check_compilation(path);
|
type = 0;
|
||||||
|
if (check_compilation(path))
|
||||||
|
type |= F_SCAN_TYPE_COMPILATION;
|
||||||
|
if (check_podcast(path))
|
||||||
|
type |= F_SCAN_TYPE_PODCAST;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -673,7 +721,7 @@ process_directory(char *path, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISREG(sb.st_mode))
|
if (S_ISREG(sb.st_mode))
|
||||||
process_file(entry, sb.st_mtime, sb.st_size, compilation, flags);
|
process_file(entry, sb.st_mtime, sb.st_size, type, flags);
|
||||||
else if (S_ISDIR(sb.st_mode))
|
else if (S_ISDIR(sb.st_mode))
|
||||||
push_dir(&dirstack, entry);
|
push_dir(&dirstack, entry);
|
||||||
else
|
else
|
||||||
@ -986,7 +1034,7 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
|
|||||||
struct stat sb;
|
struct stat sb;
|
||||||
char *deref = NULL;
|
char *deref = NULL;
|
||||||
char *file = path;
|
char *file = path;
|
||||||
int compilation;
|
int type;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_SCAN, "File event: 0x%x, cookie 0x%x, wd %d\n", ie->mask, ie->cookie, wi->wd);
|
DPRINTF(E_DBG, L_SCAN, "File event: 0x%x, cookie 0x%x, wd %d\n", ie->mask, ie->cookie, wi->wd);
|
||||||
@ -1059,9 +1107,13 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compilation = check_compilation(path);
|
type = 0;
|
||||||
|
if (check_compilation(path))
|
||||||
|
type |= F_SCAN_TYPE_COMPILATION;
|
||||||
|
if (check_podcast(path))
|
||||||
|
type |= F_SCAN_TYPE_PODCAST;
|
||||||
|
|
||||||
process_file(file, sb.st_mtime, sb.st_size, compilation, 0);
|
process_file(file, sb.st_mtime, sb.st_size, type, 0);
|
||||||
|
|
||||||
if (deref)
|
if (deref)
|
||||||
free(deref);
|
free(deref);
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
|
||||||
|
#define F_SCAN_TYPE_PODCAST (1 << 0)
|
||||||
|
#define F_SCAN_TYPE_COMPILATION (1 << 1)
|
||||||
|
#define F_SCAN_TYPE_URL (1 << 2)
|
||||||
|
|
||||||
int
|
int
|
||||||
filescanner_init(void);
|
filescanner_init(void);
|
||||||
|
|
||||||
@ -18,7 +22,7 @@ struct extinf_ctx
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
process_media_file(char *file, time_t mtime, off_t size, int compilation, int url, struct extinf_ctx *extinf);
|
process_media_file(char *file, time_t mtime, off_t size, int type, struct extinf_ctx *extinf);
|
||||||
|
|
||||||
/* Actual scanners */
|
/* Actual scanners */
|
||||||
int
|
int
|
||||||
|
@ -419,6 +419,13 @@ process_track_file(plist_t trk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set media_kind to 4 (Podcast) if Podcast is true */
|
||||||
|
ret = get_dictval_bool_from_key(trk, "Podcast", &boolean);
|
||||||
|
if ((ret == 0) && boolean)
|
||||||
|
{
|
||||||
|
mfi->media_kind = 4;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't let album_artist set to "Unknown artist" if we've
|
/* Don't let album_artist set to "Unknown artist" if we've
|
||||||
* filled artist from the iTunes data in the meantime
|
* filled artist from the iTunes data in the meantime
|
||||||
*/
|
*/
|
||||||
|
@ -212,7 +212,7 @@ scan_m3u_playlist(char *file, time_t mtime)
|
|||||||
if (extinf.found)
|
if (extinf.found)
|
||||||
DPRINTF(E_INFO, L_SCAN, "Playlist has EXTINF metadata, artist is '%s', title is '%s'\n", extinf.artist, extinf.title);
|
DPRINTF(E_INFO, L_SCAN, "Playlist has EXTINF metadata, artist is '%s', title is '%s'\n", extinf.artist, extinf.title);
|
||||||
|
|
||||||
process_media_file(filename, mtime, 0, 0, 1, &extinf);
|
process_media_file(filename, mtime, 0, F_SCAN_TYPE_URL, &extinf);
|
||||||
}
|
}
|
||||||
/* Regular file */
|
/* Regular file */
|
||||||
else
|
else
|
||||||
|
@ -841,7 +841,9 @@ dacp_reply_playspec(struct evhttp_request *req, struct evbuffer *evbuf, char **u
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* /ctrl-int/1/playspec?database-spec='dmap.persistentid:0x1'&container-spec='dmap.persistentid:0x5'&container-item-spec='dmap.containeritemid:0x9'
|
/* /ctrl-int/1/playspec?database-spec='dmap.persistentid:0x1'&container-spec='dmap.persistentid:0x5'&container-item-spec='dmap.containeritemid:0x9'
|
||||||
* With our DAAP implementation, container-spec is the playlist ID and container-item-spec is the song ID
|
* or (Apple Remote when playing a Podcast)
|
||||||
|
* /ctrl-int/1/playspec?database-spec='dmap.persistentid:0x1'&container-spec='dmap.persistentid:0x5'&item-spec='dmap.itemid:0x9'
|
||||||
|
* With our DAAP implementation, container-spec is the playlist ID and container-item-spec/item-spec is the song ID
|
||||||
*/
|
*/
|
||||||
|
|
||||||
s = daap_session_find(req, query, evbuf);
|
s = daap_session_find(req, query, evbuf);
|
||||||
@ -881,9 +883,11 @@ dacp_reply_playspec(struct evhttp_request *req, struct evbuffer *evbuf, char **u
|
|||||||
{
|
{
|
||||||
/* Start song ID */
|
/* Start song ID */
|
||||||
param = evhttp_find_header(query, "container-item-spec");
|
param = evhttp_find_header(query, "container-item-spec");
|
||||||
|
if (!param)
|
||||||
|
param = evhttp_find_header(query, "item-spec");
|
||||||
if (!param)
|
if (!param)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DACP, "No container-item-spec in playspec request\n");
|
DPRINTF(E_LOG, L_DACP, "No container-item-spec/item-spec in playspec request\n");
|
||||||
|
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
}
|
}
|
||||||
@ -891,7 +895,7 @@ dacp_reply_playspec(struct evhttp_request *req, struct evbuffer *evbuf, char **u
|
|||||||
param = strchr(param, ':');
|
param = strchr(param, ':');
|
||||||
if (!param)
|
if (!param)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DACP, "Malformed container-item-spec parameter in playspec request\n");
|
DPRINTF(E_LOG, L_DACP, "Malformed container-item-spec/item-spec parameter in playspec request\n");
|
||||||
|
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
}
|
}
|
||||||
@ -900,7 +904,7 @@ dacp_reply_playspec(struct evhttp_request *req, struct evbuffer *evbuf, char **u
|
|||||||
ret = safe_hextou32(param, &id);
|
ret = safe_hextou32(param, &id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DACP, "Couldn't convert container-item-spec to an integer in playspec (%s)\n", param);
|
DPRINTF(E_LOG, L_DACP, "Couldn't convert container-item-spec/item-spec to an integer in playspec (%s)\n", param);
|
||||||
|
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
}
|
}
|
||||||
|
@ -1148,6 +1148,8 @@ source_check(void)
|
|||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
db_file_inc_playcount((int)cur_playing->id);
|
||||||
|
|
||||||
/* Stop playback if:
|
/* Stop playback if:
|
||||||
* - at end of playlist (NULL)
|
* - at end of playlist (NULL)
|
||||||
* - repeat OFF and at end of playlist (wraparound)
|
* - repeat OFF and at end of playlist (wraparound)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user