public static void Write(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { if (file.TagTypes.HasFlag(TagTypes.Id3v2)) { var tag = GetTag <global::TagLib.Id3v2.Tag>(file, TagTypes.Id3v2); var frames = tag.GetFrames <global::TagLib.Id3v2.PopularimeterFrame>(); if (frames != null && frames.Any()) { foreach (var frame in frames) { WritePopularimeterFrame(source, metaDataItem, file, frame); } } else { var frame = new global::TagLib.Id3v2.PopularimeterFrame(string.Empty); WritePopularimeterFrame(source, metaDataItem, file, frame); tag.AddFrame(frame); } } else { WriteCustomTag(metaDataItem.Name, metaDataItem.Value, file); } }
public static void Read(TagLibMetaDataSource source, IList <MetaDataItem> metaData, File file) { if (file.TagTypes.HasFlag(TagTypes.Id3v2)) { var tag = GetTag <global::TagLib.Id3v2.Tag>(file, TagTypes.Id3v2); if (tag == null) { return; } foreach (var frame in tag.GetFrames <global::TagLib.Id3v2.PopularimeterFrame>()) { ReadPopularimeterFrame(source, metaData, file, frame); } } else { var rating = ReadCustomTag(CommonMetaData.Rating, file); if (!string.IsNullOrEmpty(rating)) { source.AddTag(metaData, CommonMetaData.Rating, rating); } var playCount = ReadCustomTag(CommonMetaData.PlayCount, file); if (!string.IsNullOrEmpty(playCount)) { source.AddTag(metaData, CommonMetaData.Rating, playCount); } } }
public static async Task <bool> Read(TagLibMetaDataSource source, IList <MetaDataItem> metaDatas, File file) { var embedded = source.EmbeddedImages.Value; var loose = source.LooseImages.Value; if (embedded && loose) { switch (MetaDataBehaviourConfiguration.GetImagesPreference(source.ImagesPreference.Value)) { default: case ImagePreference.Embedded: return(await ReadEmbedded(source, metaDatas, file).ConfigureAwait(false) || await ReadLoose(source, metaDatas, file).ConfigureAwait(false)); case ImagePreference.Loose: return(await ReadLoose(source, metaDatas, file).ConfigureAwait(false) || await ReadEmbedded(source, metaDatas, file).ConfigureAwait(false)); } } else if (embedded) { return(await ReadEmbedded(source, metaDatas, file).ConfigureAwait(false)); } else if (loose) { return(await ReadLoose(source, metaDatas, file).ConfigureAwait(false)); } return(false); }
public override IMetaDataSource Create() { var source = new TagLibMetaDataSource(); source.InitializeComponent(this.Core); return(source); }
public static void Write(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { if (file.TagTypes.HasFlag(TagTypes.Id3v2) && (new[] { CommonStatistics.Rating, CommonStatistics.PlayCount }).Contains(metaDataItem.Name, StringComparer.OrdinalIgnoreCase)) { var tag = TagManager.GetTag <global::TagLib.Id3v2.Tag>(file, TagTypes.Id3v2); var frames = tag.GetFrames <global::TagLib.Id3v2.PopularimeterFrame>(); if (frames != null && frames.Any()) { foreach (var frame in frames) { WritePopularimeterFrame(frame, metaDataItem); } } else { var frame = new global::TagLib.Id3v2.PopularimeterFrame(string.Empty); WritePopularimeterFrame(frame, metaDataItem); tag.AddFrame(frame); } } else if (string.Equals(metaDataItem.Name, CommonStatistics.Rating, StringComparison.OrdinalIgnoreCase)) { TagManager.WriteCustomTag(metaDataItem.Name, Convert.ToString(GetRatingMask(metaDataItem.Value)), file); } else { TagManager.WriteCustomTag(metaDataItem.Name, metaDataItem.Value, file); } }
public static async Task Write(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { var embedded = source.EmbeddedImages.Value; var loose = source.LooseImages.Value; if (embedded && loose) { switch (MetaDataBehaviourConfiguration.GetImagesPreference(source.ImagesPreference.Value)) { default: case ImagePreference.Embedded: await WriteEmbedded(source, metaDataItem, file).ConfigureAwait(false); break; case ImagePreference.Loose: WriteLoose(source, metaDataItem, file); break; } } else if (embedded) { await WriteEmbedded(source, metaDataItem, file).ConfigureAwait(false); } else if (loose) { WriteLoose(source, metaDataItem, file); } }
public static void Write(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { var tag = file.Tag; var value = default(double); if (string.IsNullOrEmpty(metaDataItem.Value)) { value = double.NaN; } else if (!double.TryParse(metaDataItem.Value, out value)) { value = double.NaN; } if (string.Equals(metaDataItem.Name, CommonMetaData.ReplayGainAlbumGain, StringComparison.OrdinalIgnoreCase)) { tag.ReplayGainAlbumGain = value; } else if (string.Equals(metaDataItem.Name, CommonMetaData.ReplayGainAlbumPeak, StringComparison.OrdinalIgnoreCase)) { tag.ReplayGainAlbumPeak = value; } else if (string.Equals(metaDataItem.Name, CommonMetaData.ReplayGainTrackGain, StringComparison.OrdinalIgnoreCase)) { tag.ReplayGainTrackGain = value; } else if (string.Equals(metaDataItem.Name, CommonMetaData.ReplayGainTrackPeak, StringComparison.OrdinalIgnoreCase)) { tag.ReplayGainTrackPeak = value; } }
public static void Write(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { if (string.Equals(metaDataItem.Name, CommonMetaData.IsCompilation, StringComparison.OrdinalIgnoreCase)) { var isCompilation = string.Equals(metaDataItem.Value, bool.TrueString, StringComparison.OrdinalIgnoreCase); if (TagManager.HasTag(file, TagTypes.Id3v2)) { var tag = TagManager.GetTag <global::TagLib.Id3v2.Tag>(file, TagTypes.Id3v2); if (tag != null) { tag.IsCompilation = isCompilation; } } else if (TagManager.HasTag(file, TagTypes.Apple)) { var tag = TagManager.GetTag <global::TagLib.Mpeg4.AppleTag>(file, TagTypes.Apple); if (tag != null) { tag.IsCompilation = isCompilation; } } else if (TagManager.HasTag(file, TagTypes.Xiph)) { var tag = TagManager.GetTag <global::TagLib.Ogg.XiphComment>(file, TagTypes.Xiph); if (tag != null) { tag.IsCompilation = isCompilation; } } if (source.MusicBrainz.Value) { if (isCompilation) { file.Tag.MusicBrainzReleaseType = MusicBrainzReleaseType.Compilation; } else if (string.Equals(file.Tag.MusicBrainzReleaseType, MusicBrainzReleaseType.Compilation, StringComparison.OrdinalIgnoreCase)) { //TODO: MusicBrainzReleaseType could be anything... } } } }
public static void Read(TagLibMetaDataSource source, IList <MetaDataItem> metaData, File file) { var isCompilation = default(bool); if (TagManager.HasTag(file, TagTypes.Id3v2)) { var tag = TagManager.GetTag <global::TagLib.Id3v2.Tag>(file, TagTypes.Id3v2); if (tag != null) { isCompilation = tag.IsCompilation; } } else if (TagManager.HasTag(file, TagTypes.Apple)) { var tag = TagManager.GetTag <global::TagLib.Mpeg4.AppleTag>(file, TagTypes.Apple); if (tag != null) { isCompilation = tag.IsCompilation; } } else if (TagManager.HasTag(file, TagTypes.Xiph)) { var tag = TagManager.GetTag <global::TagLib.Ogg.XiphComment>(file, TagTypes.Xiph); if (tag != null) { isCompilation = tag.IsCompilation; } } //Check MB release type, it's innocuous so don't bother respecting READ_MUSICBRAINZ_TAGS. if (string.Equals(file.Tag.MusicBrainzReleaseType, MusicBrainzReleaseType.Compilation, StringComparison.OrdinalIgnoreCase)) { isCompilation = true; } if (isCompilation) { source.AddTag(metaData, CommonMetaData.IsCompilation, bool.TrueString); //TODO: CustomMetaData.VariousArtists should go away but scripts use it, let's keep it updated for now. source.AddTag(metaData, CustomMetaData.VariousArtists, bool.TrueString); } }
private static void WriteLoose(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { var fileName = default(string); if (HasImage(metaDataItem.Name, file, out fileName)) { if (!string.IsNullOrEmpty(metaDataItem.Value)) { ReplaceImage(metaDataItem, fileName); } else { RemoveImage(metaDataItem, fileName); } } else if (!string.IsNullOrEmpty(metaDataItem.Value)) { AddImage(metaDataItem, file); } }
public static void Read(TagLibMetaDataSource source, IList <MetaDataItem> metaDatas, File file) { try { if (file.InvariantStartPosition > TagLibMetaDataSource.MAX_TAG_SIZE) { Logger.Write(typeof(ImageManager), LogLevel.Warn, "Not importing documents from file \"{0}\" due to size: {1} > {2}", file.Name, file.InvariantStartPosition, TagLibMetaDataSource.MAX_TAG_SIZE); return; } var pictures = file.Tag.Pictures; foreach (var picture in pictures) { if (string.IsNullOrEmpty(picture.Description)) { //We need the desciption for the meta data name. continue; } try { if (string.Equals(picture.MimeType, MIME_TYPE_JSON, StringComparison.OrdinalIgnoreCase)) { var name = string.Concat(PREFIX, ":", picture.Description); var value = string.Concat(MIME_TYPE_JSON, ":", ReadJsonDocument(picture.Data.Data)); metaDatas.Add(new MetaDataItem(name, MetaDataItemType.Document) { Value = value }); } } catch (Exception e) { Logger.Write(typeof(DocumentManager), LogLevel.Warn, "Failed to read document: {0} => {1} => {2}", file.Name, picture.Description, e.Message); } } } catch (Exception e) { Logger.Write(typeof(DocumentManager), LogLevel.Warn, "Failed to read documents: {0} => {1}", file.Name, e.Message); } }
public static void Read(TagLibMetaDataSource source, IList <MetaDataItem> metaData, File file) { var tag = file.Tag; if (tag.ReplayGainAlbumPeak != 0 && !double.IsNaN(tag.ReplayGainAlbumPeak) && !double.IsInfinity(tag.ReplayGainAlbumPeak)) { source.AddTag(metaData, CommonMetaData.ReplayGainAlbumPeak, tag.ReplayGainAlbumPeak.ToString()); } if (tag.ReplayGainAlbumGain != 0 && !double.IsNaN(tag.ReplayGainAlbumGain) && !double.IsInfinity(tag.ReplayGainAlbumGain)) { source.AddTag(metaData, CommonMetaData.ReplayGainAlbumGain, tag.ReplayGainAlbumGain.ToString()); } if (tag.ReplayGainTrackPeak != 0 && !double.IsNaN(tag.ReplayGainTrackPeak) && !double.IsInfinity(tag.ReplayGainTrackPeak)) { source.AddTag(metaData, CommonMetaData.ReplayGainTrackPeak, tag.ReplayGainTrackPeak.ToString()); } if (tag.ReplayGainTrackGain != 0 && !double.IsNaN(tag.ReplayGainTrackGain) && !double.IsInfinity(tag.ReplayGainTrackGain)) { source.AddTag(metaData, CommonMetaData.ReplayGainTrackGain, tag.ReplayGainTrackGain.ToString()); } }
private static void ReadPopularimeterFrame(TagLibMetaDataSource source, IList <MetaDataItem> metaData, File file, global::TagLib.Id3v2.PopularimeterFrame frame) { const byte RATING_1 = 1; const byte RATING_2 = 64; const byte RATING_3 = 128; const byte RATING_4 = 196; const byte RATING_5 = 255; if (frame.Rating != 0) { var rating = 0; switch (frame.Rating) { case RATING_1: rating = 1; break; case RATING_2: rating = 2; break; case RATING_3: rating = 3; break; case RATING_4: rating = 4; break; case RATING_5: rating = 5; break; } source.AddTag(metaData, CommonMetaData.Rating, Convert.ToString(rating)); } if (frame.PlayCount != 0) { source.AddTag(metaData, CommonMetaData.PlayCount, Convert.ToString(frame.PlayCount)); } }
private static void WritePopularimeterFrame(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file, global::TagLib.Id3v2.PopularimeterFrame frame) { const byte RATING_1 = 1; const byte RATING_2 = 64; const byte RATING_3 = 128; const byte RATING_4 = 196; const byte RATING_5 = 255; switch (metaDataItem.Name) { case CommonMetaData.Rating: switch (Convert.ToByte(metaDataItem.Value)) { case 1: frame.Rating = RATING_1; break; case 2: frame.Rating = RATING_2; break; case 3: frame.Rating = RATING_3; break; case 4: frame.Rating = RATING_4; break; case 5: frame.Rating = RATING_5; break; } break; case CommonMetaData.PlayCount: frame.PlayCount = Convert.ToUInt64(metaDataItem.Value); break; } }
private static async Task WriteEmbedded(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { var index = default(int); var pictures = new List <IPicture>(file.Tag.Pictures); if (HasImage(metaDataItem.Name, file.Tag, pictures, out index)) { if (!string.IsNullOrEmpty(metaDataItem.Value)) { await ReplaceImage(metaDataItem, file, pictures, index).ConfigureAwait(false); } else { RemoveImage(metaDataItem, file.Tag, pictures, index); } } else if (!string.IsNullOrEmpty(metaDataItem.Value)) { await AddImage(metaDataItem, file, pictures).ConfigureAwait(false); } file.Tag.Pictures = pictures.ToArray(); }
private static async Task <bool> ReadLoose(TagLibMetaDataSource source, IList <MetaDataItem> metaDatas, File file) { var types = ArtworkType.None; try { foreach (var type in new[] { ArtworkType.FrontCover, ArtworkType.BackCover }) { if (!ArtworkTypes.HasFlag(type)) { continue; } var value = ArtworkProvider.Find(file.Name, type); if (!string.IsNullOrEmpty(value) && global::System.IO.File.Exists(value)) { if (source.CopyImages.Value) { value = await ImportImage(value, value, false).ConfigureAwait(false); } metaDatas.Add(new MetaDataItem() { Name = Enum.GetName(typeof(ArtworkType), type), Value = value, Type = MetaDataItemType.Image }); if (ArtworkTypes.HasFlag(types |= type)) { //We have everything we need. return(true); } } } } catch (Exception e) { Logger.Write(typeof(ImageManager), LogLevel.Warn, "Failed to read pictures: {0} => {1}", file.Name, e.Message); } return(types != ArtworkType.None); }
public static void Write(TagLibMetaDataSource source, MetaDataItem metaDataItem, File file) { var index = default(int); var pictures = new List <IPicture>(file.Tag.Pictures); if (HasDocument(metaDataItem.Name, file.Tag, pictures, out index)) { if (!string.IsNullOrEmpty(metaDataItem.Value)) { ReplaceDocument(metaDataItem, file, pictures, index); } else { RemoveDocument(metaDataItem, file.Tag, pictures, index); } } else if (!string.IsNullOrEmpty(metaDataItem.Value)) { AddDocument(metaDataItem, file, pictures); } file.Tag.Pictures = pictures.ToArray(); }
public static void Read(TagLibMetaDataSource source, IList <MetaDataItem> metaData, File file) { var result = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); //If it's an Id3v2 tag then try to read the popularimeter frame. //It can contain a rating and a play counter. if (file.TagTypes.HasFlag(TagTypes.Id3v2)) { var tag = TagManager.GetTag <global::TagLib.Id3v2.Tag>(file, TagTypes.Id3v2); if (tag == null) { return; } foreach (var frame in tag.GetFrames <global::TagLib.Id3v2.PopularimeterFrame>()) { ReadPopularimeterFrame(frame, result); } } //If we didn't find a popularimeter frame then attempt to read the rating from a custom tag. if (!result.ContainsKey(CommonStatistics.Rating)) { var rating = TagManager.ReadCustomTag(CommonStatistics.Rating, file); if (!string.IsNullOrEmpty(rating)) { result.Add(CommonStatistics.Rating, Convert.ToString(GetRatingStars(rating))); } else { result.Add(CommonStatistics.Rating, string.Empty); } } //If we didn't find a popularimeter frame then attempt to read the play count from a custom tag. if (!result.ContainsKey(CommonStatistics.PlayCount)) { var playCount = TagManager.ReadCustomTag(CommonStatistics.PlayCount, file); if (!string.IsNullOrEmpty(playCount)) { result.Add(CommonStatistics.PlayCount, playCount); } else { result.Add(CommonStatistics.PlayCount, "0"); } } //Popularimeter frame does not support last played, attempt to read the play count from a custom tag. //if (!result.ContainsKey(CommonMetaData.LastPlayed)) { var lastPlayed = TagManager.ReadCustomTag(CommonStatistics.LastPlayed, file); if (!string.IsNullOrEmpty(lastPlayed)) { result.Add(CommonStatistics.LastPlayed, lastPlayed); } else { result.Add(CommonStatistics.LastPlayed, DateTimeHelper.NEVER); } } //Copy our informations back to the meta data collection. foreach (var key in result.Keys) { var value = result[key]; source.AddTag(metaData, key, value); } }
private static async Task <bool> ReadEmbedded(TagLibMetaDataSource source, IList <MetaDataItem> metaDatas, File file) { var types = ArtworkType.None; try { if (file.InvariantStartPosition > TagLibMetaDataSource.MAX_TAG_SIZE) { Logger.Write(typeof(ImageManager), LogLevel.Warn, "Not importing images from file \"{0}\" due to size: {1} > {2}", file.Name, file.InvariantStartPosition, TagLibMetaDataSource.MAX_TAG_SIZE); return(false); } var pictures = file.Tag.Pictures; if (pictures != null) { foreach (var fallback in new[] { false, true }) { foreach (var picture in pictures.OrderBy(picture => GetPicturePriority(picture))) { var type = GetArtworkType(picture.Type, fallback); if (!ArtworkTypes.HasFlag(type) || types.HasFlag(type)) { continue; } if (fallback) { if (!string.IsNullOrEmpty(picture.Description)) { //If we're in fallback (i.e the picture type isn't right) then ignore "pictures" with a description as it likely means the data has a specific purpose. Logger.Write(typeof(ImageManager), LogLevel.Warn, "Not importing image from file \"{0}\" due to description: {1}", file.Name, picture.Description); continue; } Logger.Write(typeof(ImageManager), LogLevel.Warn, "Importing image from file \"{0}\" with bad type: {1}.", file.Name, Enum.GetName(typeof(PictureType), picture.Type)); source.AddWarning(file.Name, string.Format("Image has bad type: {0}.", Enum.GetName(typeof(PictureType), picture.Type))); } if (string.IsNullOrEmpty(picture.MimeType)) { Logger.Write(typeof(ImageManager), LogLevel.Warn, "Importing image from file \"{0}\" with empty mime type.", file.Name); source.AddWarning(file.Name, "Image has empty mime type."); } else if (!MimeMapping.Instance.IsImage(picture.MimeType)) { Logger.Write(typeof(ImageManager), LogLevel.Warn, "Importing image from file \"{0}\" with bad mime type: {1}", file.Name, picture.MimeType); source.AddWarning(file.Name, string.Format("Image has bad mime type: {0}", picture.MimeType)); } if (picture.Data.Count > source.MaxImageSize.Value * 1024000) { Logger.Write(typeof(ImageManager), LogLevel.Warn, "Not importing image from file \"{0}\" due to size: {1} > {2}", file.Name, picture.Data.Count, source.MaxImageSize.Value * 1024000); source.AddWarning(file.Name, string.Format("Image was not imported due to size: {0} > {1}", picture.Data.Count, source.MaxImageSize.Value * 1024000)); continue; } metaDatas.Add(new MetaDataItem(Enum.GetName(typeof(ArtworkType), type), MetaDataItemType.Image) { Value = await ImportImage(file, picture, type, false).ConfigureAwait(false) }); if (ArtworkTypes.HasFlag(types |= type)) { //We have everything we need. return(true); } } } } } catch (Exception e) { Logger.Write(typeof(ImageManager), LogLevel.Warn, "Failed to read pictures: {0} => {1}", file.Name, e.Message); } return(types != ArtworkType.None); }