From bf1eee45ba24a2a2a636a3f64428cbd9569f5b16 Mon Sep 17 00:00:00 2001 From: Martchus Date: Tue, 5 Apr 2022 23:30:37 +0200 Subject: [PATCH] Add field mappings for all fields mentioned in Matroska spec --- id3/id3v2frameids.cpp | 8 ++ id3/id3v2frameids.h | 5 + id3/id3v2tag.cpp | 28 ++++++ matroska/matroskatag.cpp | 207 +++++++++++++++++++++++++++++++++++++++ matroska/matroskatagid.h | 1 + mp4/mp4tag.cpp | 4 + tag.h | 73 +++++++++++++- vorbis/vorbiscomment.cpp | 6 ++ 8 files changed, 331 insertions(+), 1 deletion(-) diff --git a/id3/id3v2frameids.cpp b/id3/id3v2frameids.cpp index b6167ec..b447900 100644 --- a/id3/id3v2frameids.cpp +++ b/id3/id3v2frameids.cpp @@ -75,6 +75,10 @@ std::uint32_t convertToShortId(std::uint32_t id) return sRecordLabel; case lUserDefinedText: return sUserDefinedText; + case lRemixedBy: + return sRemixedBy; + case lCopyright: + return sCopyright; default: return 0; } @@ -135,6 +139,10 @@ std::uint32_t convertToLongId(std::uint32_t id) return lRecordLabel; case sUserDefinedText: return lUserDefinedText; + case sRemixedBy: + return lRemixedBy; + case sCopyright: + return lCopyright; default: return 0; } diff --git a/id3/id3v2frameids.h b/id3/id3v2frameids.h index 56b739f..6a9e790 100644 --- a/id3/id3v2frameids.h +++ b/id3/id3v2frameids.h @@ -42,6 +42,9 @@ enum KnownValue : std::uint32_t { lUniqueFileId = 0x55464944, /**< UFID */ lComposer = 0x54434f4d, /**< TCOM */ lRating = 0x504f504d, /**< POPM */ + lRemixedBy = 0x54504534, /**< TPE4 */ + lCopyright = 0x54434F50, /**< TCOP */ + lEncodingTime = 0x5444454E, /**< TDEN */ lUserDefinedText = 0x54585858, /**< TXXX */ sAlbum = 0x54414c, /**< ?TAL */ @@ -71,6 +74,8 @@ enum KnownValue : std::uint32_t { sUniqueFileId = 0x554649, /**< ?UFI */ sComposer = 0x54434d, /**< ?TCM */ sRating = 0x504f50, /**< ?POP */ + sRemixedBy = 0x545034, /**< TP4 */ + sCopyright = 0x544352, /**< TCR */ sUserDefinedText = 0x545858, /**< ?TXX */ }; diff --git a/id3/id3v2tag.cpp b/id3/id3v2tag.cpp index 799e894..345c525 100644 --- a/id3/id3v2tag.cpp +++ b/id3/id3v2tag.cpp @@ -180,6 +180,16 @@ Id3v2Tag::IdentifierType Id3v2Tag::internallyGetFieldId(KnownField field) const return lRating; case KnownField::AlbumArtist: return lAlbumArtist; + case KnownField::RemixedBy: + return lRemixedBy; + case KnownField::Copyright: + return lCopyright; + case KnownField::TaggingDate: + return lTaggingTime; + case KnownField::EncodingDate: + return lEncodingTime; + case KnownField::OriginalReleaseDate: + return lOriginalReleaseTime; default:; } } else { @@ -228,6 +238,10 @@ Id3v2Tag::IdentifierType Id3v2Tag::internallyGetFieldId(KnownField field) const return sRating; case KnownField::AlbumArtist: return sAlbumArtist; + case KnownField::RemixedBy: + return sRemixedBy; + case KnownField::Copyright: + return sCopyright; default:; } } @@ -275,10 +289,20 @@ KnownField Id3v2Tag::internallyGetKnownField(const IdentifierType &id) const return KnownField::SynchronizedLyrics; case lAlbumArtist: return KnownField::AlbumArtist; + case lRemixedBy: + return KnownField::RemixedBy; + case lCopyright: + return KnownField::Copyright; case lContentGroupDescription: return KnownField::Grouping; case lRecordLabel: return KnownField::RecordLabel; + case lTaggingTime: + return KnownField::TaggingDate; + case lEncodingTime: + return KnownField::EncodingDate; + case lOriginalReleaseTime: + return KnownField::OriginalReleaseDate; case sAlbum: return KnownField::Album; case sArtist: @@ -315,6 +339,10 @@ KnownField Id3v2Tag::internallyGetKnownField(const IdentifierType &id) const return KnownField::Grouping; case sRecordLabel: return KnownField::RecordLabel; + case sRemixedBy: + return KnownField::RemixedBy; + case sCopyright: + return KnownField::Copyright; default: return KnownField::Invalid; } diff --git a/matroska/matroskatag.cpp b/matroska/matroskatag.cpp index 55dc649..1c3c20f 100644 --- a/matroska/matroskatag.cpp +++ b/matroska/matroskatag.cpp @@ -65,6 +65,144 @@ MatroskaTag::IdentifierType MatroskaTag::internallyGetFieldId(KnownField field) return std::string(duration()); case KnownField::Language: return std::string(language()); + case KnownField::AlbumArtist: + return std::string(accompaniment()); + case KnownField::Subtitle: + return std::string(subtitle()); + case KnownField::LeadPerformer: + return std::string(leadPerformer()); + case KnownField::Arranger: + return std::string(arranger()); + case KnownField::Conductor: + return std::string(conductor()); + case KnownField::Director: + return std::string(director()); + case KnownField::AssistantDirector: + return std::string(assistantDirector()); + case KnownField::DirectorOfPhotography: + return std::string(directorOfPhotography()); + case KnownField::SoundEngineer: + return std::string(soundEngineer()); + case KnownField::ArtDirector: + return std::string(artDirector()); + case KnownField::ProductionDesigner: + return std::string(productionDesigner()); + case KnownField::Choregrapher: + return std::string(choregrapher()); + case KnownField::CostumeDesigner: + return std::string(costumeDesigner()); + case KnownField::Actor: + return std::string(actor()); + case KnownField::Character: + return std::string(character()); + case KnownField::WrittenBy: + return std::string(writtenBy()); + case KnownField::ScreenplayBy: + return std::string(screenplayBy()); + case KnownField::EditedBy: + return std::string(editedBy()); + case KnownField::Producer: + return std::string(producer()); + case KnownField::Coproducer: + return std::string(coproducer()); + case KnownField::ExecutiveProducer: + return std::string(executiveProducer()); + case KnownField::DistributedBy: + return std::string(distributedBy()); + case KnownField::MasteredBy: + return std::string(masteredBy()); + case KnownField::EncodedBy: + return std::string(encodedBy()); + case KnownField::MixedBy: + return std::string(mixedBy()); + case KnownField::RemixedBy: + return std::string(remixedBy()); + case KnownField::ProductionStudio: + return std::string(productionStudio()); + case KnownField::ThanksTo: + return std::string(thanksTo()); + case KnownField::Publisher: + return std::string(publisher()); + case KnownField::Mood: + return std::string(mood()); + case KnownField::OriginalMediaType: + return std::string(originalMediaType()); + case KnownField::ContentType: + return std::string(contentType()); + case KnownField::Subject: + return std::string(subject()); + case KnownField::Keywords: + return std::string(keywords()); + case KnownField::Summary: + return std::string(summary()); + case KnownField::Synopsis: + return std::string(synopsis()); + case KnownField::InitialKey: + return std::string(initialKey()); + case KnownField::Period: + return std::string(period()); + case KnownField::LawRating: + return std::string(lawRating()); + case KnownField::EncodingDate: + return std::string(dateEncoded()); + case KnownField::TaggingDate: + return std::string(dateTagged()); + case KnownField::DigitalizationDate: + return std::string(dateDigitized()); + case KnownField::WritingDate: + return std::string(dateWritten()); + case KnownField::PurchasingDate: + return std::string(datePurchased()); + case KnownField::RecordingLocation: + return std::string(recordingLocation()); + case KnownField::CompositionLocation: + return std::string(compositionLocation()); + case KnownField::ComposerNationality: + return std::string(composerNationality()); + case KnownField::PlayCounter: + return std::string(playCounter()); + case KnownField::Measure: + return std::string(measure()); + case KnownField::Tuning: + return std::string(tuning()); + case KnownField::ISRC: + return std::string(isrc()); + case KnownField::MCDI: + return std::string(mcdi()); + case KnownField::ISBN: + return std::string(isbn()); + case KnownField::Barcode: + return std::string(barcode()); + case KnownField::CatalogNumber: + return std::string(catalogNumber()); + case KnownField::LabelCode: + return std::string(labelCode()); + case KnownField::LCCN: + return std::string(lccn()); + case KnownField::IMDB: + return std::string(imdb()); + case KnownField::TMDB: + return std::string(tmdb()); + case KnownField::TVDB: + return std::string(tvdb()); + case KnownField::PurchaseItem: + return std::string(purchaseItem()); + case KnownField::PurchaseInfo: + return std::string(purchaseInfo()); + case KnownField::PurchaseOwner: + return std::string(purchaseOwner()); + case KnownField::PurchasePrice: + return std::string(purchasePrice()); + case KnownField::PurchaseCurrency: + return std::string(purchaseCurrency()); + case KnownField::Copyright: + return std::string(copyright()); + case KnownField::ProductionCopyright: + return std::string(productionCopyright()); + case KnownField::License: + return std::string(license()); + case KnownField::TermsOfUse: + return std::string(termsOfUse()); default: return std::string(); } @@ -95,6 +233,75 @@ KnownField MatroskaTag::internallyGetKnownField(const IdentifierType &id) const { composer(), KnownField::Composer }, { duration(), KnownField::Length }, { language(), KnownField::Language }, + { accompaniment(), KnownField::AlbumArtist }, + { subtitle(), KnownField::Subtitle }, + { leadPerformer(), KnownField::LeadPerformer }, + { arranger(), KnownField::Arranger }, + { conductor(), KnownField::Conductor }, + { director(), KnownField::Director }, + { assistantDirector(), KnownField::AssistantDirector }, + { directorOfPhotography(), KnownField::DirectorOfPhotography }, + { soundEngineer(), KnownField::SoundEngineer }, + { artDirector(), KnownField::ArtDirector }, + { productionDesigner(), KnownField::ProductionDesigner }, + { choregrapher(), KnownField::Choregrapher }, + { costumeDesigner(), KnownField::CostumeDesigner }, + { actor(), KnownField::Actor }, + { character(), KnownField::Character }, + { writtenBy(), KnownField::WrittenBy }, + { screenplayBy(), KnownField::ScreenplayBy }, + { editedBy(), KnownField::EditedBy }, + { producer(), KnownField::Producer }, + { coproducer(), KnownField::Coproducer }, + { executiveProducer(), KnownField::ExecutiveProducer }, + { distributedBy(), KnownField::DistributedBy }, + { masteredBy(), KnownField::MasteredBy }, + { encodedBy(), KnownField::EncodedBy }, + { mixedBy(), KnownField::MixedBy }, + { remixedBy(), KnownField::RemixedBy }, + { productionStudio(), KnownField::ProductionStudio }, + { thanksTo(), KnownField::ThanksTo }, + { publisher(), KnownField::Publisher }, + { mood(), KnownField::Mood }, + { originalMediaType(), KnownField::OriginalMediaType }, + { contentType(), KnownField::ContentType }, + { subject(), KnownField::Subject }, + { keywords(), KnownField::Keywords }, + { summary(), KnownField::Summary }, + { synopsis(), KnownField::Synopsis }, + { initialKey(), KnownField::InitialKey }, + { period(), KnownField::Period }, + { lawRating(), KnownField::LawRating }, + { dateEncoded(), KnownField::EncodingDate }, + { dateTagged(), KnownField::TaggingDate }, + { dateDigitized(), KnownField::DigitalizationDate }, + { dateWritten(), KnownField::WritingDate }, + { datePurchased(), KnownField::PurchasingDate }, + { recordingLocation(), KnownField::RecordingLocation }, + { compositionLocation(), KnownField::CompositionLocation }, + { composerNationality(), KnownField::ComposerNationality }, + { playCounter(), KnownField::PlayCounter }, + { measure(), KnownField::Measure }, + { tuning(), KnownField::Tuning }, + { isrc(), KnownField::ISRC }, + { mcdi(), KnownField::MCDI }, + { isbn(), KnownField::ISBN }, + { barcode(), KnownField::Barcode }, + { catalogNumber(), KnownField::CatalogNumber }, + { labelCode(), KnownField::LabelCode }, + { lccn(), KnownField::LCCN }, + { imdb(), KnownField::IMDB }, + { tmdb(), KnownField::TMDB }, + { tvdb(), KnownField::TVDB }, + { purchaseItem(), KnownField::PurchaseItem }, + { purchaseInfo(), KnownField::PurchaseInfo }, + { purchaseOwner(), KnownField::PurchaseOwner }, + { purchasePrice(), KnownField::PurchasePrice }, + { purchaseCurrency(), KnownField::PurchaseCurrency }, + { copyright(), KnownField::Copyright }, + { productionCopyright(), KnownField::ProductionCopyright }, + { license(), KnownField::License }, + { termsOfUse(), KnownField::TermsOfUse }, }); const auto knownField(fieldMap.find(id)); return knownField != fieldMap.cend() ? knownField->second : KnownField::Invalid; diff --git a/matroska/matroskatagid.h b/matroska/matroskatagid.h index ad3733f..adc43f1 100644 --- a/matroska/matroskatagid.h +++ b/matroska/matroskatagid.h @@ -270,6 +270,7 @@ constexpr TAG_PARSER_EXPORT std::string_view lawRating() { return "LAW_RATING"; } +/// \deprecated Not sure what this is or should have been. Remove in v12. constexpr TAG_PARSER_EXPORT std::string_view icra() { return "ICRA"; diff --git a/mp4/mp4tag.cpp b/mp4/mp4tag.cpp index 0b75f15..d00a4d9 100644 --- a/mp4/mp4tag.cpp +++ b/mp4/mp4tag.cpp @@ -160,6 +160,8 @@ Mp4Tag::IdentifierType Mp4Tag::internallyGetFieldId(KnownField field) const return Lyricist; case KnownField::AlbumArtist: return AlbumArtist; + case KnownField::Copyright: + return Copyright; default: return 0; } @@ -211,6 +213,8 @@ KnownField Mp4Tag::internallyGetKnownField(const IdentifierType &id) const return KnownField::Lyricist; case AlbumArtist: return KnownField::AlbumArtist; + case Copyright: + return KnownField::Copyright; default: return KnownField::Invalid; } diff --git a/tag.h b/tag.h index a529a3c..914e498 100644 --- a/tag.h +++ b/tag.h @@ -70,6 +70,75 @@ enum class KnownField : unsigned int { Vendor, /**< vendor */ AlbumArtist, /**< album artist */ ReleaseDate, /**< release date */ + Subtitle, /**< subtitle */ + LeadPerformer, /** lead performer */ + Arranger, /** the person who arranged the piece */ + Conductor, /** conductor */ + Director, /** director */ + AssistantDirector, /** assistant director */ + DirectorOfPhotography, /** director of photography */ + SoundEngineer, /** sound engineer */ + ArtDirector, /** art director */ + ProductionDesigner, /** production designer */ + Choregrapher, /** choregrapher */ + CostumeDesigner, /** costume designer */ + Actor, /** actor */ + Character, /** character */ + WrittenBy, /** written by */ + ScreenplayBy, /** screenplay by */ + EditedBy, /** edited by */ + Producer, /** producer */ + Coproducer, /** coproducer */ + ExecutiveProducer, /** executive producer */ + DistributedBy, /** distributed by */ + MasteredBy, /** mastered by */ + EncodedBy, /** encoded by */ + MixedBy, /** mixed by */ + RemixedBy, /** remixed by */ + ProductionStudio, /** production studio */ + ThanksTo, /** thanks to */ + Publisher, /** publisher */ + Mood, /** mood */ + OriginalMediaType, /** original media type */ + ContentType, /** content type */ + Subject, /** subject */ + Keywords, /** keywords */ + Summary, /** summary */ + Synopsis, /** synopsis */ + InitialKey, /** initial key */ + Period, /** period */ + LawRating, /** law rating */ + EncodingDate, /** encoding date */ + TaggingDate, /** tagging date */ + OriginalReleaseDate, /** original release date */ + DigitalizationDate, /** digitalization date */ + WritingDate, /** writing date */ + PurchasingDate, /** purchasing date */ + RecordingLocation, /** recording location */ + CompositionLocation, /** composition location */ + ComposerNationality, /** composer nationality */ + PlayCounter, /** play counter */ + Measure, /** measure */ + Tuning, /** tuning */ + ISRC, /** International Standard Recording Code */ + MCDI, /** binary dump of the TOC of the CDROM that this item was taken from */ + ISBN, /** International Standard Book Number */ + Barcode, /** barcode */ + CatalogNumber, /** catalog number */ + LabelCode, /** label code */ + LCCN, /** Library of Congress Control Number */ + IMDB, /** Internet Movie Database ID */ + TMDB, /** The Movie DB “movie_id” or “tv_id” identifier for movies/TV shows */ + TVDB, /** The TV Database “Series ID” or “Episode ID” identifier for TV shows */ + PurchaseItem, /** purchase item URL */ + PurchaseInfo, /** purchase info */ + PurchaseOwner, /** purchase owner */ + PurchasePrice, /** purchase price */ + PurchaseCurrency, /** purchase currency */ + Copyright, /** copyright */ + ProductionCopyright, /** production copyright */ + License, /** license */ + TermsOfUse, /** terms of use */ }; /*! @@ -80,7 +149,7 @@ constexpr KnownField firstKnownField = KnownField::Title; /*! * \brief The last valid entry in the TagParser::KnownField enum. */ -constexpr KnownField lastKnownField = KnownField::ReleaseDate; +constexpr KnownField lastKnownField = KnownField::TermsOfUse; /*! * \brief The number of valid entries in the TagParser::KnownField enum. @@ -229,6 +298,8 @@ inline TagDataType Tag::proposedDataType(KnownField field) const return TagDataType::PositionInSet; case KnownField::Genre: return TagDataType::StandardGenreIndex; + case KnownField::MCDI: + return TagDataType::Binary; case KnownField::SynchronizedLyrics: return TagDataType::Undefined; // not supported so far default: diff --git a/vorbis/vorbiscomment.cpp b/vorbis/vorbiscomment.cpp index ff177b2..fbc9ac2 100644 --- a/vorbis/vorbiscomment.cpp +++ b/vorbis/vorbiscomment.cpp @@ -91,6 +91,10 @@ VorbisComment::IdentifierType VorbisComment::internallyGetFieldId(KnownField fie return std::string(lyrics()); case KnownField::AlbumArtist: return std::string(albumArtist()); + case KnownField::Conductor: + return std::string(conductor()); + case KnownField::Copyright: + return std::string(copyright()); default: return std::string(); } @@ -122,6 +126,8 @@ KnownField VorbisComment::internallyGetKnownField(const IdentifierType &id) cons { lyricist(), KnownField::Lyricist }, { lyrics(), KnownField::Lyrics }, { albumArtist(), KnownField::AlbumArtist }, + { conductor(), KnownField::Conductor }, + { copyright(), KnownField::Copyright }, { copyright(), KnownField::Copyright }, }); // clang-format on const auto knownField(fieldMap.find(id));