diff --git a/taglib/mp4/mp4itemfactory.cpp b/taglib/mp4/mp4itemfactory.cpp index b940a32c..dbf3d6f9 100644 --- a/taglib/mp4/mp4itemfactory.cpp +++ b/taglib/mp4/mp4itemfactory.cpp @@ -35,6 +35,12 @@ using namespace TagLib; using namespace MP4; +namespace { + +constexpr char freeFormPrefix[] = "----:com.apple.iTunes:"; + +} // namespace + class ItemFactory::ItemFactoryPrivate { public: @@ -231,7 +237,11 @@ String ItemFactory::propertyKeyForName(const ByteVector &name) const if(d->propertyKeyForName.isEmpty()) { d->propertyKeyForName = namePropertyMap(); } - return d->propertyKeyForName.value(name); + String key = d->propertyKeyForName.value(name); + if(key.isEmpty() && name.startsWith(freeFormPrefix)) { + key = name.mid(std::size(freeFormPrefix) - 1); + } + return key; } ByteVector ItemFactory::nameForPropertyKey(const String &key) const @@ -244,7 +254,14 @@ ByteVector ItemFactory::nameForPropertyKey(const String &key) const d->nameForPropertyKey[t] = k; } } - return d->nameForPropertyKey.value(key); + ByteVector name = d->nameForPropertyKey.value(key); + if(name.isEmpty() && !key.isEmpty()) { + const auto &firstChar = key[0]; + if(firstChar >= 'A' && firstChar <= 'Z') { + name = (freeFormPrefix + key).data(String::UTF8); + } + } + return name; } //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/test_mp4.cpp b/tests/test_mp4.cpp index ea4a8d0a..03f96ae5 100644 --- a/tests/test_mp4.cpp +++ b/tests/test_mp4.cpp @@ -442,6 +442,7 @@ public: tags["BPM"] = StringList("123"); tags["ARTIST"] = StringList("Foo Bar"); tags["COMPILATION"] = StringList("1"); + tags["REMIXEDBY"] = StringList("Remixed by"); f.setProperties(tags); tags = f.properties(); @@ -468,6 +469,11 @@ public: CPPUNIT_ASSERT_EQUAL(true, f.tag()->item("cpil").toBool()); CPPUNIT_ASSERT_EQUAL(StringList("1"), tags["COMPILATION"]); + CPPUNIT_ASSERT(f.tag()->contains("----:com.apple.iTunes:REMIXEDBY")); + CPPUNIT_ASSERT_EQUAL(StringList("Remixed by"), + f.tag()->item("----:com.apple.iTunes:REMIXEDBY").toStringList()); + CPPUNIT_ASSERT_EQUAL(StringList("Remixed by"), tags["REMIXEDBY"]); + tags["COMPILATION"] = StringList("0"); f.setProperties(tags);