[scan] option to use first genre on multi token genres

multiple genres are either supported by format (see flac/orbis) or are
handled by convention (see mp3) - ffmpeg presents either case as a
single string, seperated by ';' (ie "Pop;Rock")

Currently the server/db does not support multiple genres and will store
the ffmpeg string as-is which is unlikely the user intention.

Introduce 'split_genre' to take the first genre token
This commit is contained in:
whatdoineed2do/Ray 2022-12-27 13:42:07 +00:00
parent c23c2fdc45
commit 9a3cb3b79c
3 changed files with 27 additions and 1 deletions

View File

@ -171,6 +171,12 @@ library {
# to trigger a rescan. # to trigger a rescan.
# filescan_disable = false # filescan_disable = false
# Should server use first genre found in metadata
# Tracks may be tagged with multiple genres, such as 'Pop' and 'Rock'.
# This option instructs the server to use only the first genre found
# (ie 'Pop' in this case) when parsing genre
# split_genre = false
# Should metadata from m3u playlists, e.g. artist and title in EXTINF, # Should metadata from m3u playlists, e.g. artist and title in EXTINF,
# override the metadata we get from radio streams? # override the metadata we get from radio streams?
# m3u_overrides = false # m3u_overrides = false

View File

@ -118,6 +118,7 @@ static cfg_opt_t sec_library[] =
CFG_BOOL("allow_modifying_stored_playlists", cfg_false, CFGF_NONE), CFG_BOOL("allow_modifying_stored_playlists", cfg_false, CFGF_NONE),
CFG_STR("default_playlist_directory", NULL, CFGF_NONE), CFG_STR("default_playlist_directory", NULL, CFGF_NONE),
CFG_BOOL("clear_queue_on_stop_disable", cfg_false, CFGF_NONE), CFG_BOOL("clear_queue_on_stop_disable", cfg_false, CFGF_NONE),
CFG_BOOL("split_genre", cfg_false, CFGF_NONE),
CFG_END() CFG_END()
}; };

View File

@ -35,6 +35,7 @@
#include "logger.h" #include "logger.h"
#include "misc.h" #include "misc.h"
#include "http.h" #include "http.h"
#include "conffile.h"
/* Mapping between the metadata name(s) and the offset /* Mapping between the metadata name(s) and the offset
* of the equivalent metadata field in struct media_file_info */ * of the equivalent metadata field in struct media_file_info */
@ -55,6 +56,24 @@ err2str(int errnum)
return errbuf; return errbuf;
} }
static int
parse_genre(struct media_file_info *mfi, char *genre_string)
{
char **genre = (char**)((char *) mfi + mfi_offsetof(genre));
char *ptr;
*genre = strdup(genre_string);
if (cfg_getbool(cfg_getsec(cfg, "library"), "split_genre"))
{
ptr = strchr(*genre, ';');
if (ptr)
*ptr = '\0';
}
return 1;
}
static int static int
parse_slash_separated_ints(char *string, uint32_t *firstval, uint32_t *secondval) parse_slash_separated_ints(char *string, uint32_t *firstval, uint32_t *secondval)
{ {
@ -149,7 +168,7 @@ static const struct metadata_map md_map_generic[] =
{ "author", 0, mfi_offsetof(artist), NULL }, { "author", 0, mfi_offsetof(artist), NULL },
{ "album_artist", 0, mfi_offsetof(album_artist), NULL }, { "album_artist", 0, mfi_offsetof(album_artist), NULL },
{ "album", 0, mfi_offsetof(album), NULL }, { "album", 0, mfi_offsetof(album), NULL },
{ "genre", 0, mfi_offsetof(genre), NULL }, { "genre", 0, mfi_offsetof(genre), parse_genre },
{ "composer", 0, mfi_offsetof(composer), NULL }, { "composer", 0, mfi_offsetof(composer), NULL },
{ "grouping", 0, mfi_offsetof(grouping), NULL }, { "grouping", 0, mfi_offsetof(grouping), NULL },
{ "orchestra", 0, mfi_offsetof(orchestra), NULL }, { "orchestra", 0, mfi_offsetof(orchestra), NULL },