musikr: use uppercase tag names
This reduces the amount of string processing I need to do in ktaglib.
This commit is contained in:
parent
65151e006f
commit
a2498db6e5
2 changed files with 87 additions and 88 deletions
|
@ -27,31 +27,31 @@ import org.oxycblt.musikr.tag.util.parseXiphPositionField
|
|||
|
||||
// Song
|
||||
fun Metadata.musicBrainzId() =
|
||||
(xiph["musicbrainz_releasetrackid"]
|
||||
?: xiph["musicbrainz release track id"]
|
||||
?: id3v2["TXXX:musicbrainz release track id"]
|
||||
?: id3v2["TXXX:musicbrainz_releasetrackid"])
|
||||
(xiph["MUSICBRAINZ_RELEASETRACKID"]
|
||||
?: xiph["MUSICBRAINZ RELEASE TRACK ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ RELEASE TRACK ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ_RELEASETRACKID"])
|
||||
?.first()
|
||||
|
||||
fun Metadata.name() = (xiph["title"] ?: id3v2["TIT2"])?.first()
|
||||
fun Metadata.name() = (xiph["TITLE"] ?: id3v2["TIT2"])?.first()
|
||||
|
||||
fun Metadata.sortName() = (xiph["titlesort"] ?: id3v2["TSOT"])?.first()
|
||||
fun Metadata.sortName() = (xiph["TITLESORT"] ?: id3v2["TSOT"])?.first()
|
||||
|
||||
// Track.
|
||||
fun Metadata.track() =
|
||||
(parseXiphPositionField(
|
||||
xiph["tracknumber"]?.first(),
|
||||
(xiph["totaltracks"] ?: xiph["tracktotal"] ?: xiph["trackc"])?.first())
|
||||
xiph["TRACKNUMBER"]?.first(),
|
||||
(xiph["TOTALTRACKS"] ?: xiph["TRACKTOTAL"] ?: xiph["TRACKC"])?.first())
|
||||
?: id3v2["TRCK"]?.run { first().parseId3v2PositionField() })
|
||||
|
||||
// Disc and it's subtitle name.
|
||||
fun Metadata.disc() =
|
||||
(parseXiphPositionField(
|
||||
xiph["discnumber"]?.first(),
|
||||
(xiph["totaldiscs"] ?: xiph["disctotal"] ?: xiph["discc"])?.run { first() })
|
||||
xiph["DISCNUMBER"]?.first(),
|
||||
(xiph["TOTALDISCS"] ?: xiph["DISCTOTAL"] ?: xiph["DISCC"])?.run { first() })
|
||||
?: id3v2["TPOS"]?.run { first().parseId3v2PositionField() })
|
||||
|
||||
fun Metadata.subtitle() = (xiph["discsubtitle"] ?: id3v2["TSST"])?.first()
|
||||
fun Metadata.subtitle() = (xiph["DISCSUBTITLE"] ?: id3v2["TSST"])?.first()
|
||||
|
||||
// Dates are somewhat complicated, as not only did their semantics change from a flat year
|
||||
// value in ID3v2.3 to a full ISO-8601 date in ID3v2.4, but there are also a variety of
|
||||
|
@ -66,9 +66,9 @@ fun Metadata.subtitle() = (xiph["discsubtitle"] ?: id3v2["TSST"])?.first()
|
|||
// TODO: Handle dates that are in "January" because the actual specific release date
|
||||
// isn't known?
|
||||
fun Metadata.date() =
|
||||
(xiph["originaldate"]?.run { Date.from(first()) }
|
||||
?: xiph["date"]?.run { Date.from(first()) }
|
||||
?: xiph["year"]?.run { Date.from(first()) }
|
||||
(xiph["ORIGINALDATE"]?.run { Date.from(first()) }
|
||||
?: xiph["DATE"]?.run { Date.from(first()) }
|
||||
?: xiph["YEAR"]?.run { Date.from(first()) }
|
||||
?:
|
||||
|
||||
// xiph dates are less complicated, but there are still several types
|
||||
|
@ -84,95 +84,95 @@ fun Metadata.date() =
|
|||
|
||||
// Album
|
||||
fun Metadata.albumMusicBrainzId() =
|
||||
(xiph["musicbrainz_albumid"]
|
||||
?: xiph["musicbrainz album id"]
|
||||
?: id3v2["TXXX:musicbrainz album id"]
|
||||
?: id3v2["TXXX:musicbrainz_albumid"])
|
||||
(xiph["MUSICBRAINZ_ALBUMID"]
|
||||
?: xiph["MUSICBRAINZ ALBUM ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ ALBUM ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ_ALBUMID"])
|
||||
?.first()
|
||||
|
||||
fun Metadata.albumName() = (xiph["album"] ?: id3v2["TALB"])?.first()
|
||||
fun Metadata.albumName() = (xiph["ALBUM"] ?: id3v2["TALB"])?.first()
|
||||
|
||||
fun Metadata.albumSortName() = (xiph["albumsort"] ?: id3v2["TSOA"])?.first()
|
||||
fun Metadata.albumSortName() = (xiph["ALBUMSORT"] ?: id3v2["TSOA"])?.first()
|
||||
|
||||
fun Metadata.releaseTypes() =
|
||||
(xiph["releasetype"]
|
||||
?: xiph["musicbrainz album type"]
|
||||
?: id3v2["TXXX:musicbrainz album type"]
|
||||
?: id3v2["TXXX:releasetype"]
|
||||
(xiph["RELEASETYPE"]
|
||||
?: xiph["MUSICBRAINZ ALBUM TYPE"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ ALBUM TYPE"]
|
||||
?: id3v2["TXXX:RELEASETYPE"]
|
||||
?:
|
||||
// This is a non-standard iTunes extension
|
||||
id3v2["GRP1"])
|
||||
|
||||
// Artist
|
||||
fun Metadata.artistMusicBrainzIds() =
|
||||
(xiph["musicbrainz_artistid"]
|
||||
?: xiph["musicbrainz artist id"]
|
||||
?: id3v2["TXXX:musicbrainz artist id"]
|
||||
?: id3v2["TXXX:musicbrainz_artistid"])
|
||||
(xiph["MUSICBRAINZ_ARTISTID"]
|
||||
?: xiph["MUSICBRAINZ ARTIST ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ ARTIST ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ_ARTISTID"])
|
||||
|
||||
fun Metadata.artistNames() =
|
||||
(xiph["artists"]
|
||||
?: xiph["artist"]
|
||||
?: id3v2["TXXX:artists"]
|
||||
(xiph["ARTISTS"]
|
||||
?: xiph["ARTIST"]
|
||||
?: id3v2["TXXX:ARTISTS"]
|
||||
?: id3v2["TPE1"]
|
||||
?: id3v2["TXXX:artist"])
|
||||
?: id3v2["TXXX:ARTIST"])
|
||||
|
||||
fun Metadata.artistSortNames() =
|
||||
(xiph["artistssort"]
|
||||
?: xiph["artists_sort"]
|
||||
?: xiph["artists sort"]
|
||||
?: xiph["artistsort"]
|
||||
?: xiph["artist sort"]
|
||||
?: id3v2["TXXX:artistssort"]
|
||||
?: id3v2["TXXX:artists_sort"]
|
||||
?: id3v2["TXXX:artists sort"]
|
||||
(xiph["ARTISTSSORT"]
|
||||
?: xiph["ARTISTS_SORT"]
|
||||
?: xiph["ARTISTS SORT"]
|
||||
?: xiph["ARTISTSORT"]
|
||||
?: xiph["ARTIST SORT"]
|
||||
?: id3v2["TXXX:ARTISTSSORT"]
|
||||
?: id3v2["TXXX:ARTISTS_SORT"]
|
||||
?: id3v2["TXXX:ARTISTS SORT"]
|
||||
?: id3v2["TSOP"]
|
||||
?: id3v2["artistsort"]
|
||||
?: id3v2["TXXX:artist sort"])
|
||||
?: id3v2["TXXX:ARTISTSORT"]
|
||||
?: id3v2["TXXX:ARTIST SORT"])
|
||||
|
||||
fun Metadata.albumArtistMusicBrainzIds() =
|
||||
(xiph["musicbrainz_albumartistid"]
|
||||
?: xiph["musicbrainz album artist id"]
|
||||
?: id3v2["TXXX:musicbrainz album artist id"]
|
||||
?: id3v2["TXXX:musicbrainz_albumartistid"])
|
||||
(xiph["MUSICBRAINZ_ALBUMARTISTID"]
|
||||
?: xiph["MUSICBRAINZ ALBUM ARTIST ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ ALBUM ARTIST ID"]
|
||||
?: id3v2["TXXX:MUSICBRAINZ_ALBUMARTISTID"])
|
||||
|
||||
fun Metadata.albumArtistNames() =
|
||||
(xiph["albumartists"]
|
||||
?: xiph["album_artists"]
|
||||
?: xiph["album artists"]
|
||||
?: xiph["albumartist"]
|
||||
?: xiph["album artist"]
|
||||
?: id3v2["TXXX:albumartists"]
|
||||
?: id3v2["TXXX:album_artists"]
|
||||
?: id3v2["TXXX:album artists"]
|
||||
(xiph["ALBUMARTISTS"]
|
||||
?: xiph["ALBUM_ARTISTS"]
|
||||
?: xiph["ALBUM ARTISTS"]
|
||||
?: xiph["ALBUMARTIST"]
|
||||
?: xiph["ALBUM ARTIST"]
|
||||
?: id3v2["TXXX:ALBUMARTISTS"]
|
||||
?: id3v2["TXXX:ALBUM_ARTISTS"]
|
||||
?: id3v2["TXXX:ALBUM ARTISTS"]
|
||||
?: id3v2["TPE2"]
|
||||
?: id3v2["TXXX:albumartist"]
|
||||
?: id3v2["TXXX:album artist"])
|
||||
?: id3v2["TXXX:ALBUMARTIST"]
|
||||
?: id3v2["TXXX:ALBUM ARTIST"])
|
||||
|
||||
fun Metadata.albumArtistSortNames() =
|
||||
(xiph["albumartistssort"]
|
||||
?: xiph["albumartists_sort"]
|
||||
?: xiph["albumartists sort"]
|
||||
?: xiph["albumartistsort"]
|
||||
?: xiph["album artist sort"]
|
||||
?: id3v2["TXXX:albumartistssort"]
|
||||
?: id3v2["TXXX:albumartists_sort"]
|
||||
?: id3v2["TXXX:albumartists sort"]
|
||||
?: id3v2["TXXX:albumartistsort"]
|
||||
(xiph["ALBUMARTISTSSORT"]
|
||||
?: xiph["ALBUMARTISTS_SORT"]
|
||||
?: xiph["ALBUMARTISTS SORT"]
|
||||
?: xiph["ALBUMARTISTSORT"]
|
||||
?: xiph["ALBUM ARTIST SORT"]
|
||||
?: id3v2["TXXX:ALBUMARTISTSSORT"]
|
||||
?: id3v2["TXXX:ALBUMARTISTS_SORT"]
|
||||
?: id3v2["TXXX:ALBUMARTISTS SORT"]
|
||||
?: id3v2["TXXX:ALBUMARTISTSORT"]
|
||||
// This is a non-standard iTunes extension
|
||||
?: id3v2["TSO2"]
|
||||
?: id3v2["TXXX:album artist sort"])
|
||||
?: id3v2["TXXX:ALBUM ARTIST SORT"])
|
||||
|
||||
// Genre
|
||||
fun Metadata.genreNames() = xiph["genre"] ?: id3v2["TCON"]
|
||||
fun Metadata.genreNames() = xiph["GENRE"] ?: id3v2["TCON"]
|
||||
|
||||
// Compilation Flag
|
||||
fun Metadata.isCompilation() =
|
||||
(xiph["compilation"]
|
||||
?: xiph["itunescompilation"]
|
||||
(xiph["COMPILATION"]
|
||||
?: xiph["ITUNESCOMPILATION"]
|
||||
?: id3v2["TCMP"] // This is a non-standard itunes extension
|
||||
?: id3v2["TXXX:compilation"]
|
||||
?: id3v2["TXXX:itunescompilation"])
|
||||
?: id3v2["TXXX:COMPILATION"]
|
||||
?: id3v2["TXXX:ITUNESCOMPILATION"])
|
||||
?.let {
|
||||
// Ignore invalid instances of this tag
|
||||
it == listOf("1")
|
||||
|
@ -180,14 +180,14 @@ fun Metadata.isCompilation() =
|
|||
|
||||
// ReplayGain information
|
||||
fun Metadata.replayGainTrackAdjustment() =
|
||||
(xiph["r128_track_gain"]?.parseR128Adjustment()
|
||||
?: xiph["replaygain_track_gain"]?.parseReplayGainAdjustment()
|
||||
?: id3v2["TXXX:replaygain_track_gain"]?.parseReplayGainAdjustment())
|
||||
(xiph["R128_TRACK_GAIN"]?.parseR128Adjustment()
|
||||
?: xiph["REPLAYGAIN_TRACK_GAIN"]?.parseReplayGainAdjustment()
|
||||
?: id3v2["TXXX:REPLAYGAIN_TRACK_GAIN"]?.parseReplayGainAdjustment())
|
||||
|
||||
fun Metadata.replayGainAlbumAdjustment() =
|
||||
(xiph["r128_album_gain"]?.parseR128Adjustment()
|
||||
?: xiph["replaygain_album_gain"]?.parseReplayGainAdjustment()
|
||||
?: id3v2["TXXX:replaygain_album_gain"]?.parseReplayGainAdjustment())
|
||||
(xiph["R128_ALBUM_GAIN"]?.parseR128Adjustment()
|
||||
?: xiph["REPLAYGAIN_ALBUM_GAIN"]?.parseReplayGainAdjustment()
|
||||
?: id3v2["TXXX:REPLAYGAIN_ALBUM_GAIN"]?.parseReplayGainAdjustment())
|
||||
|
||||
private fun Metadata.parseId3v23Date(): Date? {
|
||||
// Assume that TDAT/TIME can refer to TYER or TORY depending on if TORY
|
||||
|
|
|
@ -17,12 +17,11 @@ void JVMMetadataBuilder::setMimeType(const std::string_view mimeType) {
|
|||
void JVMMetadataBuilder::setId3v2(const TagLib::ID3v2::Tag &tag) {
|
||||
for (auto frame: tag.frameList()) {
|
||||
if (auto txxxFrame = dynamic_cast<TagLib::ID3v2::UserTextIdentificationFrame *>(frame)) {
|
||||
TagLib::String desc = std::string(txxxFrame->description().toCString(true));
|
||||
// Make desc lowercase
|
||||
std::transform(desc.begin(), desc.end(), desc.begin(), ::tolower);
|
||||
TagLib::String key = TagLib::String(frame->frameID()) + ":" + desc;
|
||||
TagLib::StringList frameText = txxxFrame->fieldList();
|
||||
frameText.erase(frameText.begin()); // Remove description that exists for some insane reason
|
||||
// Frame text starts with the description then the remaining values
|
||||
auto begin = frameText.begin();
|
||||
TagLib::String key = TagLib::String(frame->frameID()) + ":" + begin->upper();
|
||||
frameText.erase(begin);
|
||||
id3v2.add(key, frameText);
|
||||
} else if (auto textFrame = dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(frame)) {
|
||||
TagLib::String key = frame->frameID();
|
||||
|
@ -36,11 +35,9 @@ void JVMMetadataBuilder::setId3v2(const TagLib::ID3v2::Tag &tag) {
|
|||
|
||||
void JVMMetadataBuilder::setXiph(const TagLib::Ogg::XiphComment &tag) {
|
||||
for (auto field: tag.fieldListMap()) {
|
||||
auto fieldName = std::string(field.first.toCString(true));
|
||||
std::transform(fieldName.begin(), fieldName.end(), fieldName.begin(), ::tolower);
|
||||
auto taglibFieldName = TagLib::String(fieldName);
|
||||
auto fieldValue = field.second;
|
||||
xiph.add(taglibFieldName, fieldValue);
|
||||
auto key = field.first.upper();
|
||||
auto values = field.second;
|
||||
xiph.add(key, values);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +47,8 @@ void JVMMetadataBuilder::setMp4(const TagLib::MP4::Tag &tag) {
|
|||
auto itemValue = item.second;
|
||||
auto type = itemValue.type();
|
||||
|
||||
// TODO: Handle internal atoms
|
||||
|
||||
// Only read out the atoms for the reasonable tags we are expecting.
|
||||
// None of the crazy binary atoms.
|
||||
if (type == TagLib::MP4::Item::Type::StringList) {
|
||||
|
@ -125,7 +124,7 @@ jobject JVMMetadataBuilder::build() {
|
|||
jobject mp4Map = mp4.getObject();
|
||||
jbyteArray coverArray = nullptr;
|
||||
if (cover.has_value()) {
|
||||
coverArray = env->NewByteArray(cover->size());
|
||||
coverArray = env->NewByteArray(static_cast<jsize>(cover->size());
|
||||
env->SetByteArrayRegion(coverArray, 0, cover->size(), reinterpret_cast<const jbyte *>(cover->data()));
|
||||
}
|
||||
jobject metadataObj = env->NewObject(metadataClass, metadataInit, id3v2Map, xiphMap, mp4Map, coverArray, propertiesObj);
|
||||
|
|
Loading…
Reference in a new issue