Generalized 'disc' to 'medium' in tag parser

This commit is contained in:
emeric
2023-03-07 17:11:36 +01:00
parent 3a9bde0092
commit 59eff32377
5 changed files with 113 additions and 104 deletions
+18 -14
View File
@@ -77,7 +77,7 @@ getRelease(const Av::IAudioFile::MetadataMap& metadataMap)
res.emplace();
res->name = *releaseName;
res->releaseMBID = findFirstValueOfAs<UUID>(metadataMap, {"MUSICBRAINZ ALBUM ID", "MUSICBRAINZ_ALBUMID", "MUSICBRAINZ/ALBUM ID"});
res->mbid = findFirstValueOfAs<UUID>(metadataMap, {"MUSICBRAINZ ALBUM ID", "MUSICBRAINZ_ALBUMID", "MUSICBRAINZ/ALBUM ID"});
return res;
}
@@ -149,20 +149,20 @@ AvFormatParser::parse(const std::filesystem::path& p, bool debug)
track.duration = mediaFile->getDuration();
track.hasCover = mediaFile->hasAttachedPictures();
MetaData::Clusters clusters;
MetaData::Tags tags;
const Av::IAudioFile::MetadataMap metadataMap {mediaFile->getMetaData()};
track.artists = getArtists(metadataMap);
track.release = getRelease(metadataMap);
if (track.release)
track.release->releaseArtists = getReleaseArtists(metadataMap);
track.release->artists = getReleaseArtists(metadataMap);
auto getOrCreateDisc = [&]() -> Disc&
auto getOrCreateMedium = [&]() -> Medium&
{
if (!track.disc)
track.disc.emplace();
return *track.disc;
if (!track.medium)
track.medium.emplace();
return *track.medium;
};
for (const auto& [tag, value] : metadataMap)
@@ -178,10 +178,10 @@ AvFormatParser::parse(const std::filesystem::path& p, bool debug)
const std::vector<std::string_view> strings {StringUtils::splitString(value, "/") };
if (strings.size() > 0)
{
track.trackNumber = StringUtils::readAs<std::size_t>(strings[0]);
track.position = StringUtils::readAs<std::size_t>(strings[0]);
if (strings.size() > 1)
getOrCreateDisc().totalTrack = StringUtils::readAs<std::size_t>(strings[1]);
getOrCreateMedium().trackCount = StringUtils::readAs<std::size_t>(strings[1]);
}
}
else if (tag == "DISC")
@@ -190,10 +190,10 @@ AvFormatParser::parse(const std::filesystem::path& p, bool debug)
const std::vector<std::string_view> strings {StringUtils::splitString(value, "/")};
if (strings.size() > 0)
{
track.discNumber = StringUtils::readAs<std::size_t>(strings[0]);
getOrCreateMedium().position = StringUtils::readAs<std::size_t>(strings[0]);
if (strings.size() > 1 && track.release)
track.release->totalDisc = StringUtils::readAs<std::size_t>(strings[1]);
track.release->mediumCount = StringUtils::readAs<std::size_t>(strings[1]);
}
}
else if (tag == "DATE"
@@ -214,18 +214,22 @@ AvFormatParser::parse(const std::filesystem::path& p, bool debug)
else if (tag == "MUSICBRAINZ RELEASE TRACK ID"
|| tag == "MUSICBRAINZ_RELEASETRACKID")
{
track.trackMBID = UUID::fromString(value);
track.mbid = UUID::fromString(value);
}
else if (tag == "MUSICBRAINZ_TRACKID"
|| tag == "MUSICBRAINZ/TRACK ID")
{
track.recordingMBID = UUID::fromString(value);
}
else if (tag == "MEDIA")
{
getOrCreateMedium().type = value;
}
else if (tag == "TSST"
|| tag == "DISCSUBTITLE"
|| tag == "SETSUBTITLE")
{
getOrCreateDisc().subtitle = value;
getOrCreateMedium().name = value;
}
else if (_clusterTypeNames.find(tag) != _clusterTypeNames.end())
{
@@ -237,7 +241,7 @@ AvFormatParser::parse(const std::filesystem::path& p, bool debug)
std::transform(std::cbegin(clusterNames), std::cend(clusterNames),
std::inserter(values, std::begin(values)),
[](std::string_view clusterName) { return std::string {clusterName}; });
track.clusters[tag] = std::move(values);
track.tags[tag] = std::move(values);
}
}
}
+22 -21
View File
@@ -131,7 +131,7 @@ getArtists(const TagMap& tags,
if (artistNames.size() == artistsMBID.size())
{
for (std::size_t i {}; i < artistsMBID.size(); ++i)
artists[i].artistMBID = artistsMBID[i];
artists[i].mbid = artistsMBID[i];
}
}
@@ -194,7 +194,7 @@ getRelease(const TagMap& tags)
release.emplace();
release->name = std::move(releaseName.front());
if (!releaseMBID.empty())
release->releaseMBID = releaseMBID.front();
release->mbid = releaseMBID.front();
return release;
}
@@ -227,11 +227,11 @@ TagLibParser::processTag(Track& track, const std::string& tag, const std::vector
if (tag.empty() || values.empty())
return;
auto getOrCreateDisc = [&]() -> Disc&
auto getOrCreateMedium = [&]() -> Medium&
{
if (!track.disc)
track.disc.emplace();
return *track.disc;
if (!track.medium)
track.medium.emplace();
return *track.medium;
};
std::string_view value {values.front()};
@@ -242,7 +242,7 @@ TagLibParser::processTag(Track& track, const std::string& tag, const std::vector
|| tag == "MUSICBRAINZ RELEASE TRACK ID"
|| tag == "MUSICBRAINZ/RELEASE TRACK ID")
{
track.trackMBID = UUID::fromString(value);
track.mbid = UUID::fromString(value);
}
else if (tag == "MUSICBRAINZ_TRACKID"
|| tag == "MUSICBRAINZ TRACK ID"
@@ -252,7 +252,7 @@ TagLibParser::processTag(Track& track, const std::string& tag, const std::vector
track.acoustID = UUID::fromString(value);
else if (tag == "TRACKTOTAL")
{
getOrCreateDisc().totalTrack = StringUtils::readAs<std::size_t>(value);
getOrCreateMedium().trackCount = StringUtils::readAs<std::size_t>(value);
}
else if (tag == "TRACKNUMBER")
{
@@ -261,17 +261,17 @@ TagLibParser::processTag(Track& track, const std::string& tag, const std::vector
if (!strings.empty())
{
track.trackNumber = StringUtils::readAs<std::size_t>(strings[0]);
track.position = StringUtils::readAs<std::size_t>(strings[0]);
// Lower priority than TRACKTOTAL
if (strings.size() > 1 && !getOrCreateDisc().totalTrack)
getOrCreateDisc().totalTrack = StringUtils::readAs<std::size_t>(strings[1]);
if (strings.size() > 1 && !getOrCreateMedium().trackCount)
getOrCreateMedium().trackCount = StringUtils::readAs<std::size_t>(strings[1]);
}
}
else if (tag == "DISCTOTAL")
{
if (track.release)
track.release->totalDisc = StringUtils::readAs<std::size_t>(value);
track.release->mediumCount = StringUtils::readAs<std::size_t>(value);
}
else if (tag == "DISCNUMBER")
{
@@ -279,11 +279,11 @@ TagLibParser::processTag(Track& track, const std::string& tag, const std::vector
std::vector<std::string_view> strings {StringUtils::splitString(value, "/")};
if (!strings.empty())
{
track.discNumber = StringUtils::readAs<std::size_t>(strings[0]);
getOrCreateMedium().position = StringUtils::readAs<std::size_t>(strings[0]);
// Lower priority than DISCTOTAL
if (strings.size() > 1 && track.release && !track.release->totalDisc)
track.release->totalDisc = StringUtils::readAs<std::size_t>(strings[1]);
if (strings.size() > 1 && track.release && !track.release->mediumCount)
track.release->mediumCount = StringUtils::readAs<std::size_t>(strings[1]);
}
}
else if (tag == "DATE")
@@ -315,24 +315,25 @@ TagLibParser::processTag(Track& track, const std::string& tag, const std::vector
else if (tag == "COPYRIGHTURL")
track.copyrightURL = value;
else if (tag == "REPLAYGAIN_ALBUM_GAIN")
getOrCreateDisc().replayGain = StringUtils::readAs<float>(value);
getOrCreateMedium().replayGain = StringUtils::readAs<float>(value);
else if (tag == "REPLAYGAIN_TRACK_GAIN")
track.replayGain = StringUtils::readAs<float>(value);
else if (tag == "DISCSUBTITLE" || tag == "SETSUBTITLE")
getOrCreateDisc().subtitle = value;
getOrCreateMedium().name = value;
else if (tag == "MEDIA")
getOrCreateMedium().type = value;
else if (_clusterTypeNames.find(tag) != _clusterTypeNames.end())
{
std::set<std::string> clusterNames;
for (const auto& valueList : values)
for (std::string_view valueList : values)
{
const std::vector<std::string_view> splittedValues {splitAndTrimString(valueList, "/,;")};
for (std::string_view value : splittedValues)
clusterNames.insert(std::string {value});
}
if (!clusterNames.empty())
track.clusters[tag] = clusterNames;
track.tags[tag] = std::move(clusterNames);
}
}
@@ -493,7 +494,7 @@ TagLibParser::parse(const std::filesystem::path& p, bool debug)
track.release = getRelease(tags);
if (track.release)
track.release->releaseArtists = getArtists(tags, {"ALBUMARTISTS", "ALBUMARTIST"}, {"ALBUMARTISTSSORT", "ALBUMARTISTSORT"}, {"MUSICBRAINZ_ALBUMARTISTID", "MUSICBRAINZ ALBUM ARTIST ID", "MUSICBRAINZ/ALBUM ARTIST ID"});
track.release->artists = getArtists(tags, {"ALBUMARTISTS", "ALBUMARTIST"}, {"ALBUMARTISTSSORT", "ALBUMARTISTSORT"}, {"MUSICBRAINZ_ALBUMARTISTID", "MUSICBRAINZ ALBUM ARTIST ID", "MUSICBRAINZ/ALBUM ARTIST ID"});
track.artists = getArtists(tags, {"ARTISTS", "ARTIST"}, {"ARTISTSORT"}, {"MUSICBRAINZ_ARTISTID", "MUSICBRAINZ ARTIST ID", "MUSICBRAINZ/ARTIST ID"});
track.conductorArtists = getArtists(tags, {"CONDUCTORS", "CONDUCTOR"}, {"CONDUCTORSSORT", "CONDUCTORSORT"}, {});
track.composerArtists = getArtists(tags, {"COMPOSERS", "COMPOSER"}, {"COMPOSERSSORT", "COMPOSERSORT"}, {});
+17 -16
View File
@@ -33,16 +33,16 @@
namespace MetaData
{
using Clusters = std::map<std::string /* type */, std::set<std::string> /* names */>;
using Tags = std::map<std::string /* type */, std::set<std::string> /* names */>;
struct Artist
{
std::string name;
std::optional<std::string> sortName;
std::optional<UUID> artistMBID;
std::string name;
std::optional<std::string> sortName;
std::optional<UUID> mbid;
Artist(std::string_view _name) : name {_name} {}
Artist(std::string_view _name, std::optional<std::string> _sortName, std::optional<UUID> _artistMBID) : name {_name}, sortName {std::move(_sortName)}, artistMBID {std::move(_artistMBID)} {}
Artist(std::string_view _name, std::optional<std::string> _sortName, std::optional<UUID> _mbid) : name {_name}, sortName {std::move(_sortName)}, mbid {std::move(_mbid)} {}
};
using PerformerContainer = std::map<std::string /*role*/, std::vector<Artist>>;
@@ -50,16 +50,18 @@ namespace MetaData
struct Release
{
std::string name;
std::vector<Artist> releaseArtists;
std::optional<UUID> releaseMBID;
std::optional<std::size_t> totalDisc;
std::vector<Artist> artists;
std::optional<UUID> mbid;
std::optional<std::size_t> mediumCount;
};
struct Disc
struct Medium
{
std::string subtitle;
std::optional<std::size_t> position;
std::string type;
std::string name;
std::optional<float> replayGain;
std::optional<std::size_t> totalTrack;
std::optional<std::size_t> trackCount;
};
struct AudioStream
@@ -71,14 +73,13 @@ namespace MetaData
{
std::vector<Artist> artists;
std::string title;
std::optional<UUID> trackMBID;
std::optional<UUID> mbid;
std::optional<UUID> recordingMBID;
std::optional<Release> release;
std::optional<Disc> disc;
Clusters clusters;
std::optional<Medium> medium;
Tags tags;
std::chrono::milliseconds duration;
std::optional<std::size_t> trackNumber;
std::optional<std::size_t> discNumber;
std::optional<std::size_t> position; // in medium
Wt::WDate date;
Wt::WDate originalDate;
bool hasCover {};