Write/Read score to/from files' tags, as "Amarok score" as we use the same algorithm
This commit is contained in:
parent
dc208962f6
commit
77c6a22962
|
@ -101,6 +101,7 @@ TagLib::String QStringToTaglibString(const QString& s) {
|
||||||
|
|
||||||
const char* TagReader::kMP4_FMPS_Rating_ID = "----:com.apple.iTunes:FMPS_Rating";
|
const char* TagReader::kMP4_FMPS_Rating_ID = "----:com.apple.iTunes:FMPS_Rating";
|
||||||
const char* TagReader::kMP4_FMPS_Playcount_ID = "----:com.apple.iTunes:FMPS_Playcount";
|
const char* TagReader::kMP4_FMPS_Playcount_ID = "----:com.apple.iTunes:FMPS_Playcount";
|
||||||
|
const char* TagReader::kMP4_FMPS_Score_ID = "----:com.apple.iTunes:FMPS_Rating_Amarok_Score";
|
||||||
|
|
||||||
TagReader::TagReader()
|
TagReader::TagReader()
|
||||||
: factory_(new TagLibFileRefFactory),
|
: factory_(new TagLibFileRefFactory),
|
||||||
|
@ -262,6 +263,12 @@ void TagReader::ReadFile(const QString& filename,
|
||||||
song->set_playcount(playcount);
|
song->set_playcount(playcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (items.contains(kMP4_FMPS_Playcount_ID)) {
|
||||||
|
int score = TStringToQString(items[kMP4_FMPS_Score_ID].toStringList().toString('\n')).toFloat() * 100;
|
||||||
|
if (song->score() <= 0 && score > 0) {
|
||||||
|
song->set_score(score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(items.contains("\251wrt")) {
|
if(items.contains("\251wrt")) {
|
||||||
Decode(items["\251wrt"].toStringList().toString(", "), NULL, song->mutable_composer());
|
Decode(items["\251wrt"].toStringList().toString(", "), NULL, song->mutable_composer());
|
||||||
|
@ -293,6 +300,15 @@ void TagReader::ReadFile(const QString& filename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (attributes_map.contains("FMPS/Rating_Amarok_Score")) {
|
||||||
|
const TagLib::ASF::AttributeList& attributes = attributes_map["FMPS/Rating_Amarok_Score"];
|
||||||
|
if (!attributes.isEmpty()) {
|
||||||
|
int score = TStringToQString(attributes.front().toString()).toFloat() * 100;
|
||||||
|
if (song->score() <= 0 && score > 0) {
|
||||||
|
song->set_score(score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (tag) {
|
else if (tag) {
|
||||||
|
@ -398,6 +414,11 @@ void TagReader::ParseFMPSFrame(const QString& name, const QString& value,
|
||||||
song->set_playcount(var.toDouble());
|
song->set_playcount(var.toDouble());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (name == "FMPS_Rating_Amarok_Score") {
|
||||||
|
var = parser.result()[0][0];
|
||||||
|
if (var.type() == QVariant::Double) {
|
||||||
|
song->set_score(var.toDouble() * 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,6 +456,9 @@ void TagReader::ParseOggTag(const TagLib::Ogg::FieldListMap& map,
|
||||||
|
|
||||||
if (!map["FMPS_PLAYCOUNT"].isEmpty() && song->playcount() <= 0)
|
if (!map["FMPS_PLAYCOUNT"].isEmpty() && song->playcount() <= 0)
|
||||||
song->set_playcount(TStringToQString( map["FMPS_PLAYCOUNT"].front() ).trimmed().toFloat());
|
song->set_playcount(TStringToQString( map["FMPS_PLAYCOUNT"].front() ).trimmed().toFloat());
|
||||||
|
|
||||||
|
if (!map["FMPS_RATING_AMAROK_SCORE"].isEmpty() && song->score() <= 0)
|
||||||
|
song->set_score(TStringToQString( map["FMPS_RATING_AMAROK_SCORE"].front() ).trimmed().toFloat() * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagReader::SetVorbisComments(TagLib::Ogg::XiphComment* vorbis_comments,
|
void TagReader::SetVorbisComments(TagLib::Ogg::XiphComment* vorbis_comments,
|
||||||
|
@ -453,6 +477,7 @@ void TagReader::SetFMPSVorbisComments(TagLib::Ogg::XiphComment* vorbis_comments,
|
||||||
|
|
||||||
vorbis_comments->addField("FMPS_RATING", QStringToTaglibString(QString::number(song.rating())));
|
vorbis_comments->addField("FMPS_RATING", QStringToTaglibString(QString::number(song.rating())));
|
||||||
vorbis_comments->addField("FMPS_PLAYCOUNT", QStringToTaglibString(QString::number(song.playcount())));
|
vorbis_comments->addField("FMPS_PLAYCOUNT", QStringToTaglibString(QString::number(song.playcount())));
|
||||||
|
vorbis_comments->addField("FMPS_RATING_AMAROK_SCORE", QStringToTaglibString(QString::number(song.score() / 100.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pb::tagreader::SongMetadata_Type TagReader::GuessFileType(
|
pb::tagreader::SongMetadata_Type TagReader::GuessFileType(
|
||||||
|
@ -570,6 +595,7 @@ bool TagReader::SaveSongStatisticsToFile(const QString& filename,
|
||||||
// Save as FMPS
|
// Save as FMPS
|
||||||
SetUserTextFrame("FMPS_Rating", QString::number(song.rating()), tag);
|
SetUserTextFrame("FMPS_Rating", QString::number(song.rating()), tag);
|
||||||
SetUserTextFrame("FMPS_PlayCount", QString::number(song.playcount()), tag);
|
SetUserTextFrame("FMPS_PlayCount", QString::number(song.playcount()), tag);
|
||||||
|
SetUserTextFrame("FMPS_Rating_Amarok_Score", QString::number(song.score() / 100.0), tag);
|
||||||
|
|
||||||
// Also save as POPM
|
// Also save as POPM
|
||||||
TagLib::ID3v2::PopularimeterFrame* frame = NULL;
|
TagLib::ID3v2::PopularimeterFrame* frame = NULL;
|
||||||
|
@ -599,12 +625,14 @@ bool TagReader::SaveSongStatisticsToFile(const QString& filename,
|
||||||
#define ConvertASF(x) TagLib::ASF::Attribute(QStringToTaglibString(QString::number(x)))
|
#define ConvertASF(x) TagLib::ASF::Attribute(QStringToTaglibString(QString::number(x)))
|
||||||
tag->addAttribute("FMPS/Rating", ConvertASF(song.rating()));
|
tag->addAttribute("FMPS/Rating", ConvertASF(song.rating()));
|
||||||
tag->addAttribute("FMPS/Playcount", ConvertASF(song.playcount()));
|
tag->addAttribute("FMPS/Playcount", ConvertASF(song.playcount()));
|
||||||
|
tag->addAttribute("FMPS/Rating_Amarok_Score", ConvertASF(song.score() / 100.0));
|
||||||
#undef ConvertASF
|
#undef ConvertASF
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
||||||
TagLib::MP4::Tag* tag = file->tag();
|
TagLib::MP4::Tag* tag = file->tag();
|
||||||
tag->itemListMap()[kMP4_FMPS_Rating_ID] = TagLib::StringList(QStringToTaglibString(QString::number(song.rating())));
|
tag->itemListMap()[kMP4_FMPS_Rating_ID] = TagLib::StringList(QStringToTaglibString(QString::number(song.rating())));
|
||||||
|
tag->itemListMap()[kMP4_FMPS_Score_ID] = TagLib::StringList(QStringToTaglibString(QString::number(song.score() / 100.0)));
|
||||||
tag->itemListMap()[kMP4_FMPS_Playcount_ID] = TagLib::StringList(TagLib::String::number(song.playcount()));
|
tag->itemListMap()[kMP4_FMPS_Playcount_ID] = TagLib::StringList(TagLib::String::number(song.playcount()));
|
||||||
} else {
|
} else {
|
||||||
// Nothing to save: stop now
|
// Nothing to save: stop now
|
||||||
|
|
|
@ -100,6 +100,7 @@ class TagReader {
|
||||||
private:
|
private:
|
||||||
static const char* kMP4_FMPS_Rating_ID;
|
static const char* kMP4_FMPS_Rating_ID;
|
||||||
static const char* kMP4_FMPS_Playcount_ID;
|
static const char* kMP4_FMPS_Playcount_ID;
|
||||||
|
static const char* kMP4_FMPS_Score_ID;
|
||||||
// Returns a float in [0.0..1.0] corresponding to the rating range we use in Clementine
|
// Returns a float in [0.0..1.0] corresponding to the rating range we use in Clementine
|
||||||
static float ConvertPOPMRating(const int POPM_rating);
|
static float ConvertPOPMRating(const int POPM_rating);
|
||||||
// Reciprocal
|
// Reciprocal
|
||||||
|
|
|
@ -146,6 +146,19 @@ TEST_F(SongTest, FMPSPlayCountBoth) {
|
||||||
EXPECT_EQ(123, song.playcount());
|
EXPECT_EQ(123, song.playcount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SongTest, FMPSScore) {
|
||||||
|
TemporaryResource r(":/testdata/beep.mp3");
|
||||||
|
{
|
||||||
|
Song song = ReadSongFromFile(r.fileName());
|
||||||
|
song.set_score(43);
|
||||||
|
|
||||||
|
WriteSongStatisticsToFile(song, r.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Song new_song = ReadSongFromFile(r.fileName());
|
||||||
|
EXPECT_FLOAT_EQ(43, new_song.score());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SongTest, POPMRating) {
|
TEST_F(SongTest, POPMRating) {
|
||||||
TemporaryResource r(":/testdata/popmrating.mp3");
|
TemporaryResource r(":/testdata/popmrating.mp3");
|
||||||
Song song = ReadSongFromFile(r.fileName());
|
Song song = ReadSongFromFile(r.fileName());
|
||||||
|
@ -166,6 +179,7 @@ TEST_F(SongTest, RatingAndStatisticsOgg) {
|
||||||
Song song = ReadSongFromFile(r.fileName());
|
Song song = ReadSongFromFile(r.fileName());
|
||||||
song.set_rating(0.20);
|
song.set_rating(0.20);
|
||||||
song.set_playcount(1337);
|
song.set_playcount(1337);
|
||||||
|
song.set_score(87);
|
||||||
|
|
||||||
WriteSongStatisticsToFile(song, r.fileName());
|
WriteSongStatisticsToFile(song, r.fileName());
|
||||||
}
|
}
|
||||||
|
@ -173,6 +187,7 @@ TEST_F(SongTest, RatingAndStatisticsOgg) {
|
||||||
Song new_song = ReadSongFromFile(r.fileName());
|
Song new_song = ReadSongFromFile(r.fileName());
|
||||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||||
EXPECT_EQ(1337, new_song.playcount());
|
EXPECT_EQ(1337, new_song.playcount());
|
||||||
|
EXPECT_EQ(87, new_song.score());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SongTest, RatingAndStatisticsFLAC) {
|
TEST_F(SongTest, RatingAndStatisticsFLAC) {
|
||||||
|
@ -181,6 +196,7 @@ TEST_F(SongTest, RatingAndStatisticsFLAC) {
|
||||||
Song song = ReadSongFromFile(r.fileName());
|
Song song = ReadSongFromFile(r.fileName());
|
||||||
song.set_rating(0.20);
|
song.set_rating(0.20);
|
||||||
song.set_playcount(1337);
|
song.set_playcount(1337);
|
||||||
|
song.set_score(87);
|
||||||
|
|
||||||
WriteSongStatisticsToFile(song, r.fileName());
|
WriteSongStatisticsToFile(song, r.fileName());
|
||||||
}
|
}
|
||||||
|
@ -188,6 +204,7 @@ TEST_F(SongTest, RatingAndStatisticsFLAC) {
|
||||||
Song new_song = ReadSongFromFile(r.fileName());
|
Song new_song = ReadSongFromFile(r.fileName());
|
||||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||||
EXPECT_EQ(1337, new_song.playcount());
|
EXPECT_EQ(1337, new_song.playcount());
|
||||||
|
EXPECT_EQ(87, new_song.score());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TAGLIB_WITH_ASF
|
#ifdef TAGLIB_WITH_ASF
|
||||||
|
@ -197,6 +214,7 @@ TEST_F(SongTest, RatingAndStatisticsASF) {
|
||||||
Song song = ReadSongFromFile(r.fileName());
|
Song song = ReadSongFromFile(r.fileName());
|
||||||
song.set_rating(0.20);
|
song.set_rating(0.20);
|
||||||
song.set_playcount(1337);
|
song.set_playcount(1337);
|
||||||
|
song.set_score(87);
|
||||||
|
|
||||||
WriteSongStatisticsToFile(song, r.fileName());
|
WriteSongStatisticsToFile(song, r.fileName());
|
||||||
}
|
}
|
||||||
|
@ -204,6 +222,7 @@ TEST_F(SongTest, RatingAndStatisticsASF) {
|
||||||
Song new_song = ReadSongFromFile(r.fileName());
|
Song new_song = ReadSongFromFile(r.fileName());
|
||||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||||
EXPECT_EQ(1337, new_song.playcount());
|
EXPECT_EQ(1337, new_song.playcount());
|
||||||
|
EXPECT_EQ(87, new_song.score());
|
||||||
}
|
}
|
||||||
#endif // TAGLIB_WITH_ASF
|
#endif // TAGLIB_WITH_ASF
|
||||||
|
|
||||||
|
@ -213,6 +232,7 @@ TEST_F(SongTest, RatingAndStatisticsMP4) {
|
||||||
Song song = ReadSongFromFile(r.fileName());
|
Song song = ReadSongFromFile(r.fileName());
|
||||||
song.set_rating(0.20);
|
song.set_rating(0.20);
|
||||||
song.set_playcount(1337);
|
song.set_playcount(1337);
|
||||||
|
song.set_score(87);
|
||||||
|
|
||||||
WriteSongStatisticsToFile(song, r.fileName());
|
WriteSongStatisticsToFile(song, r.fileName());
|
||||||
}
|
}
|
||||||
|
@ -220,6 +240,7 @@ TEST_F(SongTest, RatingAndStatisticsMP4) {
|
||||||
Song new_song = ReadSongFromFile(r.fileName());
|
Song new_song = ReadSongFromFile(r.fileName());
|
||||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||||
EXPECT_EQ(1337, new_song.playcount());
|
EXPECT_EQ(1337, new_song.playcount());
|
||||||
|
EXPECT_EQ(87, new_song.score());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue