WIP
This commit is contained in:
@@ -72,7 +72,20 @@ AvFormat::parse(const boost::filesystem::path& p, bool debug)
|
||||
std::cout << "TAG = " << tag << ", VAL = " << value << std::endl;
|
||||
|
||||
if (tag == "ARTIST")
|
||||
items.insert( std::make_pair(MetaData::Type::Artist, stringTrim( value) ));
|
||||
{
|
||||
if (items.find(MetaData::Type::Artists) == items.end())
|
||||
items[MetaData::Type::Artists] = std::set<std::string>{ stringTrim( value) };
|
||||
}
|
||||
else if (tag == "ARTISTS")
|
||||
{
|
||||
std::vector<std::string> strings {splitString(value, "/;")}; // Picard separator is '/'
|
||||
|
||||
std::set<std::string> artists;
|
||||
for (const std::string& string : strings)
|
||||
artists.insert(stringTrim(string));
|
||||
|
||||
items[MetaData::Type::Artists] = std::move(artists);
|
||||
}
|
||||
else if (tag == "ALBUM")
|
||||
items.insert( std::make_pair(MetaData::Type::Album, stringTrim( value) ));
|
||||
else if (tag == "TITLE")
|
||||
@@ -133,7 +146,13 @@ AvFormat::parse(const boost::filesystem::path& p, bool debug)
|
||||
else if (tag == "MUSICBRAINZ ARTIST ID"
|
||||
|| tag == "MUSICBRAINZ_ARTISTID")
|
||||
{
|
||||
items.insert( std::make_pair(MetaData::Type::MusicBrainzArtistID, stringTrim(value)) );
|
||||
std::vector<std::string> strings {splitString(value, "/")};
|
||||
|
||||
std::set<std::string> mbids;
|
||||
for (const std::string& string : strings)
|
||||
mbids.insert(stringTrim(string));
|
||||
|
||||
items[MetaData::Type::MusicBrainzArtistID] = std::move(mbids);
|
||||
}
|
||||
else if (tag == "MUSICBRAINZ ALBUM ID"
|
||||
|| tag == "MUSICBRAINZ_ALBUMID")
|
||||
@@ -152,7 +171,7 @@ AvFormat::parse(const boost::filesystem::path& p, bool debug)
|
||||
}
|
||||
else if (_clusterTypeNames.find(tag) != _clusterTypeNames.end())
|
||||
{
|
||||
std::vector<std::string> clusterNames = splitString(value, ";,\\");
|
||||
std::vector<std::string> clusterNames = splitString(value, "/,;");
|
||||
|
||||
if (!clusterNames.empty())
|
||||
{
|
||||
@@ -167,7 +186,7 @@ AvFormat::parse(const boost::filesystem::path& p, bool debug)
|
||||
}
|
||||
catch(Av::MediaFileException& e)
|
||||
{
|
||||
return items;
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
return items;
|
||||
|
||||
+34
-31
@@ -22,54 +22,57 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace MetaData
|
||||
{
|
||||
using Clusters = std::map<std::string /* type */, std::set<std::string> /* names */>;
|
||||
|
||||
enum class Type
|
||||
struct Artist
|
||||
{
|
||||
// Name Type of the value
|
||||
Artist, // string
|
||||
Title, // string
|
||||
Album, // string
|
||||
Clusters, // Clusters, ex: { "genre", {"death metal", "brutal death"} }, { "albumgrouping", {"metal"} }
|
||||
Duration, // std::chrono::milliseconds
|
||||
TrackNumber, // size_t
|
||||
DiscNumber, // size_t
|
||||
TotalTrack, // size_t
|
||||
TotalDisc, // size_t
|
||||
Year, // int
|
||||
OriginalYear, // int
|
||||
HasCover, // bool
|
||||
AudioStreams, // vector<AudioStream>
|
||||
MusicBrainzArtistID, // string
|
||||
MusicBrainzAlbumID, // string
|
||||
MusicBrainzTrackID, // string
|
||||
MusicBrainzRecordingID, // string
|
||||
AcoustID, // string
|
||||
Copyright, // string
|
||||
CopyrightURL, // string
|
||||
std::string name;
|
||||
std::string musicBrainzArtistID;
|
||||
};
|
||||
|
||||
// Used by Streams
|
||||
struct Album
|
||||
{
|
||||
std::string name;
|
||||
std::string musicBrainzAlbumID;
|
||||
}
|
||||
|
||||
struct AudioStream
|
||||
{
|
||||
// TODO codec?
|
||||
std::size_t bitRate;
|
||||
unsigned bitRate;
|
||||
};
|
||||
|
||||
// Type and associated data
|
||||
// See enum Type's comments
|
||||
using Items = std::map<Type, boost::any>;
|
||||
using Clusters = std::map<std::string /* type */, std::set<std::string> /* names */>;
|
||||
struct Track
|
||||
{
|
||||
std::vector<Artist> artists;
|
||||
boost::optional<Artist> albumArtist;
|
||||
std::string title;
|
||||
std::string musicBrainzTrackID;
|
||||
std::string musicBrainzRecordID;
|
||||
boost::optional<Album> album;
|
||||
Clusters clusters;
|
||||
std::chrono::milliseconds duration {};
|
||||
boost::optional<std::size_t> trackNumber;
|
||||
boost::optional<std::size_t> totalTrack;
|
||||
boost::optional<std::size_t> discNumber;
|
||||
boost::optional<std::size_t> totalDisc;
|
||||
boost::optional<int> year;
|
||||
boost::optional<int> originalYear;
|
||||
bool hasCover {false};
|
||||
std::vector<AudioStream> audioStreams;
|
||||
std::string acoustId;
|
||||
std::string copyright;
|
||||
std::string copyrightURL;
|
||||
};
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
virtual boost::optional<Items> parse(const boost::filesystem::path& p, bool debug = false) = 0;
|
||||
virtual boost::optional<Track> parse(const boost::filesystem::path& p, bool debug = false) = 0;
|
||||
|
||||
void setClusterTypeNames(const std::set<std::string>& clusterTypeNames) { _clusterTypeNames = clusterTypeNames; }
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ namespace MetaData
|
||||
boost::optional<Items>
|
||||
TagLibParser::parse(const boost::filesystem::path& p, bool debug)
|
||||
{
|
||||
TagLib::FileRef f(p.string().c_str(),
|
||||
TagLib::FileRef f {p.string().c_str(),
|
||||
true, // read audio properties
|
||||
TagLib::AudioProperties::Average);
|
||||
TagLib::AudioProperties::Average};
|
||||
|
||||
if (f.isNull())
|
||||
return boost::none;
|
||||
@@ -47,13 +47,12 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug)
|
||||
Items items;
|
||||
|
||||
{
|
||||
TagLib::AudioProperties *properties = f.audioProperties();
|
||||
const TagLib::AudioProperties *properties {f.audioProperties() };
|
||||
|
||||
std::chrono::milliseconds duration(properties->length() * 1000);
|
||||
items.insert( std::make_pair(MetaData::Type::Duration, duration) );
|
||||
items[MetaData::Type::Duration] = std::chrono::milliseconds {properties->length() * 1000};
|
||||
|
||||
MetaData::AudioStream audioStream = { .bitRate = static_cast<std::size_t>(properties->bitrate() * 1000) };
|
||||
items.insert( std::make_pair(MetaData::Type::AudioStreams, std::vector<MetaData::AudioStream>(1, audioStream ) ));
|
||||
MetaData::AudioStream audioStream {.bitRate = static_cast<std::size_t>(properties->bitrate() * 1000)};
|
||||
items[MetaData::Type::AudioStreams] = std::vector<MetaData::AudioStream> {audioStream};
|
||||
}
|
||||
|
||||
// Not that good embedded pictures handling
|
||||
@@ -71,7 +70,7 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug)
|
||||
if (f.tag())
|
||||
{
|
||||
MetaData::Clusters clusters;
|
||||
TagLib::PropertyMap properties = f.file()->properties();
|
||||
const TagLib::PropertyMap& properties {f.file()->properties()};
|
||||
|
||||
for(auto property : properties)
|
||||
{
|
||||
@@ -93,7 +92,23 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug)
|
||||
}
|
||||
|
||||
if (tag == "ARTIST")
|
||||
items.insert( std::make_pair(MetaData::Type::Artist, stringTrim( values.front().to8Bit(true))));
|
||||
{
|
||||
// Lower priority than ARTISTS
|
||||
if (items.find(MetaData::Type::Artists) == items.end())
|
||||
items[MetaData::Type::Artists] = std::vector<std::string>{ stringTrim( values.front().to8Bit(true)) };
|
||||
}
|
||||
else if (tag == "ARTISTS")
|
||||
{
|
||||
// Higher priority than ARTISTS
|
||||
std::vector<std::string> strings {splitString(values.front().to8Bit(), "/;")}; // Picard separator is '/'
|
||||
|
||||
std::vector<std::string> artists;
|
||||
for (const std::string& string : strings)
|
||||
artists.emplace_back(stringTrim(string));
|
||||
|
||||
items[MetaData::Type::Artists] = std::move(artists);
|
||||
}
|
||||
|
||||
else if (tag == "ALBUM")
|
||||
items.insert( std::make_pair(MetaData::Type::Album, stringTrim( values.front().to8Bit(true))));
|
||||
else if (tag == "TITLE")
|
||||
@@ -104,7 +119,15 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug)
|
||||
items.insert( std::make_pair(MetaData::Type::MusicBrainzTrackID, stringTrim( values.front().to8Bit(true))));
|
||||
}
|
||||
else if (tag == "MUSICBRAINZ_ARTISTID")
|
||||
items.insert( std::make_pair(MetaData::Type::MusicBrainzArtistID, stringTrim( values.front().to8Bit(true))));
|
||||
{
|
||||
std::vector<std::string> strings {splitString(values.front().to8Bit(), "/")}; // Picard separator is '/'
|
||||
|
||||
std::vector<std::string> mbids;
|
||||
for (const std::string& string : strings)
|
||||
mbids.emplace_back(stringTrim(string));
|
||||
|
||||
items[MetaData::Type::MusicBrainzArtistID] = std::move(mbids);
|
||||
}
|
||||
else if (tag == "MUSICBRAINZ_ALBUMID")
|
||||
items.insert( std::make_pair(MetaData::Type::MusicBrainzAlbumID, stringTrim( values.front().to8Bit(true))));
|
||||
else if (tag == "MUSICBRAINZ_TRACKID")
|
||||
@@ -113,25 +136,25 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug)
|
||||
items.insert( std::make_pair(MetaData::Type::AcoustID, stringTrim( values.front().to8Bit(true))));
|
||||
else if (tag == "TRACKTOTAL")
|
||||
{
|
||||
auto totalTrack = readAs<std::size_t>(values.front().to8Bit(true));
|
||||
auto totalTrack {readAs<std::size_t>(values.front().to8Bit(true)) };
|
||||
if (totalTrack)
|
||||
items[MetaData::Type::TotalTrack] = *totalTrack;
|
||||
}
|
||||
else if (tag == "TRACKNUMBER")
|
||||
{
|
||||
// Expecting 'Number/Total'
|
||||
auto strings = splitString(values.front().to8Bit(), "/");
|
||||
std::vector<std::string> strings {splitString(values.front().to8Bit(), "/")};
|
||||
|
||||
if (!strings.empty())
|
||||
{
|
||||
auto number = readAs<std::size_t>(strings[0]);
|
||||
auto number {readAs<std::size_t>(strings[0])};
|
||||
if (number)
|
||||
items.insert( std::make_pair(MetaData::Type::TrackNumber, *number ));
|
||||
|
||||
// Lower priority than TRACKTOTAL
|
||||
if (strings.size() > 1 && items.find(MetaData::Type::TotalTrack) == items.end())
|
||||
{
|
||||
auto totalTrack = readAs<std::size_t>(strings[1]);
|
||||
auto totalTrack {readAs<std::size_t>(strings[1])};
|
||||
if (totalTrack)
|
||||
items[MetaData::Type::TotalTrack] = *totalTrack;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user