This commit is contained in:
emeric
2019-03-10 13:49:51 +01:00
parent 99d592a71e
commit 4d01a1e996
12 changed files with 272 additions and 196 deletions
+6
View File
@@ -266,6 +266,12 @@ Track::getCopyrightURL() const
return _copyrightURL != "" ? boost::make_optional<std::string>(_copyrightURL) : boost::none;
}
std::vector<Wt::Dbo::ptr<Artist>>
Track::getArtists() const
{
return std::vector<Wt::Dbo::ptr<Artist>>(_artists.begin(), _artists.end());
}
Wt::Dbo::ptr<TrackFeatures>
Track::getTrackFeatures() const
{
+27 -27
View File
@@ -96,33 +96,33 @@ class Track : public Wt::Dbo::Dbo<Track>
void setMBID(const std::string& MBID) { _MBID = MBID; }
void setCopyright(const std::string& copyright) { _copyright = std::string(copyright, 0, _maxCopyrightLength); }
void setCopyrightURL(const std::string& copyrightURL) { _copyrightURL = std::string(copyrightURL, 0, _maxCopyrightURLLength); }
void setArtist(Wt::Dbo::ptr<Artist> artist) { _artist = artist; }
void setArtists(std::vector<Wt::Dbo::ptr<Artist>>& artists);
void setRelease(Wt::Dbo::ptr<Release> release) { _release = release; }
void eraseClusters() { _clusters.clear(); }
void eraseFeatures() { /*_trackFeatures.reset();*/ }
std::size_t getScanVersion() const { return _scanVersion; }
boost::optional<std::size_t> getTrackNumber() const;
boost::optional<std::size_t> getTotalTrackNumber() const;
boost::optional<std::size_t> getDiscNumber() const;
boost::optional<std::size_t> getTotalDiscNumber() const;
std::string getName() const { return _name; }
boost::filesystem::path getPath() const { return _filePath; }
std::chrono::milliseconds getDuration() const { return _duration; }
boost::optional<int> getYear() const;
boost::optional<int> getOriginalYear() const;
Wt::WDateTime getLastWriteTime() const { return _fileLastWrite; }
Wt::WDateTime getAddedTime() const { return _fileAdded; }
const std::vector<unsigned char>& getChecksum() const { return _fileChecksum; }
bool hasCover() const { return _hasCover; }
const std::string& getMBID() const { return _MBID; }
boost::optional<std::string> getCopyright() const;
boost::optional<std::string> getCopyrightURL() const;
Wt::Dbo::ptr<Artist> getArtist() const { return _artist; }
Wt::Dbo::ptr<Release> getRelease() const { return _release; }
std::size_t getScanVersion() const { return _scanVersion; }
boost::optional<std::size_t> getTrackNumber() const;
boost::optional<std::size_t> getTotalTrackNumber() const;
boost::optional<std::size_t> getDiscNumber() const;
boost::optional<std::size_t> getTotalDiscNumber() const;
std::string getName() const { return _name; }
boost::filesystem::path getPath() const { return _filePath; }
std::chrono::milliseconds getDuration() const { return _duration; }
boost::optional<int> getYear() const;
boost::optional<int> getOriginalYear() const;
Wt::WDateTime getLastWriteTime() const { return _fileLastWrite; }
Wt::WDateTime getAddedTime() const { return _fileAdded; }
const std::vector<unsigned char>& getChecksum() const { return _fileChecksum; }
bool hasCover() const { return _hasCover; }
const std::string& getMBID() const { return _MBID; }
boost::optional<std::string> getCopyright() const;
boost::optional<std::string> getCopyrightURL() const;
std::vector<Wt::Dbo::ptr<Artist>> getArtists() const;
Wt::Dbo::ptr<Release> getRelease() const { return _release; }
std::vector<Wt::Dbo::ptr<Cluster>> getClusters() const;
bool hasTrackFeatures() const;
Wt::Dbo::ptr<TrackFeatures> getTrackFeatures() const;
bool hasTrackFeatures() const;
Wt::Dbo::ptr<TrackFeatures> getTrackFeatures() const;
std::vector<std::vector<Wt::Dbo::ptr<Cluster>>> getClusterGroups(std::vector<Wt::Dbo::ptr<ClusterType>> clusterTypes, std::size_t size) const;
@@ -148,7 +148,7 @@ class Track : public Wt::Dbo::Dbo<Track>
Wt::Dbo::field(a, _copyright, "copyright");
Wt::Dbo::field(a, _copyrightURL, "copyright_url");
Wt::Dbo::belongsTo(a, _release, "release", Wt::Dbo::OnDeleteCascade);
Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade);
Wt::Dbo::hasMany(a, _artists, Wt::Dbo::ManyToMany, "track_artist", "", Wt::Dbo::OnDeleteCascade);
Wt::Dbo::hasMany(a, _clusters, Wt::Dbo::ManyToMany, "track_cluster", "", Wt::Dbo::OnDeleteCascade);
Wt::Dbo::hasMany(a, _playlistEntries, Wt::Dbo::ManyToOne, "track");
Wt::Dbo::hasOne(a, _trackFeatures);
@@ -181,11 +181,11 @@ class Track : public Wt::Dbo::Dbo<Track>
std::string _copyright;
std::string _copyrightURL;
Wt::Dbo::ptr<Artist> _artist;
Wt::Dbo::ptr<Release> _release;
Wt::Dbo::collection<Wt::Dbo::ptr<Cluster>> _clusters;
Wt::Dbo::ptr<Release> _release;
Wt::Dbo::collection<Wt::Dbo::ptr<Artist>> _artists;
Wt::Dbo::collection<Wt::Dbo::ptr<Cluster>> _clusters;
Wt::Dbo::collection<Wt::Dbo::ptr<TrackListEntry>> _playlistEntries;
Wt::Dbo::weak_ptr<TrackFeatures> _trackFeatures;
Wt::Dbo::weak_ptr<TrackFeatures> _trackFeatures;
};
+23 -4
View File
@@ -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
View File
@@ -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; }
+37 -14
View File
@@ -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;
}
+1 -1
View File
@@ -475,7 +475,7 @@ MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan,
}
// ***** Artist
Artist::pointer artist;
std::set<Artist::pointer> artists;
{
std::string artistName;
std::string artistMusicBrainzID;
@@ -153,14 +153,16 @@ getSimilarArtists(Wt::Dbo::Session& session, Database::IdType artistId, std::siz
if (!track)
continue;
auto trackArtist = track->getArtist();
if (!trackArtist || trackArtist.id() == artistId)
continue;
for (auto trackArtist : track->getArtists())
{
if (!trackArtist || trackArtist.id() == artistId)
continue;
if (std::find(res.begin(), res.end(), trackArtist.id()) != res.end())
continue;
if (std::find(res.begin(), res.end(), trackArtist.id()) != res.end())
continue;
res.push_back(trackArtist.id());
res.push_back(trackArtist.id());
}
if (res.size() == maxCount)
break;
+2 -2
View File
@@ -55,7 +55,7 @@ bool readList(const std::string& str, const std::string& separators, std::list<s
}
std::vector<std::string>
splitString(std::string string, std::string separators)
splitString(const std::string& string, const std::string& separators)
{
std::vector<std::string> res;
@@ -65,7 +65,7 @@ splitString(std::string string, std::string separators)
}
std::string
joinStrings(std::vector<std::string> strings, std::string delimiter)
joinStrings(const std::vector<std::string>& strings, const std::string& delimiter)
{
return boost::algorithm::join(strings, delimiter);
}
+2 -2
View File
@@ -34,10 +34,10 @@ bool
readList(const std::string& str, const std::string& separators, std::list<std::string>& results);
std::vector<std::string>
splitString(std::string string, std::string separators);
splitString(const std::string& string, const std::string& separators);
std::string
joinStrings(std::vector<std::string> strings, std::string delimiter);
joinStrings(const std::vector<std::string>& strings, const std::string& delimiter);
std::string
stringTrim(const std::string& str, const std::string& whitespaces = " \t");
+126 -105
View File
@@ -1,13 +1,129 @@
#include <stdlib.h>
#include <chrono>
#include <stdexcept>
#include <stdlib.h>
#include <iostream>
#include <Wt/WDate.h>
#include "av/AvInfo.hpp"
#include "metadata/AvFormat.hpp"
#include "metadata/TagLibParser.hpp"
void parse(MetaData::Parser& parser, const boost::filesystem::path& file)
{
parser.setClusterTypeNames( {"MOOD", "GENRE"} );
boost::optional<MetaData::Items> items {parser.parse(file, true)};
if (!items)
{
std::cerr << "Parsing failed" << std::endl;
return;
}
std::cout << "Items:" << std::endl;
for (auto item : (*items))
{
switch (item.first)
{
case MetaData::Type::Title:
std::cout << "Title: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::Artists:
for (const std::string& artist : boost::any_cast<std::set<std::string>>(item.second))
std::cout << "Artist: " << artist << std::endl;
break;
case MetaData::Type::Album:
std::cout << "Album: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::Clusters:
for (const auto& cluster : boost::any_cast<MetaData::Clusters>(item.second))
{
std::cout << "Cluster: " << cluster.first << std::endl;
for (const auto name : cluster.second)
{
std::cout << "\t" << name << std::endl;
}
}
break;
case MetaData::Type::Duration:
std::cout << "Duration: " << boost::any_cast<std::chrono::milliseconds>(item.second).count() / 1000 << "s" << std::endl;
break;
case MetaData::Type::TrackNumber:
std::cout << "Track: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::TotalTrack:
std::cout << "TotalTrack: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::DiscNumber:
std::cout << "Disc: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::TotalDisc:
std::cout << "TotalDisc: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::Year:
std::cout << "Year: " << std::to_string(boost::any_cast<int>(item.second)) << std::endl;
break;
case MetaData::Type::OriginalYear:
std::cout << "Original year: " << std::to_string(boost::any_cast<int>(item.second)) << std::endl;
break;
case MetaData::Type::HasCover:
std::cout << "HasCover = " << std::boolalpha << boost::any_cast<bool>(item.second) << std::endl;
break;
case MetaData::Type::AudioStreams:
for (const auto& audioStream : boost::any_cast<std::vector<MetaData::AudioStream> >(item.second))
std::cout << "Audio stream: " << audioStream.bitRate << " bps" << std::endl;
break;
case MetaData::Type::MusicBrainzArtistID:
for (const std::string& mbid : boost::any_cast<std::set<std::string>>(item.second))
std::cout << "MusicBrainzArtistID: " << mbid << std::endl;
break;
case MetaData::Type::MusicBrainzAlbumID:
std::cout << "MusicBrainzAlbumID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::MusicBrainzTrackID:
std::cout << "MusicBrainzTrackID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::MusicBrainzRecordingID:
std::cout << "MusicBrainzRecordingID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::AcoustID:
std::cout << "AcoustID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::Copyright:
std::cout << "Copyright: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::CopyrightURL:
std::cout << "CopyrightURL: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
default:
break;
}
}
std::cout << std::endl;
}
int main(int argc, char *argv[])
{
if (argc != 2)
@@ -18,116 +134,21 @@ int main(int argc, char *argv[])
try
{
MetaData::TagLibParser parser;
Av::AvInit();
boost::filesystem::path file {argv[1]};
parser.setClusterTypeNames( {"MOOD", "GENRE"} );
boost::optional<MetaData::Items> items = parser.parse(argv[1], true);
if (!items)
{
std::cerr << "Parsing failed" << std::endl;
return EXIT_FAILURE;
std::cout << "Using av:" << std::endl;
MetaData::AvFormat parser;
parse(parser, file);
}
std::cout << "Items:" << std::endl;
for (auto item : (*items))
{
switch (item.first)
{
case MetaData::Type::Title:
std::cout << "Title: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::Artist:
std::cout << "Artist: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::Album:
std::cout << "Album: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::Clusters:
for (const auto& cluster : boost::any_cast<MetaData::Clusters>(item.second))
{
std::cout << "Cluster: " << cluster.first << std::endl;
for (const auto name : cluster.second)
{
std::cout << "\t" << name << std::endl;
}
}
break;
case MetaData::Type::Duration:
std::cout << "Duration: " << boost::any_cast<std::chrono::milliseconds>(item.second).count() / 1000 << "s" << std::endl;
break;
case MetaData::Type::TrackNumber:
std::cout << "Track: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::TotalTrack:
std::cout << "TotalTrack: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::DiscNumber:
std::cout << "Disc: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::TotalDisc:
std::cout << "TotalDisc: " << boost::any_cast<std::size_t>(item.second) << std::endl;
break;
case MetaData::Type::Year:
std::cout << "Year: " << std::to_string(boost::any_cast<int>(item.second)) << std::endl;
break;
case MetaData::Type::OriginalYear:
std::cout << "Original year: " << std::to_string(boost::any_cast<int>(item.second)) << std::endl;
break;
case MetaData::Type::HasCover:
std::cout << "HasCover = " << std::boolalpha << boost::any_cast<bool>(item.second) << std::endl;
break;
case MetaData::Type::AudioStreams:
for (auto& audioStream : boost::any_cast<std::vector<MetaData::AudioStream> >(item.second))
std::cout << "Audio stream: " << audioStream.bitRate << " bps" << std::endl;
break;
case MetaData::Type::MusicBrainzArtistID:
std::cout << "MusicBrainzArtistID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::MusicBrainzAlbumID:
std::cout << "MusicBrainzAlbumID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::MusicBrainzTrackID:
std::cout << "MusicBrainzTrackID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::MusicBrainzRecordingID:
std::cout << "MusicBrainzRecordingID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::AcoustID:
std::cout << "AcoustID: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::Copyright:
std::cout << "Copyright: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
case MetaData::Type::CopyrightURL:
std::cout << "CopyrightURL: " << boost::any_cast<std::string>(item.second) << std::endl;
break;
default:
break;
}
std::cout << "Using TagLib:" << std::endl;
MetaData::TagLibParser parser;
parse(parser, file);
}
std::cout << std::endl;
}
catch (std::exception& e)
{
+4 -2
View File
@@ -2,9 +2,11 @@ bin_PROGRAMS = lms-metadata
lms_metadata_SOURCES = \
$(srcdir)/LmsMetadata.cpp \
$(top_srcdir)/src/av/AvInfo.cpp \
$(top_srcdir)/src/metadata/AvFormat.cpp \
$(top_srcdir)/src/metadata/TagLibParser.cpp \
$(top_srcdir)/src/utils/Logger.cpp \
$(top_srcdir)/src/utils/Utils.cpp \
$(top_srcdir)/src/metadata/TagLibParser.cpp
$(top_srcdir)/src/utils/Utils.cpp
lms_metadata_CXXFLAGS=-std=c++14 -Wall -I$(top_srcdir)/src -D_REENTRANT
+2 -2
View File
@@ -24,8 +24,8 @@ std::ostream& operator<<(std::ostream& os, const Database::Track::pointer& track
auto genreClusters = track->getClusterGroups({genreClusterType}, 1);
for (auto genreCluster : genreClusters)
os << genreCluster.front()->getName() << " - ";
if (track->getArtist())
os << track->getArtist()->getName() << " - ";
for (auto artist : track->getArtists())
os << artist->getName() << " - ";
if (track->getRelease())
os << track->getRelease()->getName() << " - ";
os << track->getName() << "]";