diff --git a/app/src/main/java/org/oxycblt/musikr/tag/parse/ExoPlayerTagFields.kt b/app/src/main/java/org/oxycblt/musikr/tag/parse/ExoPlayerTagFields.kt index 76f72fb16..f8f309cef 100644 --- a/app/src/main/java/org/oxycblt/musikr/tag/parse/ExoPlayerTagFields.kt +++ b/app/src/main/java/org/oxycblt/musikr/tag/parse/ExoPlayerTagFields.kt @@ -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 diff --git a/ktaglib/src/main/cpp/JVMMetadataBuilder.cpp b/ktaglib/src/main/cpp/JVMMetadataBuilder.cpp index 78a9ed626..21083fd49 100644 --- a/ktaglib/src/main/cpp/JVMMetadataBuilder.cpp +++ b/ktaglib/src/main/cpp/JVMMetadataBuilder.cpp @@ -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(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(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(cover->size()); env->SetByteArrayRegion(coverArray, 0, cover->size(), reinterpret_cast(cover->data())); } jobject metadataObj = env->NewObject(metadataClass, metadataInit, id3v2Map, xiphMap, mp4Map, coverArray, propertiesObj);