Support a consistent set of MusicBrainz properties where possible

The support for MusicBrainz properties is enhanced with "ARTISTS", "ASIN",
"RELEASECOUNTRY", "RELEASESTATUS", "RELEASETYPE", "MUSICBRAINZ_RELEASETRACKID",
"ORIGINALDATE" on APE, ASF, MP4, ID3v2, and Xiph tags.
This commit is contained in:
Urs Fleisch 2021-01-10 15:16:45 +01:00
parent f7c24930cd
commit cf6c68bafc
10 changed files with 220 additions and 2 deletions

View File

@ -215,7 +215,9 @@ namespace
{"DATE", "YEAR" },
{"ALBUMARTIST", "ALBUM ARTIST"},
{"DISCNUMBER", "DISC" },
{"REMIXER", "MIXARTIST" }};
{"REMIXER", "MIXARTIST" },
{"RELEASESTATUS", "MUSICBRAINZ_ALBUMSTATUS" },
{"RELEASETYPE", "MUSICBRAINZ_ALBUMTYPE" }};
const size_t keyConversionsSize = sizeof(keyConversions) / sizeof(keyConversions[0]);
}

View File

@ -216,7 +216,7 @@ namespace
{ "WM/AlbumTitle", "ALBUM" },
{ "WM/AlbumArtist", "ALBUMARTIST" },
{ "WM/Composer", "COMPOSER" },
{ "WM/Writer", "WRITER" },
{ "WM/Writer", "LYRICIST" },
{ "WM/Conductor", "CONDUCTOR" },
{ "WM/ModifiedBy", "REMIXER" },
{ "WM/Year", "DATE" },
@ -243,11 +243,17 @@ namespace
{ "WM/TitleSortOrder", "TITLESORT" },
{ "WM/Script", "SCRIPT" },
{ "WM/Language", "LANGUAGE" },
{ "WM/ARTISTS", "ARTISTS" },
{ "ASIN", "ASIN" },
{ "MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID" },
{ "MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID" },
{ "MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID" },
{ "MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
{ "MusicBrainz/Album Release Country", "RELEASECOUNTRY" },
{ "MusicBrainz/Album Status", "RELEASESTATUS" },
{ "MusicBrainz/Album Type", "RELEASETYPE" },
{ "MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
{ "MusicBrainz/Release Track Id", "MUSICBRAINZ_RELEASETRACKID" },
{ "MusicBrainz/Work Id", "MUSICBRAINZ_WORKID" },
{ "MusicIP/PUID", "MUSICIP_PUID" },
{ "Acoustid/Id", "ACOUSTID_ID" },

View File

@ -915,7 +915,13 @@ namespace
{ "----:com.apple.iTunes:MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
{ "----:com.apple.iTunes:MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
{ "----:com.apple.iTunes:MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
{ "----:com.apple.iTunes:MusicBrainz Release Track Id", "MUSICBRAINZ_RELEASETRACKID" },
{ "----:com.apple.iTunes:MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
{ "----:com.apple.iTunes:MusicBrainz Album Release Country", "RELEASECOUNTRY" },
{ "----:com.apple.iTunes:MusicBrainz Album Status", "RELEASESTATUS" },
{ "----:com.apple.iTunes:MusicBrainz Album Type", "RELEASETYPE" },
{ "----:com.apple.iTunes:ARTISTS", "ARTISTS" },
{ "----:com.apple.iTunes:originaldate", "ORIGINALDATE" },
{ "----:com.apple.iTunes:ASIN", "ASIN" },
{ "----:com.apple.iTunes:LABEL", "LABEL" },
{ "----:com.apple.iTunes:LYRICIST", "LYRICIST" },

View File

@ -406,7 +406,11 @@ namespace
{ "MUSICBRAINZ ALBUM ID", "MUSICBRAINZ_ALBUMID" },
{ "MUSICBRAINZ ARTIST ID", "MUSICBRAINZ_ARTISTID" },
{ "MUSICBRAINZ ALBUM ARTIST ID", "MUSICBRAINZ_ALBUMARTISTID" },
{ "MUSICBRAINZ ALBUM RELEASE COUNTRY", "RELEASECOUNTRY" },
{ "MUSICBRAINZ ALBUM STATUS", "RELEASESTATUS" },
{ "MUSICBRAINZ ALBUM TYPE", "RELEASETYPE" },
{ "MUSICBRAINZ RELEASE GROUP ID", "MUSICBRAINZ_RELEASEGROUPID" },
{ "MUSICBRAINZ RELEASE TRACK ID", "MUSICBRAINZ_RELEASETRACKID" },
{ "MUSICBRAINZ WORK ID", "MUSICBRAINZ_WORKID" },
{ "ACOUSTID ID", "ACOUSTID_ID" },
{ "ACOUSTID FINGERPRINT", "ACOUSTID_FINGERPRINT" },

View File

@ -91,12 +91,16 @@ namespace TagLib {
* - LABEL
* - CATALOGNUMBER
* - BARCODE
* - RELEASECOUNTRY
* - RELEASESTATUS
* - RELEASETYPE
*
* MusicBrainz identifiers:
*
* - MUSICBRAINZ_TRACKID
* - MUSICBRAINZ_ALBUMID
* - MUSICBRAINZ_RELEASEGROUPID
* - MUSICBRAINZ_RELEASETRACKID
* - MUSICBRAINZ_WORKID
* - MUSICBRAINZ_ARTISTID
* - MUSICBRAINZ_ALBUMARTISTID

View File

@ -155,6 +155,58 @@ public:
}
}
void testProperties()
{
PropertyMap tags;
tags["ALBUM"] = StringList("Album");
tags["ALBUMARTIST"] = StringList("Album Artist");
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
tags["ALBUMSORT"] = StringList("Album Sort");
tags["ARTIST"] = StringList("Artist");
tags["ARTISTS"] = StringList("Artists");
tags["ARTISTSORT"] = StringList("Artist Sort");
tags["ASIN"] = StringList("ASIN");
tags["BARCODE"] = StringList("Barcode");
tags["CATALOGNUMBER"] = StringList("Catalog Number 1").append("Catalog Number 2");
tags["COMMENT"] = StringList("Comment");
tags["DATE"] = StringList("2021-01-10");
tags["DISCNUMBER"] = StringList("3/5");
tags["GENRE"] = StringList("Genre");
tags["ISRC"] = StringList("UKAAA0500001");
tags["LABEL"] = StringList("Label 1").append("Label 2");
tags["MEDIA"] = StringList("Media");
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
tags["ORIGINALDATE"] = StringList("2021-01-09");
tags["RELEASECOUNTRY"] = StringList("Release Country");
tags["RELEASESTATUS"] = StringList("Release Status");
tags["RELEASETYPE"] = StringList("Release Type");
tags["SCRIPT"] = StringList("Script");
tags["TITLE"] = StringList("Title");
tags["TRACKNUMBER"] = StringList("2/3");
ScopedFileCopy copy("mac-399", ".ape");
{
APE::File f(copy.fileName().c_str());
PropertyMap properties = f.properties();
CPPUNIT_ASSERT(properties.isEmpty());
f.setProperties(tags);
f.save();
}
{
const APE::File f(copy.fileName().c_str());
PropertyMap properties = f.properties();
if (tags != properties) {
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
}
CPPUNIT_ASSERT(tags == properties);
}
}
void testRepeatedSave()
{
ScopedFileCopy copy("mac-399", ".ape");

View File

@ -50,6 +50,7 @@ class TestASF : public CppUnit::TestFixture
CPPUNIT_TEST(testSavePicture);
CPPUNIT_TEST(testSaveMultiplePictures);
CPPUNIT_TEST(testProperties);
CPPUNIT_TEST(testPropertiesAllSupported);
CPPUNIT_TEST(testRepeatedSave);
CPPUNIT_TEST_SUITE_END();
@ -302,6 +303,84 @@ public:
CPPUNIT_ASSERT_EQUAL(StringList("3"), tags["DISCNUMBER"]);
}
void testPropertiesAllSupported()
{
PropertyMap tags;
tags["ACOUSTID_ID"] = StringList("Acoustid ID");
tags["ACOUSTID_FINGERPRINT"] = StringList("Acoustid Fingerprint");
tags["ALBUM"] = StringList("Album");
tags["ALBUMARTIST"] = StringList("Album Artist");
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
tags["ALBUMSORT"] = StringList("Album Sort");
tags["ARTIST"] = StringList("Artist");
tags["ARTISTS"] = StringList("Artists");
tags["ARTISTSORT"] = StringList("Artist Sort");
tags["ASIN"] = StringList("ASIN");
tags["BARCODE"] = StringList("Barcode");
tags["BPM"] = StringList("123");
tags["CATALOGNUMBER"] = StringList("Catalog Number");
tags["COMMENT"] = StringList("Comment");
tags["COMPOSER"] = StringList("Composer");
tags["CONDUCTOR"] = StringList("Conductor");
tags["COPYRIGHT"] = StringList("2021 Copyright");
tags["DATE"] = StringList("2021-01-03 12:29:23");
tags["DISCNUMBER"] = StringList("3/5");
tags["DISCSUBTITLE"] = StringList("Disc Subtitle");
tags["ENCODEDBY"] = StringList("Encoded by");
tags["GENRE"] = StringList("Genre");
tags["GROUPING"] = StringList("Grouping");
tags["ISRC"] = StringList("UKAAA0500001");
tags["LABEL"] = StringList("Label");
tags["LANGUAGE"] = StringList("eng");
tags["LYRICIST"] = StringList("Lyricist");
tags["LYRICS"] = StringList("Lyrics");
tags["MEDIA"] = StringList("Media");
tags["MOOD"] = StringList("Mood");
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
tags["MUSICBRAINZ_WORKID"] = StringList("MusicBrainz_WorkID");
tags["MUSICIP_PUID"] = StringList("MusicIP PUID");
tags["ORIGINALDATE"] = StringList("2021-01-03 13:52:19");
tags["PRODUCER"] = StringList("Producer");
tags["RELEASECOUNTRY"] = StringList("Release Country");
tags["RELEASESTATUS"] = StringList("Release Status");
tags["RELEASETYPE"] = StringList("Release Type");
tags["REMIXER"] = StringList("Remixer");
tags["SCRIPT"] = StringList("Script");
tags["SUBTITLE"] = StringList("Subtitle");
tags["TITLE"] = StringList("Title");
tags["TITLESORT"] = StringList("Title Sort");
tags["TRACKNUMBER"] = StringList("2/4");
ScopedFileCopy copy("silence-1", ".wma");
{
ASF::File f(copy.fileName().c_str());
ASF::Tag *asfTag = f.tag();
asfTag->setTitle("");
asfTag->attributeListMap().clear();
f.save();
}
{
ASF::File f(copy.fileName().c_str());
PropertyMap properties = f.properties();
CPPUNIT_ASSERT(properties.isEmpty());
f.setProperties(tags);
f.save();
}
{
const ASF::File f(copy.fileName().c_str());
PropertyMap properties = f.properties();
if (tags != properties) {
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
}
CPPUNIT_ASSERT(tags == properties);
}
}
void testRepeatedSave()
{
ScopedFileCopy copy("silence-1", ".wma");

View File

@ -54,6 +54,7 @@ class TestFLAC : public CppUnit::TestFixture
CPPUNIT_TEST(testRepeatedSave3);
CPPUNIT_TEST(testSaveMultipleValues);
CPPUNIT_TEST(testDict);
CPPUNIT_TEST(testProperties);
CPPUNIT_TEST(testInvalid);
CPPUNIT_TEST(testAudioProperties);
CPPUNIT_TEST(testZeroSizedPadding1);
@ -313,6 +314,60 @@ public:
}
}
void testProperties()
{
PropertyMap tags;
tags["ALBUM"] = StringList("Album");
tags["ALBUMARTIST"] = StringList("Album Artist");
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
tags["ALBUMSORT"] = StringList("Album Sort");
tags["ARTIST"] = StringList("Artist");
tags["ARTISTS"] = StringList("Artists");
tags["ARTISTSORT"] = StringList("Artist Sort");
tags["ASIN"] = StringList("ASIN");
tags["BARCODE"] = StringList("Barcode");
tags["CATALOGNUMBER"] = StringList("Catalog Number 1").append("Catalog Number 2");
tags["COMMENT"] = StringList("Comment");
tags["DATE"] = StringList("2021-01-10");
tags["DISCNUMBER"] = StringList("3");
tags["DISCTOTAL"] = StringList("5");
tags["GENRE"] = StringList("Genre");
tags["ISRC"] = StringList("UKAAA0500001");
tags["LABEL"] = StringList("Label 1").append("Label 2");
tags["MEDIA"] = StringList("Media");
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
tags["ORIGINALDATE"] = StringList("2021-01-09");
tags["RELEASECOUNTRY"] = StringList("Release Country");
tags["RELEASESTATUS"] = StringList("Release Status");
tags["RELEASETYPE"] = StringList("Release Type");
tags["SCRIPT"] = StringList("Script");
tags["TITLE"] = StringList("Title");
tags["TRACKNUMBER"] = StringList("2");
tags["TRACKTOTAL"] = StringList("4");
ScopedFileCopy copy("no-tags", ".flac");
{
FLAC::File f(copy.fileName().c_str());
PropertyMap properties = f.properties();
CPPUNIT_ASSERT(properties.isEmpty());
f.setProperties(tags);
f.save();
}
{
const FLAC::File f(copy.fileName().c_str());
PropertyMap properties = f.properties();
if (tags != properties) {
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
}
CPPUNIT_ASSERT(tags == properties);
}
}
void testInvalid()
{
ScopedFileCopy copy("silence-44-s", ".flac");

View File

@ -435,6 +435,7 @@ public:
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
tags["ALBUMSORT"] = StringList("Album Sort");
tags["ARTIST"] = StringList("Artist");
tags["ARTISTS"] = StringList("Artists");
tags["ARTISTSORT"] = StringList("Artist Sort");
tags["ASIN"] = StringList("ASIN");
tags["BARCODE"] = StringList("Barcode");
@ -471,14 +472,19 @@ public:
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
tags["MUSICBRAINZ_WORKID"] = StringList("MusicBrainz_WorkID");
tags["ORIGINALDATE"] = StringList("2021-01-03 13:52:19");
tags["PODCAST"] = StringList("1");
tags["PODCASTCATEGORY"] = StringList("Podcast Category");
tags["PODCASTDESC"] = StringList("Podcast Description");
tags["PODCASTID"] = StringList("Podcast ID");
tags["PODCASTURL"] = StringList("Podcast URL");
tags["PRODUCER"] = StringList("Producer");
tags["RELEASECOUNTRY"] = StringList("Release Country");
tags["RELEASESTATUS"] = StringList("Release Status");
tags["RELEASETYPE"] = StringList("Release Type");
tags["REMIXER"] = StringList("Remixer");
tags["SCRIPT"] = StringList("Script");
tags["SHOWSORT"] = StringList("Show Sort");

View File

@ -347,6 +347,7 @@ public:
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
tags["MUSICBRAINZ_WORKID"] = StringList("MusicBrainz_WorkID");
tags["ORIGINALALBUM"] = StringList("Original Album");
@ -369,6 +370,9 @@ public:
tags["PUBLISHERWEBPAGE"] = StringList("Publisher Web Page");
tags["RADIOSTATION"] = StringList("Radio Station");
tags["RADIOSTATIONOWNER"] = StringList("Radio Station Owner");
tags["RELEASECOUNTRY"] = StringList("Release Country");
tags["RELEASESTATUS"] = StringList("Release Status");
tags["RELEASETYPE"] = StringList("Release Type");
tags["REMIXER"] = StringList("Remixer");
tags["SCRIPT"] = StringList("Script");
tags["SUBTITLE"] = StringList("Subtitle");