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_Playcount_ID = "----:com.apple.iTunes:FMPS_Playcount";
|
||||
const char* TagReader::kMP4_FMPS_Score_ID = "----:com.apple.iTunes:FMPS_Rating_Amarok_Score";
|
||||
|
||||
TagReader::TagReader()
|
||||
: factory_(new TagLibFileRefFactory),
|
||||
|
@ -262,6 +263,12 @@ void TagReader::ReadFile(const QString& filename,
|
|||
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")) {
|
||||
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
|
||||
else if (tag) {
|
||||
|
@ -398,6 +414,11 @@ void TagReader::ParseFMPSFrame(const QString& name, const QString& value,
|
|||
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)
|
||||
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,
|
||||
|
@ -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_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(
|
||||
|
@ -570,6 +595,7 @@ bool TagReader::SaveSongStatisticsToFile(const QString& filename,
|
|||
// Save as FMPS
|
||||
SetUserTextFrame("FMPS_Rating", QString::number(song.rating()), 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
|
||||
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)))
|
||||
tag->addAttribute("FMPS/Rating", ConvertASF(song.rating()));
|
||||
tag->addAttribute("FMPS/Playcount", ConvertASF(song.playcount()));
|
||||
tag->addAttribute("FMPS/Rating_Amarok_Score", ConvertASF(song.score() / 100.0));
|
||||
#undef ConvertASF
|
||||
}
|
||||
#endif
|
||||
else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
|
||||
TagLib::MP4::Tag* tag = file->tag();
|
||||
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()));
|
||||
} else {
|
||||
// Nothing to save: stop now
|
||||
|
|
|
@ -100,6 +100,7 @@ class TagReader {
|
|||
private:
|
||||
static const char* kMP4_FMPS_Rating_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
|
||||
static float ConvertPOPMRating(const int POPM_rating);
|
||||
// Reciprocal
|
||||
|
|
|
@ -146,6 +146,19 @@ TEST_F(SongTest, FMPSPlayCountBoth) {
|
|||
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) {
|
||||
TemporaryResource r(":/testdata/popmrating.mp3");
|
||||
Song song = ReadSongFromFile(r.fileName());
|
||||
|
@ -166,6 +179,7 @@ TEST_F(SongTest, RatingAndStatisticsOgg) {
|
|||
Song song = ReadSongFromFile(r.fileName());
|
||||
song.set_rating(0.20);
|
||||
song.set_playcount(1337);
|
||||
song.set_score(87);
|
||||
|
||||
WriteSongStatisticsToFile(song, r.fileName());
|
||||
}
|
||||
|
@ -173,6 +187,7 @@ TEST_F(SongTest, RatingAndStatisticsOgg) {
|
|||
Song new_song = ReadSongFromFile(r.fileName());
|
||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||
EXPECT_EQ(1337, new_song.playcount());
|
||||
EXPECT_EQ(87, new_song.score());
|
||||
}
|
||||
|
||||
TEST_F(SongTest, RatingAndStatisticsFLAC) {
|
||||
|
@ -181,6 +196,7 @@ TEST_F(SongTest, RatingAndStatisticsFLAC) {
|
|||
Song song = ReadSongFromFile(r.fileName());
|
||||
song.set_rating(0.20);
|
||||
song.set_playcount(1337);
|
||||
song.set_score(87);
|
||||
|
||||
WriteSongStatisticsToFile(song, r.fileName());
|
||||
}
|
||||
|
@ -188,6 +204,7 @@ TEST_F(SongTest, RatingAndStatisticsFLAC) {
|
|||
Song new_song = ReadSongFromFile(r.fileName());
|
||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||
EXPECT_EQ(1337, new_song.playcount());
|
||||
EXPECT_EQ(87, new_song.score());
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
|
@ -197,6 +214,7 @@ TEST_F(SongTest, RatingAndStatisticsASF) {
|
|||
Song song = ReadSongFromFile(r.fileName());
|
||||
song.set_rating(0.20);
|
||||
song.set_playcount(1337);
|
||||
song.set_score(87);
|
||||
|
||||
WriteSongStatisticsToFile(song, r.fileName());
|
||||
}
|
||||
|
@ -204,6 +222,7 @@ TEST_F(SongTest, RatingAndStatisticsASF) {
|
|||
Song new_song = ReadSongFromFile(r.fileName());
|
||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||
EXPECT_EQ(1337, new_song.playcount());
|
||||
EXPECT_EQ(87, new_song.score());
|
||||
}
|
||||
#endif // TAGLIB_WITH_ASF
|
||||
|
||||
|
@ -213,6 +232,7 @@ TEST_F(SongTest, RatingAndStatisticsMP4) {
|
|||
Song song = ReadSongFromFile(r.fileName());
|
||||
song.set_rating(0.20);
|
||||
song.set_playcount(1337);
|
||||
song.set_score(87);
|
||||
|
||||
WriteSongStatisticsToFile(song, r.fileName());
|
||||
}
|
||||
|
@ -220,6 +240,7 @@ TEST_F(SongTest, RatingAndStatisticsMP4) {
|
|||
Song new_song = ReadSongFromFile(r.fileName());
|
||||
EXPECT_FLOAT_EQ(0.20, new_song.rating());
|
||||
EXPECT_EQ(1337, new_song.playcount());
|
||||
EXPECT_EQ(87, new_song.score());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue