public static GeneralEncapsulatedObjectFrame Get(Tag tag, string description, bool create) { GeneralEncapsulatedObjectFrame geob; foreach (Frame frame in tag.GetFrames(FrameType.GEOB)) { geob = frame as GeneralEncapsulatedObjectFrame; if (geob == null) { continue; } if (geob.Description != description) { continue; } return(geob); } if (!create) { return(null); } geob = new GeneralEncapsulatedObjectFrame(); geob.Description = description; tag.AddFrame(geob); return(geob); }
public static TextInformationFrame Get(Tag tag, ByteVector ident, StringType encoding, bool create) { if (tag == null) { throw new ArgumentNullException("tag"); } if (ident == null) { throw new ArgumentNullException("ident"); } if (ident.Count != 4) { throw new ArgumentException("Identifier must be four bytes long.", "ident"); } foreach (TextInformationFrame frame in tag.GetFrames <TextInformationFrame>(ident)) { return(frame); } if (!create) { return(null); } TextInformationFrame new_frame = new TextInformationFrame(ident, encoding); tag.AddFrame(new_frame); return(new_frame); }
/// <summary> /// Gets a specified terms of use frame from the specified /// tag, trying to to match the language but accepting one /// with a different language if a match was not found. /// </summary> /// <param name="tag"> /// A <see cref="Tag" /> object to search in. /// </param> /// <param name="language"> /// A <see cref="string" /> specifying the ISO-639-2 language /// code to match. /// </param> /// <returns> /// A <see cref="TermsOfUseFrame" /> object containing the /// matching frame, or <see langword="null" /> if a match /// wasn't found. /// </returns> public static TermsOfUseFrame GetPreferred(Tag tag, string language) { TermsOfUseFrame best = null; foreach (Frame f in tag.GetFrames(FrameType.USER)) { TermsOfUseFrame cf = f as TermsOfUseFrame; if (cf == null) { continue; } if (cf.Language == language) { return(cf); } if (best == null) { best = cf; } } return(best); }
public static UnsynchronisedLyricsFrame GetPreferred(Tag tag, string description, string language) { int best_value = -1; UnsynchronisedLyricsFrame best_frame = null; foreach (Frame frame in tag.GetFrames(FrameType.USLT)) { UnsynchronisedLyricsFrame uslt = frame as UnsynchronisedLyricsFrame; if (uslt == null) { continue; } bool same_name = uslt.Description == description; bool same_lang = uslt.Language == language; if (same_name && same_lang) { return(uslt); } int value = same_lang?2:same_name?1:0; if (value <= best_value) { continue; } best_value = value; best_frame = uslt; } return(best_frame); }
public static UserTextInformationFrame Get(Tag tag, string description, StringType type, bool create, bool caseSensitive) { if (tag == null) { throw new ArgumentNullException("tag"); } if (description == null) { throw new ArgumentNullException("description"); } if (description.Length == 0) { throw new ArgumentException("Description must not be empty.", "description"); } StringComparison stringComparison = caseSensitive?StringComparison.InvariantCulture:StringComparison.InvariantCultureIgnoreCase; foreach (UserTextInformationFrame frame in tag.GetFrames <UserTextInformationFrame>(FrameType.TXXX)) { if (description.Equals(frame.Description, stringComparison)) { return(frame); } } if (!create) { return(null); } UserTextInformationFrame new_frame = new UserTextInformationFrame(description, type); tag.AddFrame(new_frame); return(new_frame); }
public static UserUrlLinkFrame Get(Tag tag, string description, StringType type, bool create) { if (tag == null) { throw new ArgumentNullException("tag"); } if (description == null) { throw new ArgumentNullException("description"); } if (description.Length == 0) { throw new ArgumentException("Description must not be empty.", "description"); } foreach (UserUrlLinkFrame frame in tag.GetFrames <UserUrlLinkFrame>(FrameType.WXXX)) { if (description.Equals(frame.Description)) { return(frame); } } if (!create) { return(null); } UserUrlLinkFrame new_frame = new UserUrlLinkFrame(description, type); tag.AddFrame(new_frame); return(new_frame); }
public static UrlLinkFrame Get(Tag tag, ByteVector ident, bool create) { if (tag == null) { throw new ArgumentNullException("tag"); } if (ident == null) { throw new ArgumentNullException("ident"); } if (ident.Count != 4) { throw new ArgumentException("Identifier must be four bytes long.", "ident"); } foreach (UrlLinkFrame frame in tag.GetFrames <UrlLinkFrame>(ident)) { return(frame); } if (!create) { return(null); } UrlLinkFrame new_frame = new UrlLinkFrame(ident); tag.AddFrame(new_frame); return(new_frame); }
public static CommentsFrame Get(Tag tag, string description, string language, bool create) { CommentsFrame comm; foreach (Frame frame in tag.GetFrames(FrameType.COMM)) { comm = frame as CommentsFrame; if (comm == null) { continue; } if (comm.Description != description) { continue; } if (language != null && language != comm.Language) { continue; } return(comm); } if (!create) { return(null); } comm = new CommentsFrame(description, language); tag.AddFrame(comm); return(comm); }
public static CommentsFrame GetPreferred(Tag tag, string description, string language) { bool skip_itunes = description == null || !description.StartsWith("iTun"); int best_value = -1; CommentsFrame best_frame = null; foreach (Frame frame in tag.GetFrames(FrameType.COMM)) { CommentsFrame comm = frame as CommentsFrame; if (comm == null) { continue; } if (skip_itunes && comm.Description.StartsWith("iTun")) { continue; } bool same_name = comm.Description == description; bool same_lang = comm.Language == language; if (same_name && same_lang) { return(comm); } int value = same_lang?2:same_name?1:0; if (value <= best_value) { continue; } best_value = value; best_frame = comm; } return(best_frame); }
/// <summary> /// Gets a specified volume adjustment frame from the /// specified tag, optionally creating it if it does not /// exist. /// </summary> /// <param name="tag"> /// A <see cref="Tag" /> object to search in. /// </param> /// <param name="identification"> /// A <see cref="string" /> specifying the identification to /// match. /// </param> /// <param name="create"> /// A <see cref="bool" /> specifying whether or not to create /// and add a new frame to the tag if a match is not found. /// </param> /// <returns> /// A <see cref="RelativeVolumeFrame" /> object containing /// the matching frame, or <see langword="null" /> if a match /// wasn't found and <paramref name="create" /> is <see /// langword="false" />. /// </returns> public static RelativeVolumeFrame Get(Tag tag, string identification, bool create) { RelativeVolumeFrame rva2; foreach (Frame frame in tag.GetFrames(FrameType.RVA2)) { rva2 = frame as RelativeVolumeFrame; if (rva2 == null) { continue; } if (rva2.Identification != identification) { continue; } return(rva2); } if (!create) { return(null); } rva2 = new RelativeVolumeFrame(identification); tag.AddFrame(rva2); return(rva2); }
/// <summary> /// Gets a specified unique file identifer frame from the /// specified tag, optionally creating it if it does not /// exist. /// </summary> /// <param name="tag"> /// A <see cref="Tag" /> object to search in. /// </param> /// <param name="owner"> /// A <see cref="string" /> specifying the owner to match. /// </param> /// <param name="create"> /// A <see cref="bool" /> specifying whether or not to create /// and add a new frame to the tag if a match is not found. /// </param> /// <returns> /// A <see cref="UserTextInformationFrame" /> object /// containing the matching frame, or <see langword="null" /> /// if a match wasn't found and <paramref name="create" /> is /// <see langword="false" />. /// </returns> public static UniqueFileIdentifierFrame Get(Tag tag, string owner, bool create) { UniqueFileIdentifierFrame ufid; foreach (Frame frame in tag.GetFrames(FrameType.UFID)) { ufid = frame as UniqueFileIdentifierFrame; if (ufid == null) { continue; } if (ufid.Owner == owner) { return(ufid); } } if (!create) { return(null); } ufid = new UniqueFileIdentifierFrame(owner, null); tag.AddFrame(ufid); return(ufid); }
public static AttachedPictureFrame Get(Tag tag, string description, PictureType type, bool create) { AttachedPictureFrame apic; foreach (Frame frame in tag.GetFrames(FrameType.APIC)) { apic = frame as AttachedPictureFrame; if (apic == null) { continue; } if (description != null && apic.Description != description) { continue; } if (type != PictureType.Other && apic.Type != type) { continue; } return(apic); } if (!create) { return(null); } apic = new AttachedPictureFrame(); apic.Description = description; apic.Type = type; tag.AddFrame(apic); return(apic); }
public static UnsynchronisedLyricsFrame Get(Tag tag, string description, string language, bool create) { UnsynchronisedLyricsFrame uslt; foreach (Frame frame in tag.GetFrames(FrameType.USLT)) { uslt = frame as UnsynchronisedLyricsFrame; if (uslt == null) { continue; } if (uslt.Description != description) { continue; } if (language != null && language != uslt.Language) { continue; } return(uslt); } if (!create) { return(null); } uslt = new UnsynchronisedLyricsFrame(description, language); tag.AddFrame(uslt); return(uslt); }
/// <summary> /// Gets a specified comments frame from the specified tag, /// trying to to match the description and language but /// accepting an incomplete match. /// </summary> /// <param name="tag"> /// A <see cref="Tag" /> object to search in. /// </param> /// <param name="description"> /// A <see cref="string" /> specifying the description to /// match. /// </param> /// <param name="language"> /// A <see cref="string" /> specifying the ISO-639-2 language /// code to match. /// </param> /// <returns> /// A <see cref="CommentsFrame" /> object containing the /// matching frame, or <see langword="null" /> if a match /// wasn't found. /// </returns> /// <remarks> /// <para>The method tries matching with the following order /// of precidence:</para> /// <list type="number"> /// <item><term>The first frame with a matching /// description and language.</term></item> /// <item><term>The first frame with a matching /// language.</term></item> /// <item><term>The first frame with a matching /// description.</term></item> /// <item><term>The first frame.</term></item> /// </list> /// </remarks> public static CommentsFrame GetPreferred(Tag tag, string description, string language) { // This is weird, so bear with me. The best thing we can // have is something straightforward and in our own // language. If it has a description, then it is // probably used for something other than an actual // comment. If that doesn't work, we'd still rather have // something in our language than something in another. // After that all we have left are things in other // languages, so we'd rather have one with actual // content, so we try to get one with no description // first. bool skip_itunes = description == null || !description.StartsWith("iTun"); int best_value = -1; CommentsFrame best_frame = null; foreach (Frame frame in tag.GetFrames(FrameType.COMM)) { CommentsFrame comm = frame as CommentsFrame; if (comm == null) { continue; } if (skip_itunes && comm.Description.StartsWith("iTun")) { continue; } bool same_name = comm.Description == description; bool same_lang = comm.Language == language; if (same_name && same_lang) { return(comm); } int value = same_lang ? 2 : same_name ? 1 : 0; if (value <= best_value) { continue; } best_value = value; best_frame = comm; } return(best_frame); }
/// <summary> /// Gets a specified comments frame from the specified tag, /// trying to to match the description and language but /// accepting an incomplete match. /// </summary> /// <param name="tag"> /// A <see cref="Tag" /> object to search in. /// </param> /// <param name="description"> /// A <see cref="string" /> specifying the description to /// match. /// </param> /// <param name="language"> /// A <see cref="string" /> specifying the ISO-639-2 language /// code to match. /// </param> /// <returns> /// A <see cref="UnsynchronisedLyricsFrame" /> object /// containing the matching frame, or <see langword="null" /> /// if a match wasn't found. /// </returns> /// <remarks> /// <para>The method tries matching with the following order /// of precidence:</para> /// <list type="number"> /// <item><term>The first frame with a matching /// description and language.</term></item> /// <item><term>The first frame with a matching /// language.</term></item> /// <item><term>The first frame with a matching /// description.</term></item> /// <item><term>The first frame.</term></item> /// </list> /// </remarks> public static UnsynchronisedLyricsFrame GetPreferred(Tag tag, string description, string language) { // This is weird, so bear with me. The best thing we can // have is something straightforward and in our own // language. If it has a description, then it is // probably used for something other than an actual // comment. If that doesn't work, we'd still rather have // something in our language than something in another. // After that all we have left are things in other // languages, so we'd rather have one with actual // content, so we try to get one with no description // first. int best_value = -1; UnsynchronisedLyricsFrame best_frame = null; foreach (Frame frame in tag.GetFrames(FrameType.USLT)) { UnsynchronisedLyricsFrame uslt = frame as UnsynchronisedLyricsFrame; if (uslt == null) { continue; } bool same_name = uslt.Description == description; bool same_lang = uslt.Language == language; if (same_name && same_lang) { return(uslt); } int value = same_lang ? 2 : same_name ? 1 : 0; if (value <= best_value) { continue; } best_value = value; best_frame = uslt; } return(best_frame); }
public static TermsOfUseFrame Get(Tag tag, string language, bool create) { foreach (Frame f in tag.GetFrames(FrameType.USER)) { TermsOfUseFrame cf = f as TermsOfUseFrame; if (cf != null && (language == null || language == cf.Language)) { return(cf); } } if (!create) { return(null); } TermsOfUseFrame frame = new TermsOfUseFrame(language); tag.AddFrame(frame); return(frame); }
/// <summary> /// Gets a specified attachment frame from the specified tag, /// optionally creating it if it does not exist. /// </summary> /// <param name="tag"> /// A <see cref="Tag" /> object to search in. /// </param> /// <param name="description"> /// A <see cref="string" /> specifying the description to /// match. /// </param> /// <param name="type"> /// A <see cref="PictureType" /> specifying the picture type /// to match. /// </param> /// <param name="create"> /// A <see cref="bool" /> specifying whether or not to create /// and add a new frame to the tag if a match is not found. /// </param> /// <returns> /// A <see cref="AttachmentFrame" /> object containing /// the matching frame, or <see langword="null" /> if a match /// wasn't found and <paramref name="create" /> is <see /// langword="false" />. /// </returns> /// <example> /// <para>Sets a cover image with a description. Because <see /// cref="Get(Tag,string,PictureType,bool)" /> is used, if /// the program is called again with the same audio file and /// desciption, the picture will be overwritten with the new /// one.</para> /// <code lang="C#"> /// using TagLib; /// using TagLib.Id3v2; /// /// public static class SetId3v2Cover /// { /// public static void Main (string [] args) /// { /// if (args.Length != 3) /// throw new ApplicationException ( /// "USAGE: SetId3v2Cover.exe AUDIO_FILE PICTURE_FILE DESCRIPTION"); /// /// // Create the file. Can throw file to TagLib# exceptions. /// File file = File.Create (args [0]); /// /// // Get or create the ID3v2 tag. /// TagLib.Id3v2.Tag tag = file.GetTag (TagTypes.Id3v2, true) as TagLib.Id3v2.Tag; /// if (tag == null) /// throw new ApplicationException ("File does not support ID3v2 tags."); /// /// // Create a picture. Can throw file related exceptions. /// TagLib.Picture picture = TagLib.Picture.CreateFromPath (args [1]); /// /// // Get or create the picture frame. /// AttachedPictureFrame frame = AttachedPictureFrame.Get ( /// tag, args [2], PictureType.FrontCover, true); /// /// // Set the data from the picture. /// frame.MimeType = picture.MimeType; /// frame.Data = picture.data; /// /// // Save the file. /// file.Save (); /// } /// } /// </code> /// </example> public static AttachmentFrame Get(Tag tag, string description, PictureType type, bool create) { AttachmentFrame att; foreach (Frame frame in tag.GetFrames <AttachmentFrame>()) { att = frame as AttachmentFrame; if (att == null) { continue; } if (description != null && att.Description != description) { continue; } if (type != PictureType.Other && att.Type != type) { continue; } return(att); } if (!create) { return(null); } att = new AttachmentFrame(); att.Description = description; att.Type = type; tag.AddFrame(att); return(att); }
public static UniqueFileIdentifierFrame Get(Tag tag, string owner, bool create) { foreach (Frame f in tag.GetFrames(FrameType.UFID)) { if (f is UniqueFileIdentifierFrame && (f as UniqueFileIdentifierFrame).Owner == owner) { return(f as UniqueFileIdentifierFrame); } } if (!create) { return(null); } UniqueFileIdentifierFrame frame = new UniqueFileIdentifierFrame(owner, null); tag.AddFrame(frame); return(frame); }
public static UnsynchronisedLyricsFrame Get(Tag tag, string description, string language, bool create) { foreach (Frame f in tag.GetFrames(FrameType.USLT)) { UnsynchronisedLyricsFrame cf = f as UnsynchronisedLyricsFrame; if (cf != null && cf.Description == description && (language == null || language == cf.Language)) { return(cf); } } if (!create) { return(null); } UnsynchronisedLyricsFrame frame = new UnsynchronisedLyricsFrame(description, language); tag.AddFrame(frame); return(frame); }
/// <summary> /// Gets a specified private frame from the specified tag, /// optionally creating it if it does not exist. /// </summary> /// <param name="tag"> /// A <see cref="Tag" /> object to search in. /// </param> /// <param name="owner"> /// A <see cref="string" /> specifying the owner to match. /// </param> /// <param name="create"> /// A <see cref="bool" /> specifying whether or not to create /// and add a new frame to the tag if a match is not found. /// </param> /// <returns> /// A <see cref="PrivateFrame" /> object containing the /// matching frame, or <see langword="null" /> if a match /// wasn't found and <paramref name="create" /> is <see /// langword="false" />. /// </returns> public static PrivateFrame Get(Tag tag, string owner, bool create) { PrivateFrame priv; foreach (Frame frame in tag.GetFrames(FrameType.PRIV)) { priv = frame as PrivateFrame; if (priv != null && priv.Owner == owner) { return(priv); } } if (!create) { return(null); } priv = new PrivateFrame(owner); tag.AddFrame(priv); return(priv); }
public void TestMp3Uid() { var mp3File = string.Format("{0}\\{1:N}.mp3", Path.GetTempPath(), Guid.NewGuid()); System.IO.File.Copy(@"TestData\test.mp3", mp3File, true); var file = File.Create(CreateAbstraction(mp3File)); Tag id3V2Tag = (Tag)file.GetTag(TagTypes.Id3v2, true); var userTextInformationFrames = id3V2Tag.GetFrames <UserTextInformationFrame>(); UserTextInformationFrame frame = userTextInformationFrames.First(a => a.Description == "UID"); frame.Text.First().Should().Be("SomewhereOverTheRainbow"); frame.Text = new[] { "Hei" }; var userTextInformationFrame = new UserTextInformationFrame("WhateverUID") { Text = new[] { Guid.NewGuid().ToString("N") } }; id3V2Tag.AddFrame(userTextInformationFrame); file.Save(); System.IO.File.Delete(mp3File); }
/// <summary> /// Read the Tags from the File /// </summary> /// <param name="fileName"></param> /// <returns></returns> public static TrackData Create(string fileName) { TrackData track = new TrackData(); TagLib.File file = null; bool error = false; try { TagLib.ByteVector.UseBrokenLatin1Behavior = true; file = TagLib.File.Create(fileName); } catch (CorruptFileException) { log.Warn("File Read: Ignoring track {0} - Corrupt File!", fileName); error = true; } catch (UnsupportedFormatException) { log.Warn("File Read: Ignoring track {0} - Unsupported format!", fileName); error = true; } catch (FileNotFoundException) { log.Warn("File Read: Ignoring track {0} - Physical file no longer existing!", fileName); error = true; } catch (Exception ex) { log.Error("File Read: Error processing file: {0} {1}", fileName, ex.Message); error = true; } if (error) { return(null); } TagLib.Id3v2.Tag id3v2tag = null; try { if (file.MimeType.Substring(file.MimeType.IndexOf("/") + 1) == "mp3") { id3v2tag = file.GetTag(TagTypes.Id3v2, false) as TagLib.Id3v2.Tag; } } catch (Exception ex) { log.Error("File Read: Error retrieving id3tag: {0} {1}", fileName, ex.Message); return(null); } #region Set Common Values FileInfo fi = new FileInfo(fileName); try { track.Id = Guid.NewGuid(); track.FullFileName = fileName; track.FileName = Path.GetFileName(fileName); track.Readonly = fi.IsReadOnly; track.TagType = file.MimeType.Substring(file.MimeType.IndexOf("/") + 1); } catch (Exception ex) { log.Error("File Read: Error setting Common tags: {0} {1}", fileName, ex.Message); return(null); } #endregion #region Set Tags try { // Artist track.Artist = String.Join(";", file.Tag.Performers); if (track.Artist.Contains("AC;DC")) { track.Artist = track.Artist.Replace("AC;DC", "AC/DC"); } track.ArtistSortName = String.Join(";", file.Tag.PerformersSort); if (track.ArtistSortName.Contains("AC;DC")) { track.ArtistSortName = track.ArtistSortName.Replace("AC;DC", "AC/DC"); } track.AlbumArtist = String.Join(";", file.Tag.AlbumArtists); if (track.AlbumArtist.Contains("AC;DC")) { track.AlbumArtist = track.AlbumArtist.Replace("AC;DC", "AC/DC"); } track.AlbumArtistSortName = String.Join(";", file.Tag.AlbumArtistsSort); if (track.AlbumArtistSortName.Contains("AC;DC")) { track.AlbumArtistSortName = track.AlbumArtistSortName.Replace("AC;DC", "AC/DC"); } track.Album = file.Tag.Album ?? ""; track.AlbumSortName = file.Tag.AlbumSort ?? ""; track.BPM = (int)file.Tag.BeatsPerMinute; track.Compilation = id3v2tag == null ? false : id3v2tag.IsCompilation; track.Composer = string.Join(";", file.Tag.Composers); track.Conductor = file.Tag.Conductor ?? ""; track.Copyright = file.Tag.Copyright ?? ""; track.DiscNumber = file.Tag.Disc; track.DiscCount = file.Tag.DiscCount; track.Genre = string.Join(";", file.Tag.Genres); track.Grouping = file.Tag.Grouping ?? ""; track.Title = file.Tag.Title ?? ""; track.TitleSortName = file.Tag.TitleSort ?? ""; track.ReplayGainTrack = file.Tag.ReplayGainTrack ?? ""; track.ReplayGainTrackPeak = file.Tag.ReplayGainTrackPeak ?? ""; track.ReplayGainAlbum = file.Tag.ReplayGainAlbum ?? ""; track.ReplayGainAlbumPeak = file.Tag.ReplayGainAlbumPeak ?? ""; track.TrackNumber = file.Tag.Track; track.TrackCount = file.Tag.TrackCount; track.Year = (int)file.Tag.Year; // Pictures foreach (IPicture picture in file.Tag.Pictures) { MPTagThat.Core.Common.Picture pic = new MPTagThat.Core.Common.Picture { Type = picture.Type, MimeType = picture.MimeType, Description = picture.Description }; pic.Data = picture.Data.Data; track.Pictures.Add(pic); } // Comments if (track.IsMp3 && id3v2tag != null) { foreach (CommentsFrame commentsframe in id3v2tag.GetFrames <CommentsFrame>()) { track.ID3Comments.Add(new Comment(commentsframe.Description, commentsframe.Language, commentsframe.Text)); } } else { track.Comment = file.Tag.Comment; } // Lyrics track.Lyrics = file.Tag.Lyrics; if (track.IsMp3 && id3v2tag != null) { foreach (UnsynchronisedLyricsFrame lyricsframe in id3v2tag.GetFrames <UnsynchronisedLyricsFrame>()) { // Only add non-empty Frames if (lyricsframe.Text != "") { track.LyricsFrames.Add(new Lyric(lyricsframe.Description, lyricsframe.Language, lyricsframe.Text)); } } } // Rating if (track.IsMp3) { TagLib.Id3v2.PopularimeterFrame popmFrame = null; // First read in all POPM Frames found if (id3v2tag != null) { foreach (PopularimeterFrame popmframe in id3v2tag.GetFrames <PopularimeterFrame>()) { // Only add valid POPM Frames if (popmframe.User != "" && popmframe.Rating > 0) { track.Ratings.Add(new PopmFrame(popmframe.User, (int)popmframe.Rating, (int)popmframe.PlayCount)); } } popmFrame = TagLib.Id3v2.PopularimeterFrame.Get(id3v2tag, "MPTagThat", false); if (popmFrame != null) { track.Rating = popmFrame.Rating; } } if (popmFrame == null) { // Now check for Ape Rating TagLib.Ape.Tag apetag = file.GetTag(TagTypes.Ape, true) as TagLib.Ape.Tag; TagLib.Ape.Item apeItem = apetag.GetItem("RATING"); if (apeItem != null) { string rating = apeItem.ToString(); try { track.Rating = Convert.ToInt32(rating); } catch (Exception) { } } } } else if (track.TagType == "ape") { TagLib.Ape.Tag apetag = file.GetTag(TagTypes.Ape, true) as TagLib.Ape.Tag; TagLib.Ape.Item apeItem = apetag.GetItem("RATING"); if (apeItem != null) { string rating = apeItem.ToString(); try { track.Rating = Convert.ToInt32(rating); } catch (Exception) { } } } else if (track.TagType == "ogg" || track.TagType == "flac") { XiphComment xiph = file.GetTag(TagLib.TagTypes.Xiph, false) as XiphComment; string[] rating = xiph.GetField("RATING"); if (rating.Length > 0) { try { track.Rating = Convert.ToInt32(rating[0]); } catch (Exception) { } } } } catch (Exception ex) { log.Error("Exception setting Tags for file: {0}. {1}", fileName, ex.Message); } #endregion #region Set Properties try { track.DurationTimespan = file.Properties.Duration; int fileLength = (int)(fi.Length / 1024); track.FileSize = fileLength.ToString(); track.BitRate = file.Properties.AudioBitrate.ToString(); track.SampleRate = file.Properties.AudioSampleRate.ToString(); track.Channels = file.Properties.AudioChannels.ToString(); track.Version = file.Properties.Description; track.CreationTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", fi.CreationTime); track.LastWriteTime = string.Format("{0:yyyy-MM-dd HH:mm:ss}", fi.LastWriteTime); } catch (Exception ex) { log.Error("Exception setting Properties for file: {0}. {1}", fileName, ex.Message); } #endregion // Now copy all Text frames of an ID3 V2 try { if (track.IsMp3 && id3v2tag != null) { foreach (TagLib.Id3v2.Frame frame in id3v2tag.GetFrames()) { string id = frame.FrameId.ToString(); if (!Util.StandardFrames.Contains(id) && Util.ExtendedFrames.Contains(id)) { track.Frames.Add(new Frame(id, "", frame.ToString())); } else if (!Util.StandardFrames.Contains(id) && !Util.ExtendedFrames.Contains(id)) { if ((Type)frame.GetType() == typeof(UserTextInformationFrame)) { // Don't add Replaygain frames, as they are handled in taglib tags if (!Util.IsReplayGain((frame as UserTextInformationFrame).Description)) { track.UserFrames.Add(new Frame(id, (frame as UserTextInformationFrame).Description ?? "", (frame as UserTextInformationFrame).Text.Length == 0 ? "" : (frame as UserTextInformationFrame).Text[0])); } } else if ((Type)frame.GetType() == typeof(PrivateFrame)) { track.UserFrames.Add(new Frame(id, (frame as PrivateFrame).Owner ?? "", (frame as PrivateFrame).PrivateData == null ? "" : (frame as PrivateFrame).PrivateData.ToString())); } else if ((Type)frame.GetType() == typeof(UniqueFileIdentifierFrame)) { track.UserFrames.Add(new Frame(id, (frame as UniqueFileIdentifierFrame).Owner ?? "", (frame as UniqueFileIdentifierFrame).Identifier == null ? "" : (frame as UniqueFileIdentifierFrame).Identifier.ToString())); } else if ((Type)frame.GetType() == typeof(UnknownFrame)) { track.UserFrames.Add(new Frame(id, "", (frame as UnknownFrame).Data == null ? "" : (frame as UnknownFrame).Data.ToString())); } else { track.UserFrames.Add(new Frame(id, "", frame.ToString())); } } } track.ID3Version = id3v2tag.Version; } } catch (Exception ex) { log.Error("Exception getting User Defined frames for file: {0}. {1}", fileName, ex.Message); } return(track); }
// TODO: expection handling private void bt_Save_Click(object sender, EventArgs e) { TreeNodeCollection nodes = tagTreeView.Nodes; UserTextInformationFrame tagframe; List <UserTextInformationFrame> save_frame_list = new List <UserTextInformationFrame>(); List <string> tag_desc_list = new List <string>(); try { // RemoveFrame() is invalid, workaround: save other "TXXX" first, then remove all "TXXX", add selected tags and recovery other "TXXX" at last foreach (TreeNode n in nodes) { tag_desc_list.Add(n.Text); } foreach (UserTextInformationFrame fm in audioTag.GetFrames("TXXX")) { if (!tag_desc_list.Contains(fm.Description)) { save_frame_list.Add(fm); } } // Remove all "TXXX" audioTag.RemoveFrames("TXXX"); // Pre-handle comment tag for link to comment if (cb_LinkToComment.Checked == true) { if (cb_AppendMode.Checked == true) { if (string.IsNullOrWhiteSpace(audioTag.Comment)) { audioTag.Comment = ""; // clear comment } else { audioTag.Comment += "||"; // add a link character "||" } } else { audioTag.Comment = ""; // clear comment } } // Add selected tags foreach (TreeNode n in nodes) { string valmixed = ""; foreach (TreeNode tn in n.Nodes) { if (tn.Checked == true) { valmixed += tn.Text + ";"; // Handle link to comment tag if (cb_LinkToComment.Checked == true) { audioTag.Comment += tn.Text + ";"; } } } tagframe = new UserTextInformationFrame(n.Text); tagframe.Text = new string[] { valmixed }; audioTag.AddFrame(tagframe); } // Recovery other "TXXX" if (save_frame_list.Count != 0) { foreach (UserTextInformationFrame fm in save_frame_list) { audioTag.AddFrame(fm); } } // Save file audioFile.Save(); showInStatusBar("Save OK"); } catch (Exception ex) { MessageBox.Show(ExceptionInfo.ShowExceptionInfo(ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
// TODO: ape, mp4 support private void createTreeViewFromXmlAndMedia(string xmlpath, string path) { try { audioFile = TagLib.File.Create(path); // Display file name in status bar //statusStrip.Items[0].Text = Path.GetFileName(path); showInStatusBar(Path.GetFileName(path)); audioTag = (TagLib.Id3v2.Tag)audioFile.GetTag(TagTypes.Id3v2); if (audioTag == null) { MessageBox.Show("Only support ID3v2 tag", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } XmlDocument xmltag = new XmlDocument(); xmltag.Load(xmlpath); XmlNode mp3tag = xmltag.SelectSingleNode("/mp3tag"); XmlNodeList taglist = mp3tag.ChildNodes; // Clear all nodes first before add new nodes tagTreeView.Nodes.Clear(); foreach (XmlNode tag in taglist) { TreeNode nodetag = tagTreeView.Nodes.Add(tag.Attributes["field"].Value); //Debug.WriteLine("\nField: " + tag.Attributes["field"].Value + "\n"); XmlNodeList valuelist = tag.ChildNodes; foreach (XmlNode value in valuelist) { TreeNode nodevalue = new TreeNode(value.InnerText); foreach (UserTextInformationFrame fm in audioTag.GetFrames("TXXX")) { if (fm.Description == tag.Attributes["field"].Value) { //Debug.WriteLine("\r\nString list length = " + fm.Text.Length + "\r\n"); if (fm.Text.Length == 0) { continue; } if (fm.Text[0].Contains(nodevalue.Text))// TODO use ; to separate { nodevalue.Checked = true; } } } nodetag.Nodes.Add(nodevalue); // Update node check status tagTreeView.TriStateUpdateCheckStatus(nodevalue); } } } catch (Exception ex) { MessageBox.Show(ExceptionInfo.ShowExceptionInfo(ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); } }