From 9a3cb3b79ccb1a3f39680d9b4fe194f31dca090f Mon Sep 17 00:00:00 2001 From: whatdoineed2do/Ray Date: Tue, 27 Dec 2022 13:42:07 +0000 Subject: [PATCH] [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 --- owntone.conf.in | 6 ++++++ src/conffile.c | 1 + src/library/filescanner_ffmpeg.c | 21 ++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/owntone.conf.in b/owntone.conf.in index 31b530fd..808aac11 100644 --- a/owntone.conf.in +++ b/owntone.conf.in @@ -171,6 +171,12 @@ library { # to trigger a rescan. # 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, # override the metadata we get from radio streams? # m3u_overrides = false diff --git a/src/conffile.c b/src/conffile.c index 59af0e5f..321d8bbc 100644 --- a/src/conffile.c +++ b/src/conffile.c @@ -118,6 +118,7 @@ static cfg_opt_t sec_library[] = CFG_BOOL("allow_modifying_stored_playlists", cfg_false, CFGF_NONE), CFG_STR("default_playlist_directory", NULL, CFGF_NONE), CFG_BOOL("clear_queue_on_stop_disable", cfg_false, CFGF_NONE), + CFG_BOOL("split_genre", cfg_false, CFGF_NONE), CFG_END() }; diff --git a/src/library/filescanner_ffmpeg.c b/src/library/filescanner_ffmpeg.c index 1f8577d1..595297a3 100644 --- a/src/library/filescanner_ffmpeg.c +++ b/src/library/filescanner_ffmpeg.c @@ -35,6 +35,7 @@ #include "logger.h" #include "misc.h" #include "http.h" +#include "conffile.h" /* Mapping between the metadata name(s) and the offset * of the equivalent metadata field in struct media_file_info */ @@ -55,6 +56,24 @@ err2str(int errnum) 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 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 }, { "album_artist", 0, mfi_offsetof(album_artist), 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 }, { "grouping", 0, mfi_offsetof(grouping), NULL }, { "orchestra", 0, mfi_offsetof(orchestra), NULL },