diff --git a/autotests/samplefiles/test.wma b/autotests/samplefiles/test.wma index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@("fileType"); + QTest::addColumn("mimeType"); + + QTest::addRow("asf") + << QStringLiteral("wma") + << QStringLiteral("audio/x-ms-wma") + ; +} + void TagLibExtractorTest::testId3Rating_data() { QTest::addColumn("path"); @@ -389,6 +422,43 @@ QCOMPARE(result.properties().value(Property::Rating).toInt(), expectedRating); } +void TagLibExtractorTest::testWmaRating() +{ + QFETCH(QString, path); + QFETCH(int, expectedRating); + + TagLibExtractor plugin{this}; + SimpleExtractionResult result(path, "audio/x-ms-wma"); + plugin.extract(&result); + + QCOMPARE(result.properties().value(Property::Rating).toUInt(), expectedRating); +} + +void TagLibExtractorTest::testWmaRating_data() +{ + QTest::addColumn("path"); + QTest::addColumn("expectedRating"); + + QTest::addRow("WMP0") + << QFINDTESTDATA("samplefiles/wma_rating/test0.wma") + << 0 ; + QTest::addRow("WMP1") + << QFINDTESTDATA("samplefiles/wma_rating/test1.wma") + << 2 ; + QTest::addRow("WMP2") + << QFINDTESTDATA("samplefiles/wma_rating/test2.wma") + << 4 ; + QTest::addRow("WMP3") + << QFINDTESTDATA("samplefiles/wma_rating/test3.wma") + << 6 ; + QTest::addRow("WMP4") + << QFINDTESTDATA("samplefiles/wma_rating/test4.wma") + << 8 ; + QTest::addRow("WMP5") + << QFINDTESTDATA("samplefiles/wma_rating/test5.wma") + << 10 ; +} + void TagLibExtractorTest::testNoMetadata_data() { const auto expectedKeys = QList{ diff --git a/src/extractors/taglibextractor.h b/src/extractors/taglibextractor.h --- a/src/extractors/taglibextractor.h +++ b/src/extractors/taglibextractor.h @@ -28,6 +28,9 @@ namespace TagLib { + namespace ASF { + class Tag; + } namespace ID3v2 { class Tag; } @@ -89,6 +92,7 @@ void extractMp4Tags(TagLib::MP4::Tag* mp4Tags, ExtractedData& data); void extractApeTags(TagLib::APE::Tag* apeTags, ExtractedData& data); void extractVorbisTags(TagLib::Ogg::XiphComment* vorbisTags, ExtractedData& data); + void extractAsfTags(TagLib::ASF::Tag* asfTags, ExtractedData& data); }; } diff --git a/src/extractors/taglibextractor.cpp b/src/extractors/taglibextractor.cpp --- a/src/extractors/taglibextractor.cpp +++ b/src/extractors/taglibextractor.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -707,6 +709,84 @@ } } +void TagLibExtractor::extractAsfTags(TagLib::ASF::Tag* asfTags, ExtractedData& data) +{ + if (asfTags->isEmpty()) { + return; + } + + if (!asfTags->copyright().isEmpty()) { + data.copyright = asfTags->copyright(); + } + + TagLib::ASF::AttributeList lstASF = asfTags->attribute("WM/SharedUserRating"); + if (!lstASF.isEmpty()) { + int rating = lstASF.front().toString().toInt(); + //map the rating values of WMP to Baloo rating + //0->0, 1->2, 25->4, 50->6, 75->8, 99->10 + if (rating == 0) { + data.rating = 0; + } else if (rating == 1) { + data.rating = 2; + } else { + data.rating = static_cast(0.09 * rating + 2); + } + } + + lstASF = asfTags->attribute("WM/PartOfSet"); + if (!lstASF.isEmpty()) { + data.discNumber = lstASF.front().toString().toInt(); + } + + lstASF = asfTags->attribute("WM/AlbumArtist"); + for (const auto& attribute : qAsConst(lstASF)) { + if (!data.albumArtists.isEmpty()) { + data.albumArtists += ", "; + } + data.albumArtists += attribute.toString(); + } + + lstASF = asfTags->attribute("WM/Composer"); + for (const auto& attribute : qAsConst(lstASF)) { + if (!data.composers.isEmpty()) { + data.composers += ", "; + } + data.composers += attribute.toString(); + } + + lstASF = asfTags->attribute("WM/Conductor"); + for (const auto& attribute : qAsConst(lstASF)) { + if (!data.conductor.isEmpty()) { + data.conductor += ", "; + } + data.conductor += attribute.toString(); + } + + lstASF = asfTags->attribute("WM/Writer"); + for (const auto& attribute : qAsConst(lstASF)) { + if (!data.lyricists.isEmpty()) { + data.lyricists += ", "; + } + data.lyricists += attribute.toString(); + } + + lstASF = asfTags->attribute("WM/Publisher"); + for (const auto& attribute : qAsConst(lstASF)) { + if (!data.publisher.isEmpty()) { + data.publisher += ", "; + } + data.publisher += attribute.toString(); + } + + lstASF = asfTags->attribute("Author"); + for (const auto& attribute : qAsConst(lstASF)) { + if (!data.author.isEmpty()) { + data.author += ", "; + } + data.author += attribute.toString(); + } +} + void TagLibExtractor::extract(ExtractionResult* result) { const QString fileUrl = result->inputUrl(); @@ -771,6 +851,13 @@ if (opusFile.tag()) { extractVorbisTags(opusFile.tag(), data); } + } else if (mimeType == QLatin1String("audio/x-ms-wma")) { + /* For some reason, TagLib::ASF::File tag() returns only an invalid pointer. + * Use the dynamic_cast instead. */ + TagLib::ASF::Tag* asfTags = dynamic_cast(tags); + if (asfTags) { + extractAsfTags(asfTags, data); + } } if (!tags->isEmpty()) {