public Dictionary <string, string> GetAllMetaTagsDataFormatted() // Returns all metadata of the track in a formatted, displayable manner { Dictionary <string, string> allTags = new Dictionary <string, string>(); allTags.Add(nameof(Title), Title.ToString()); allTags.Add(nameof(Album), Album.ToString()); allTags.Add(nameof(Copyright), Copyright.ToString()); allTags.Add(nameof(AlbumArtists), AlbumArtists.ToString()); allTags.Add(nameof(AlbumArtistsSort), AlbumArtistsSort.ToString()); allTags.Add(nameof(Genres), Genres.ToString()); allTags.Add(nameof(BeatsPerMinute), BeatsPerMinute.ToString()); allTags.Add(nameof(Year), Year.ToString()); allTags.Add(nameof(Track), Track.ToString()); allTags.Add(nameof(TrackCount), TrackCount.ToString()); allTags.Add(nameof(Disc), Disc.ToString()); allTags.Add(nameof(DiscCount), DiscCount.ToString()); allTags.Add(nameof(MusicBrainzReleaseArtistId), MusicBrainzReleaseArtistId.ToString()); allTags.Add(nameof(MusicBrainzTrackId), MusicBrainzTrackId.ToString()); allTags.Add(nameof(MusicBrainzDiscId), MusicBrainzDiscId.ToString()); allTags.Add(nameof(MusicBrainzReleaseStatus), MusicBrainzReleaseStatus.ToString()); allTags.Add(nameof(MusicBrainzReleaseType), MusicBrainzReleaseType.ToString()); allTags.Add(nameof(MusicBrainzReleaseCountry), MusicBrainzReleaseCountry.ToString()); allTags.Add(nameof(MusicBrainzReleaseId), MusicBrainzReleaseId.ToString()); allTags.Add(nameof(MusicBrainzArtistId), MusicBrainzArtistId.ToString()); return(allTags); }
public void Read(string path) { Logger.Debug($"Starting tag read for {path}"); IsValid = false; TagLib.File file = null; try { file = TagLib.File.Create(path); var tag = file.Tag; Title = tag.Title ?? tag.TitleSort; Performers = tag.Performers ?? tag.PerformersSort; AlbumArtists = tag.AlbumArtists ?? tag.AlbumArtistsSort; Track = tag.Track; TrackCount = tag.TrackCount; Album = tag.Album ?? tag.AlbumSort; Disc = tag.Disc; DiscCount = tag.DiscCount; Year = tag.Year; Publisher = tag.Publisher; Duration = file.Properties.Duration; Genres = tag.Genres; ImageSize = tag.Pictures.FirstOrDefault()?.Data.Count ?? 0; MusicBrainzReleaseCountry = tag.MusicBrainzReleaseCountry; MusicBrainzReleaseStatus = tag.MusicBrainzReleaseStatus; MusicBrainzReleaseType = tag.MusicBrainzReleaseType; MusicBrainzReleaseId = tag.MusicBrainzReleaseId; MusicBrainzArtistId = tag.MusicBrainzArtistId; MusicBrainzReleaseArtistId = tag.MusicBrainzReleaseArtistId; MusicBrainzReleaseGroupId = tag.MusicBrainzReleaseGroupId; MusicBrainzTrackId = tag.MusicBrainzTrackId; DateTime tempDate; // Do the ones that aren't handled by the generic taglib implementation if (file.TagTypesOnDisk.HasFlag(TagTypes.Id3v2)) { var id3tag = (TagLib.Id3v2.Tag)file.GetTag(TagTypes.Id3v2); Media = id3tag.GetTextAsString("TMED"); Date = ReadId3Date(id3tag, "TDRC"); OriginalReleaseDate = ReadId3Date(id3tag, "TDOR"); MusicBrainzAlbumComment = UserTextInformationFrame.Get(id3tag, "MusicBrainz Album Comment", false)?.Text.ExclusiveOrDefault(); MusicBrainzReleaseTrackId = UserTextInformationFrame.Get(id3tag, "MusicBrainz Release Track Id", false)?.Text.ExclusiveOrDefault(); } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Xiph)) { // while publisher is handled by taglib, it seems to be mapped to 'ORGANIZATION' and not 'LABEL' like Picard is // https://picard.musicbrainz.org/docs/mappings/ var flactag = (TagLib.Ogg.XiphComment)file.GetTag(TagLib.TagTypes.Xiph); Media = flactag.GetField("MEDIA").ExclusiveOrDefault(); Date = DateTime.TryParse(flactag.GetField("DATE").ExclusiveOrDefault(), out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(flactag.GetField("ORIGINALDATE").ExclusiveOrDefault(), out tempDate) ? tempDate : default(DateTime?); Publisher = flactag.GetField("LABEL").ExclusiveOrDefault(); MusicBrainzAlbumComment = flactag.GetField("MUSICBRAINZ_ALBUMCOMMENT").ExclusiveOrDefault(); MusicBrainzReleaseTrackId = flactag.GetField("MUSICBRAINZ_RELEASETRACKID").ExclusiveOrDefault(); // If we haven't managed to read status/type, try the alternate mapping if (MusicBrainzReleaseStatus.IsNullOrWhiteSpace()) { MusicBrainzReleaseStatus = flactag.GetField("RELEASESTATUS").ExclusiveOrDefault(); } if (MusicBrainzReleaseType.IsNullOrWhiteSpace()) { MusicBrainzReleaseType = flactag.GetField("RELEASETYPE").ExclusiveOrDefault(); } } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Ape)) { var apetag = (TagLib.Ape.Tag)file.GetTag(TagTypes.Ape); Media = apetag.GetItem("Media")?.ToString(); Date = DateTime.TryParse(apetag.GetItem("Year")?.ToString(), out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(apetag.GetItem("Original Date")?.ToString(), out tempDate) ? tempDate : default(DateTime?); Publisher = apetag.GetItem("Label")?.ToString(); MusicBrainzAlbumComment = apetag.GetItem("MUSICBRAINZ_ALBUMCOMMENT")?.ToString(); MusicBrainzReleaseTrackId = apetag.GetItem("MUSICBRAINZ_RELEASETRACKID")?.ToString(); } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Asf)) { var asftag = (TagLib.Asf.Tag)file.GetTag(TagTypes.Asf); Media = asftag.GetDescriptorString("WM/Media"); Date = DateTime.TryParse(asftag.GetDescriptorString("WM/Year"), out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(asftag.GetDescriptorString("WM/OriginalReleaseTime"), out tempDate) ? tempDate : default(DateTime?); Publisher = asftag.GetDescriptorString("WM/Publisher"); MusicBrainzAlbumComment = asftag.GetDescriptorString("MusicBrainz/Album Comment"); MusicBrainzReleaseTrackId = asftag.GetDescriptorString("MusicBrainz/Release Track Id"); } else if (file.TagTypesOnDisk.HasFlag(TagTypes.Apple)) { var appletag = (TagLib.Mpeg4.AppleTag)file.GetTag(TagTypes.Apple); Media = appletag.GetDashBox("com.apple.iTunes", "MEDIA"); Date = DateTime.TryParse(appletag.DataBoxes(FixAppleId("day")).FirstOrDefault()?.Text, out tempDate) ? tempDate : default(DateTime?); OriginalReleaseDate = DateTime.TryParse(appletag.GetDashBox("com.apple.iTunes", "Original Date"), out tempDate) ? tempDate : default(DateTime?); MusicBrainzAlbumComment = appletag.GetDashBox("com.apple.iTunes", "MusicBrainz Album Comment"); MusicBrainzReleaseTrackId = appletag.GetDashBox("com.apple.iTunes", "MusicBrainz Release Track Id"); } OriginalYear = OriginalReleaseDate.HasValue ? (uint)OriginalReleaseDate?.Year : 0; foreach (ICodec codec in file.Properties.Codecs) { IAudioCodec acodec = codec as IAudioCodec; if (acodec != null && (acodec.MediaTypes & MediaTypes.Audio) != MediaTypes.None) { int bitrate = acodec.AudioBitrate; if (bitrate == 0) { // Taglib can't read bitrate for Opus. bitrate = EstimateBitrate(file, path); } Logger.Debug("Audio Properties: " + acodec.Description + ", Bitrate: " + bitrate + ", Sample Size: " + file.Properties.BitsPerSample + ", SampleRate: " + acodec.AudioSampleRate + ", Channels: " + acodec.AudioChannels); Quality = QualityParser.ParseQuality(file.Name, acodec.Description, bitrate, file.Properties.BitsPerSample); Logger.Debug($"Quality parsed: {Quality}, Source: {Quality.QualityDetectionSource}"); MediaInfo = new MediaInfoModel { AudioFormat = acodec.Description, AudioBitrate = bitrate, AudioChannels = acodec.AudioChannels, AudioBits = file.Properties.BitsPerSample, AudioSampleRate = acodec.AudioSampleRate }; } } IsValid = true; } catch (Exception ex) { if (ex is CorruptFileException) { Logger.Warn(ex, $"Tag reading failed for {path}. File is corrupt"); } else { // Log as error so it goes to sentry with correct fingerprint Logger.Error(ex, "Tag reading failed for {0}", path); } } finally { file?.Dispose(); } // make sure these are initialized to avoid errors later on if (Quality == null) { Quality = QualityParser.ParseQuality(path, null, EstimateBitrate(file, path)); Logger.Debug($"Unable to parse qulity from tag, Quality parsed from file path: {Quality}, Source: {Quality.QualityDetectionSource}"); } MediaInfo = MediaInfo ?? new MediaInfoModel(); }