public void TestPrivateFrame() { MockFileSystem fileSystem = new MockFileSystem(); fileSystem.AddFile(@"C:\test.mp3", new MockFileData(System.IO.File.ReadAllBytes(@"TestData\test.mp3"))); File.IFileAbstraction mp3File = fileSystem.File.CreateFileAbstraction(@"C:\test.mp3"); File file = File.Create(mp3File); Tag id3V2Tag = (Tag)file.GetTag(TagTypes.Id3v2, true); // Get the private frame, create if necessary. PrivateFrame frame = PrivateFrame.Get(id3V2Tag, "SW/Uid", true); string uid = Guid.NewGuid().ToString("N"); frame.PrivateData = Encoding.Unicode.GetBytes(uid); file.Save(); File actualFile = File.Create(mp3File); id3V2Tag = (Tag)actualFile.GetTag(TagTypes.Id3v2, true); // Get the private frame, create if necessary. PrivateFrame actualFrame = PrivateFrame.Get(id3V2Tag, "SW/Uid", true); // Set the frame data to your value. I am 90% sure that these are encoded with UTF-16. string actualUid = Encoding.Unicode.GetString(actualFrame.PrivateData.Data); actualUid.Should().Be(uid); }
public TagLib.Tag AddTag(TagTypes type, TagLib.Tag copy) { TagLib.Tag target = null; if (type == (TagTypes.None | TagTypes.Id3v1)) { target = new TagLib.Id3v1.Tag(); } else if (type == (TagTypes.None | TagTypes.Id3v2)) { TagLib.Id3v2.Tag tag2; target = new TagLib.Id3v2.Tag { Version = 4, Flags = (byte) (tag2.Flags | HeaderFlags.FooterPresent) }; } else if (type == (TagTypes.None | TagTypes.Ape)) { target = new TagLib.Ape.Tag(); } if (target != null) { if (copy != null) { copy.CopyTo(target, true); } if (type == (TagTypes.None | TagTypes.Id3v1)) { base.AddTag(target); return target; } base.InsertTag(0, target); } return target; }
private TagLib.Tag ReadTag(ref long end) { long position = end; TagTypes types = this.ReadTagInfo(ref position); TagLib.Tag tag = null; try { TagTypes types2 = types; switch (types2) { case (TagTypes.None | TagTypes.Id3v1): tag = new TagLib.Id3v1.Tag(this.file, position); break; case (TagTypes.None | TagTypes.Id3v2): tag = new TagLib.Id3v2.Tag(this.file, position); break; default: if (types2 == (TagTypes.None | TagTypes.Ape)) { tag = new TagLib.Ape.Tag(this.file, end - 0x20L); } break; } end = position; } catch (CorruptFileException) { } return tag; }
private TagLib.Tag ReadTag(ref long start) { long position = start; TagTypes types = this.ReadTagInfo(ref position); TagLib.Tag tag = null; try { switch (types) { case (TagTypes.None | TagTypes.Id3v2): tag = new TagLib.Id3v2.Tag(this.file, start); break; case (TagTypes.None | TagTypes.Ape): tag = new TagLib.Ape.Tag(this.file, start); break; } } catch (CorruptFileException exception) { Console.Error.WriteLine("taglib-sharp caught exception creating tag: {0}", exception); } start = position; return tag; }
private void WriteId3Tag(TagLib.Id3v2.Tag tag, string id, string value) { var frame = UserTextInformationFrame.Get(tag, id, true); if (value.IsNotNullOrWhiteSpace()) { frame.Text = value.Split(';'); } else { tag.RemoveFrame(frame); } }
/// <summary> /// Attempt to write a private frame /// </summary> private bool TryWritePrivateFrame(string name, string value) { try { TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)mp3File.GetTag(TagTypes.Id3v2, true); var privateFrame = PrivateFrame.Get(tag, name, true); privateFrame.PrivateData = Encoding.Unicode.GetBytes(value ?? string.Empty); return(true); } catch { return(false); } }
/// <summary> /// Attempt to write a private frame /// </summary> private bool TryWriteUserFrame(string name, string value) { try { TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)mp3File.GetTag(TagTypes.Id3v2, true); var userFrame = UserTextInformationFrame.Get(tag, name, true); userFrame.Text = value == null ? new string[] { string.Empty } : value.Split(';'); return(true); } catch { return(false); } }
public override TagLib.Tag GetTag(TagTypes type, bool create) { TagLib.Tag tag = null; if (type != (TagTypes.None | TagTypes.Id3v2)) { return tag; } if ((this.tag == null) && create) { this.tag = new TagLib.Id3v2.Tag(); this.tag.Version = 2; } return this.tag; }
/// <summary> /// Attempt to read a private frame /// </summary> private bool TryReadPrivateFrame(string name, out string value) { try { TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)mp3File.GetTag(TagTypes.Id3v2); var privateFrame = PrivateFrame.Get(tag, name, false); value = Encoding.Unicode.GetString(privateFrame.PrivateData.Data); return(true); } catch { value = string.Empty; return(false); } }
/// <summary> /// Attempt to read a user frame /// </summary> private bool TryReadUserFrame(string name, out string value) { try { TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)mp3File.GetTag(TagTypes.Id3v2); var userFrame = UserTextInformationFrame.Get(tag, name, false); value = stringArrayToString(userFrame.Text); return(true); } catch { value = string.Empty; return(false); } }
public override TagLib.Tag GetTag(TagTypes type, bool create) { TagLib.Tag tag = null; switch (type) { case (TagTypes.None | TagTypes.Id3v2): if ((this.id32_tag == null) && create) { this.id32_tag = new TagLib.Id3v2.Tag(); this.id32_tag.Version = 4; this.id32_tag.Flags = (HeaderFlags) ((byte) (this.id32_tag.Flags | HeaderFlags.FooterPresent)); this.tag.CopyTo(this.id32_tag, true); } tag = this.id32_tag; break; case TagTypes.RiffInfo: if ((this.info_tag == null) && create) { this.info_tag = new InfoTag(); this.tag.CopyTo(this.info_tag, true); } tag = this.info_tag; break; case TagTypes.MovieId: if ((this.mid_tag == null) && create) { this.mid_tag = new MovieIdTag(); this.tag.CopyTo(this.mid_tag, true); } tag = this.mid_tag; break; case TagTypes.DivX: if ((this.divx_tag == null) && create) { this.divx_tag = new DivXTag(); this.tag.CopyTo(this.divx_tag, true); } tag = this.divx_tag; break; } TagLib.Tag[] tags = new TagLib.Tag[] { this.id32_tag, this.info_tag, this.mid_tag, this.divx_tag }; this.tag.SetTags(tags); return tag; }
/// <summary> /// merge like values, hide unlike values /// </summary> public override void Coalesce() { FileInfo fi = (FileInfo)lv.SelectedItems[0].Tag; TagLib.File first_tag_file = TagLib.File.Create(fi.FullName); TagLib.Id3v2.Tag first_tag = tag_file.GetTag(TagLib.TagTypes.Id3v2) as TagLib.Id3v2.Tag; TagV2Ext first_tag_ext = new TagV2Ext(first_tag); foreach (ListViewItem item in lv.SelectedItems) { fi = (FileInfo)item.Tag; first_tag_file = TagLib.File.Create(fi.FullName); TagLib.Tag tag = tag_file.GetTag(TagLib.TagTypes.Id3v1); TagV2Ext tag_ext = new TagV2Ext(first_tag); if (tag != null) { } } v2 = first_tag; }
private DateTime?ReadId3Date(TagLib.Id3v2.Tag tag, string dateTag) { string date = tag.GetTextAsString(dateTag); if (tag.Version == 4) { // the unabused TDRC/TDOR tags return(DateTime.TryParse(date, out DateTime result) ? result : default(DateTime?)); } else if (dateTag == "TDRC") { // taglib maps the v3 TYER and TDAT to TDRC but does it incorrectly return(DateTime.TryParseExact(date, "yyyy-dd-MM", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result) ? result : default(DateTime?)); } else { // taglib maps the v3 TORY to TDRC so we just get a year return(int.TryParse(date, out int year) && year >= 1860 && year <= DateTime.UtcNow.Year + 1 ? new DateTime(year, 1, 1) : default(DateTime?)); } }
private void WriteId3Date(TagLib.Id3v2.Tag tag, string v4field, string v3yyyy, string v3ddmm, DateTime?date) { if (tag.Version == 4) { tag.SetTextFrame(v3yyyy, default(string)); if (v3ddmm.IsNotNullOrWhiteSpace()) { tag.SetTextFrame(v3ddmm, default(string)); } tag.SetTextFrame(v4field, date.HasValue ? date.Value.ToString("yyyy-MM-dd") : null); } else { tag.SetTextFrame(v4field, default(string)); tag.SetTextFrame(v3yyyy, date.HasValue ? date.Value.ToString("yyyy") : null); if (v3ddmm.IsNotNullOrWhiteSpace()) { tag.SetTextFrame(v3ddmm, date.HasValue ? date.Value.ToString("ddMM") : null); } } }
public TagLib.Tag AddTag(TagTypes type, TagLib.Tag copy) { TagLib.Tag target = null; if (type == (TagTypes.None | TagTypes.Id3v2)) { target = new TagLib.Id3v2.Tag(); } else if (type == (TagTypes.None | TagTypes.Ape)) { target = new TagLib.Ape.Tag(); (target as TagLib.Ape.Tag).HeaderPresent = true; } if (target != null) { if (copy != null) { copy.CopyTo(target, true); } base.AddTag(target); } return target; }
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); }
public void WritePrivateFrames_TagsAreWritten() { const string fileName = @"C:\test.mp3"; _mockFileSystem.AddFile(fileName, new MockFileData(System.IO.File.ReadAllBytes(@"TestData\test.mp3"))); File.IFileAbstraction mp3File = _mockFileSystem.File.CreateFileAbstraction(fileName); Dictionary <string, string> values = new Dictionary <string, string> { { "SW/Uid", Guid.NewGuid().ToString("N") } }; _tagTool.WritePrivateFrames(fileName, values); File actualFile = File.Create(mp3File); TagLib.Id3v2.Tag id3V2Tag = (TagLib.Id3v2.Tag)actualFile.GetTag(TagTypes.Id3v2, true); PrivateFrame actualFrame = PrivateFrame.Get(id3V2Tag, "SW/Uid", true); string actualUid = Encoding.Unicode.GetString(actualFrame.PrivateData.Data); actualUid.Should().Be(values["SW/Uid"]); }
public static void DumpId3V2Metadata(File tagFile) { TagLib.Id3v2.Tag tags = (TagLib.Id3v2.Tag)tagFile.GetTag(TagTypes.Id3v2); foreach (SimpleFrame f in tags.Select(f => new SimpleFrame(f)).OrderBy(f => f.FrameId)) { if (f.Value.Length > 1) { Console.WriteLine("{0} ({1}):", f.FrameId, f.Value.Length); foreach (string fv in f.Value) { WriteLineWithIndent(4, fv); } } else if (f.Value.Length == 1) { Console.WriteLine("{0}:", f.FrameId); WriteLineWithIndent(4, f.Value[0]); } else { Console.WriteLine("{0} (No Value)", f.FrameId); } } }
private void Read(bool read_tags, ReadStyle style, out uint riff_size, out long tag_start, out long tag_end) { bool flag; base.Seek(0L); if (base.ReadBlock(4) != FileIdentifier) { throw new CorruptFileException("File does not begin with RIFF identifier"); } riff_size = base.ReadBlock(4).ToUInt(false); ByteVector vector = base.ReadBlock(4); tag_start = -1L; tag_end = -1L; long offset = 12L; long length = base.Length; uint num3 = 0; TimeSpan zero = TimeSpan.Zero; ICodec[] codecs = new ICodec[0]; Label_0066: flag = false; base.Seek(offset); string str = base.ReadBlock(4).ToString(StringType.UTF8); num3 = base.ReadBlock(4).ToUInt(false); string key = str; if (key != null) { Dictionary<string, int> dictionary; int num4; if (<>f__switch$map3 == null) { dictionary = new Dictionary<string, int>(6); dictionary.Add("fmt ", 0); dictionary.Add("data", 1); dictionary.Add("LIST", 2); dictionary.Add("ID32", 3); dictionary.Add("IDVX", 4); dictionary.Add("JUNK", 5); <>f__switch$map3 = dictionary; } if (<>f__switch$map3.TryGetValue(key, out num4)) { switch (num4) { case 0: if ((style != ReadStyle.None) && (vector == "WAVE")) { base.Seek(offset + 8L); codecs = new ICodec[] { new WaveFormatEx(base.ReadBlock(0x12), 0) }; break; } break; case 1: if (vector == "WAVE") { base.InvariantStartPosition = offset; base.InvariantEndPosition = offset + num3; if (((style != ReadStyle.None) && (codecs.Length == 1)) && (codecs[0] is WaveFormatEx)) { WaveFormatEx ex = (WaveFormatEx) codecs[0]; zero += TimeSpan.FromSeconds(((double) num3) / ((double) ex.AverageBytesPerSecond)); } break; } break; case 2: { string str3 = base.ReadBlock(4).ToString(StringType.UTF8); if (str3 != null) { int num5; if (<>f__switch$map2 == null) { dictionary = new Dictionary<string, int>(4); dictionary.Add("hdrl", 0); dictionary.Add("INFO", 1); dictionary.Add("MID ", 2); dictionary.Add("movi", 3); <>f__switch$map2 = dictionary; } if (<>f__switch$map2.TryGetValue(str3, out num5)) { switch (num5) { case 0: if ((style != ReadStyle.None) && (vector == "AVI ")) { AviHeaderList list = new AviHeaderList(this, offset + 12L, ((int) num3) - 4); zero = list.Header.Duration; codecs = list.Codecs; break; } goto Label_040E; case 1: if (read_tags && (this.info_tag == null)) { this.info_tag = new InfoTag(this, offset + 12L, ((int) num3) - 4); } flag = true; break; case 2: if (read_tags && (this.mid_tag == null)) { this.mid_tag = new MovieIdTag(this, offset + 12L, ((int) num3) - 4); } flag = true; break; case 3: if (vector == "AVI ") { base.InvariantStartPosition = offset; base.InvariantEndPosition = offset + num3; break; } break; } } } break; } case 3: if (read_tags && (this.id32_tag == null)) { this.id32_tag = new TagLib.Id3v2.Tag(this, offset + 8L); } flag = true; break; case 4: if (read_tags && (this.divx_tag == null)) { this.divx_tag = new DivXTag(this, offset + 8L); } flag = true; break; case 5: if (tag_end == offset) { tag_end = (offset + 8L) + num3; } break; } } } if (flag) { if (tag_start == -1L) { tag_start = offset; tag_end = (offset + 8L) + num3; } else if (tag_end == offset) { tag_end = (offset + 8L) + num3; } } Label_040E: if (((offset += (8 + num3)) + 8L) < length) { goto Label_0066; } if (style != ReadStyle.None) { if (codecs.Length == 0) { throw new UnsupportedFormatException("Unsupported RIFF type."); } this.properties = new TagLib.Properties(zero, codecs); } if (read_tags) { TagLib.Tag[] tags = new TagLib.Tag[] { this.id32_tag, this.info_tag, this.mid_tag, this.divx_tag }; this.tag.SetTags(tags); } }
private void Read(bool read_tags, ReadStyle style, out uint aiff_size, out long tag_start, out long tag_end) { base.Seek(0L); if (base.ReadBlock(4) != FileIdentifier) { throw new CorruptFileException("File does not begin with AIFF identifier"); } aiff_size = base.ReadBlock(4).ToUInt(true); tag_start = -1L; tag_end = -1L; if ((this.header_block == null) && (style != ReadStyle.None)) { long offset = base.Find(CommIdentifier, 0L); if (offset == -1L) { throw new CorruptFileException("No Common chunk available in AIFF file."); } base.Seek(offset); this.header_block = base.ReadBlock(0x1a); StreamHeader header = new StreamHeader(this.header_block, (long) ((ulong) aiff_size)); ICodec[] codecs = new ICodec[] { header }; this.properties = new TagLib.Properties(TimeSpan.Zero, codecs); } long num2 = -1L; if (base.Find(SoundIdentifier, 0L, ID3Identifier) == -1L) { num2 = base.Find(ID3Identifier, 0L); } long num3 = base.Find(SoundIdentifier, 0L); if (num3 == -1L) { throw new CorruptFileException("No Sound chunk available in AIFF file."); } base.Seek(num3 + 4L); long startPosition = (((long) base.ReadBlock(4).ToULong(true)) + num3) + 4L; if (num2 == -1L) { num2 = base.Find(ID3Identifier, startPosition); } if (num2 > -1L) { if (read_tags && (this.tag == null)) { this.tag = new TagLib.Id3v2.Tag(this, num2 + 8L); } base.Seek(num2 + 4L); uint num6 = base.ReadBlock(4).ToUInt(true) + 8; long num7 = num2; base.InvariantStartPosition = num7; tag_start = num7; num7 = tag_start + num6; base.InvariantEndPosition = num7; tag_end = num7; } }
/// <summary> /// Gets a specified picture 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="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> public static AttachmentFrame Get(Tag tag, string description, bool create) { return(Get(tag, description, PictureType.Other, create)); }
/// <summary> /// Gets a specified picture 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="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> public static AttachmentFrame Get(Tag tag, PictureType type, bool create) { return(Get(tag, null, type, create)); }
/// <summary> /// /// </summary> /// <param name="tag"></param> public TagV2Ext(TagLib.Id3v2.Tag tag) { this.tag = tag; }
// 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); } }
public static void Main(string [] args) { if (args.Length < 3) { Console.Error.WriteLine("USAGE: BatchSet.exe -tag value [-tag2 value ...] File1 [File2 ...]"); return; } Mode mode = Mode.Tag; List <string> files = new List <string> (); Dictionary <string, string> tags = new Dictionary <string, string> (); string tag = null; foreach (string str in args) { if (mode == Mode.Tag) { if (str [0] == '-') { if (str == "--") { mode = Mode.File; } else { tag = str.Substring(1); mode = Mode.Value; } continue; } mode = Mode.File; } if (mode == Mode.Value) { if (!tags.ContainsKey(tag)) { tags.Add(tag, str); } mode = Mode.Tag; continue; } if (mode == Mode.File) { files.Add(str); } } foreach (string filename in files) { TagLib.File file = TagLib.File.Create(filename); if (file == null) { continue; } Console.WriteLine("Updating Tags For: " + filename); foreach (string key in tags.Keys) { string value = tags [key]; try { switch (key) { case "id3version": byte number = byte.Parse(value); if (number == 1) { file.RemoveTags(TagTypes.Id3v2); } else { TagLib.Id3v2.Tag v2 = file.GetTag(TagTypes.Id3v2, true) as TagLib.Id3v2.Tag; if (v2 != null) { v2.Version = number; } } break; case "album": file.Tag.Album = value; break; case "artists": file.Tag.AlbumArtists = value.Split(new char [] { ';' }); break; case "comment": file.Tag.Comment = value; break; case "lyrics": file.Tag.Lyrics = value; break; case "composers": file.Tag.Composers = value.Split(new char [] { ';' }); break; case "disc": file.Tag.Disc = uint.Parse(value); break; case "disccount": file.Tag.DiscCount = uint.Parse(value); break; case "genres": file.Tag.Genres = value.Split(new char [] { ';' }); break; case "performers": file.Tag.Performers = value.Split(new char [] { ';' }); break; case "title": file.Tag.Title = value; break; case "track": file.Tag.Track = uint.Parse(value); break; case "trackcount": file.Tag.TrackCount = uint.Parse(value); break; case "year": file.Tag.Year = uint.Parse(value); break; case "pictures": List <Picture> pics = new List <Picture> (); if (!string.IsNullOrEmpty(value)) { foreach (string path in value.Split(new char [] { ';' })) { pics.Add(new Picture(path)); } } file.Tag.Pictures = pics.ToArray(); break; } } catch (Exception e) { Console.WriteLine("Error setting tag " + key + ":"); Console.WriteLine(e); } } file.Save(); } }
private void SetTags(File mp3File) { tag = (TagLib.Id3v2.Tag)mp3File.GetTag(TagTypes.Id3v2, true); SetTagMainInfo(); SetTagMainKey(); }
/// <summary> /// Save the Modified file /// </summary> /// <param name="song"></param> /// <param name="errorMessage"></param> /// <returns></returns> public static bool SaveFile(SongData song, ref string errorMessage) { errorMessage = ""; if (!song.Changed) { return(true); } var options = (ServiceLocator.Current.GetInstance(typeof(ISettingsManager)) as ISettingsManager)?.GetOptions; /* * if (song.Readonly && !options.MainSettings.ChangeReadOnlyAttributte && * (options.ReadOnlyFileHandling == 0 || options.ReadOnlyFileHandling == 2)) * { * Form dlg = new ReadOnlyDialog(song.FullFileName); * DialogResult dlgResult = dlg.ShowDialog(); * * switch (dlgResult) * { * case DialogResult.Yes: * options.ReadOnlyFileHandling = 0; // Yes * break; * * case DialogResult.OK: * options.ReadOnlyFileHandling = 1; // Yes to All * break; * * case DialogResult.No: * options.ReadOnlyFileHandling = 2; // No * break; * * case DialogResult.Cancel: * options.ReadOnlyFileHandling = 3; // No to All * break; * } * } */ if (song.Readonly) { if (!options.MainSettings.ChangeReadOnlyAttribute && options.ReadOnlyFileHandling > 1) { errorMessage = "File is readonly"; return(false); } try { System.IO.File.SetAttributes(song.FullFileName, System.IO.File.GetAttributes(song.FullFileName) & ~FileAttributes.ReadOnly); song.Readonly = false; } catch (Exception ex) { log.Error($"File Save: Can't reset Readonly attribute: {song.FullFileName} {ex.Message}"); errorMessage = LocalizeDictionary.Instance.GetLocalizedObject("MPTagThat", "Strings", "message_ErrorResetAttr", LocalizeDictionary.Instance.Culture).ToString(); return(false); } } TagLib.File file = null; bool error = false; try { TagLib.ByteVector.UseBrokenLatin1Behavior = true; file = TagLib.File.Create(song.FullFileName); } catch (CorruptFileException) { log.Warn($"File Read: Ignoring song {song.FullFileName} - Corrupt File!"); errorMessage = LocalizeDictionary.Instance.GetLocalizedObject("MPTagThat", "Strings", "message_CorruptFile", LocalizeDictionary.Instance.Culture).ToString(); error = true; } catch (UnsupportedFormatException) { log.Warn($"File Read: Ignoring song {song.FullFileName} - Unsupported format!"); errorMessage = LocalizeDictionary.Instance.GetLocalizedObject("MPTagThat", "Strings", "message_UnsupportedFormat", LocalizeDictionary.Instance.Culture).ToString(); error = true; } catch (FileNotFoundException) { log.Warn($"File Read: Ignoring song {song.FullFileName} - Physical file no longer existing!"); errorMessage = LocalizeDictionary.Instance.GetLocalizedObject("MPTagThat", "Strings", "message_NonExistingFile", LocalizeDictionary.Instance.Culture).ToString(); error = true; } catch (Exception ex) { log.Error($"File Read: Error processing file: {song.FullFileName} {ex.Message}"); errorMessage = string.Format(LocalizeDictionary.Instance.GetLocalizedObject("MPTagThat", "Strings", "message_ErrorReadingFile", LocalizeDictionary.Instance.Culture).ToString(), song.FullFileName); error = true; } if (file == null || error) { log.Error("File Read: Error processing file.: {0}", song.FullFileName); return(false); } try { // Get the ID3 Frame for ID3 specifc frame handling TagLib.Id3v1.Tag id3v1tag = null; TagLib.Id3v2.Tag id3v2tag = null; if (song.IsMp3) { id3v1tag = file.GetTag(TagTypes.Id3v1, true) as TagLib.Id3v1.Tag; id3v2tag = file.GetTag(TagTypes.Id3v2, true) as TagLib.Id3v2.Tag; } // Remove Tags, if they have been removed in TagEdit Panel foreach (TagLib.TagTypes tagType in song.TagsRemoved) { file.RemoveTags(tagType); } if (file.Tag != null) { #region Main Tags string[] splitValues = song.Artist.Split(new[] { ';', '|' }); file.Tag.Performers = splitValues; splitValues = song.AlbumArtist.Split(new[] { ';', '|' }); file.Tag.AlbumArtists = splitValues; file.Tag.Album = song.Album.Trim(); file.Tag.BeatsPerMinute = (uint)song.BPM; if (song.Comment != "") { file.Tag.Comment = ""; if (song.IsMp3) { id3v1tag.Comment = song.Comment; foreach (Comment comment in song.ID3Comments) { CommentsFrame commentsframe = CommentsFrame.Get(id3v2tag, comment.Description, comment.Language, true); commentsframe.Text = comment.Text; commentsframe.Description = comment.Description; commentsframe.Language = comment.Language; } } else { file.Tag.Comment = song.Comment; } } else { if (song.IsMp3 && id3v2tag != null) { id3v2tag.RemoveFrames("COMM"); } else { file.Tag.Comment = ""; } } if (song.IsMp3) { id3v2tag.IsCompilation = song.Compilation; } file.Tag.Disc = song.DiscNumber; file.Tag.DiscCount = song.DiscCount; splitValues = song.Genre.Split(new[] { ';', '|' }); file.Tag.Genres = splitValues; file.Tag.Title = song.Title; file.Tag.Track = song.TrackNumber; file.Tag.TrackCount = song.TrackCount; file.Tag.Year = (uint)song.Year; double gain; var replayGainTrack = string.IsNullOrEmpty(song.ReplayGainTrack) ? "" : song.ReplayGainTrack.Substring(0, song.ReplayGainTrack.IndexOf(" ", StringComparison.Ordinal)); if (double.TryParse(replayGainTrack, NumberStyles.Any, CultureInfo.InvariantCulture, out gain)) { file.Tag.ReplayGainTrackGain = gain; } if (Double.TryParse(song.ReplayGainTrackPeak, NumberStyles.Any, CultureInfo.InvariantCulture, out gain)) { file.Tag.ReplayGainTrackPeak = gain; } var replayGainAlbum = string.IsNullOrEmpty(song.ReplayGainAlbum) ? "" : song.ReplayGainAlbum.Substring(0, song.ReplayGainAlbum.IndexOf(" ", StringComparison.Ordinal)); if (Double.TryParse(replayGainAlbum, NumberStyles.Any, CultureInfo.InvariantCulture, out gain)) { file.Tag.ReplayGainAlbumGain = gain; } if (Double.TryParse(song.ReplayGainAlbumPeak, NumberStyles.Any, CultureInfo.InvariantCulture, out gain)) { file.Tag.ReplayGainAlbumPeak = gain; } #endregion #region MusicBrainz file.Tag.MusicBrainzArtistId = song.MusicBrainzArtistId; file.Tag.MusicBrainzDiscId = song.MusicBrainzDiscId; file.Tag.MusicBrainzReleaseArtistId = song.MusicBrainzReleaseArtistId; file.Tag.MusicBrainzReleaseCountry = song.MusicBrainzReleaseCountry; file.Tag.MusicBrainzReleaseGroupId = song.MusicBrainzReleaseGroupId; file.Tag.MusicBrainzReleaseId = song.MusicBrainzReleaseId; file.Tag.MusicBrainzReleaseStatus = song.MusicBrainzReleaseStatus; file.Tag.MusicBrainzTrackId = song.MusicBrainzTrackId; file.Tag.MusicBrainzReleaseType = song.MusicBrainzReleaseType; #endregion #region Detailed Information splitValues = song.Composer.Split(new[] { ';', '|' }); file.Tag.Composers = splitValues; file.Tag.Conductor = song.Conductor; file.Tag.Copyright = song.Copyright; file.Tag.Grouping = song.Grouping; splitValues = song.ArtistSortName.Split(new[] { ';', '|' }); file.Tag.PerformersSort = splitValues; splitValues = song.AlbumArtistSortName.Split(new[] { ';', '|' }); file.Tag.AlbumArtistsSort = splitValues; file.Tag.AlbumSort = song.AlbumSortName; file.Tag.TitleSort = song.TitleSortName; #endregion #region Picture List <TagLib.Picture> pics = new List <TagLib.Picture>(); foreach (Picture pic in song.Pictures) { TagLib.Picture tagPic = new TagLib.Picture(); try { byte[] byteArray = pic.Data; ByteVector data = new ByteVector(byteArray); tagPic.Data = data; tagPic.Description = pic.Description; tagPic.MimeType = "image/jpg"; tagPic.Type = pic.Type; pics.Add(tagPic); } catch (Exception ex) { log.Error("Error saving Picture: {0}", ex.Message); } file.Tag.Pictures = pics.ToArray(); } // Clear the picture if (song.Pictures.Count == 0) { file.Tag.Pictures = pics.ToArray(); } #endregion #region Lyrics if (song.Lyrics != null && song.Lyrics != "") { file.Tag.Lyrics = song.Lyrics; if (song.IsMp3) { id3v2tag.RemoveFrames("USLT"); foreach (Lyric lyric in song.LyricsFrames) { UnsynchronisedLyricsFrame lyricframe = UnsynchronisedLyricsFrame.Get(id3v2tag, lyric.Description, lyric.Language, true); lyricframe.Text = lyric.Text; lyricframe.Description = lyric.Description; lyricframe.Language = lyric.Language; } } else { file.Tag.Lyrics = song.Lyrics; } } else { file.Tag.Lyrics = ""; } #endregion #region Ratings if (song.IsMp3) { id3v2tag.RemoveFrames("POPM"); if (song.Ratings.Count > 0) { foreach (PopmFrame rating in song.Ratings) { PopularimeterFrame popmFrame = PopularimeterFrame.Get(id3v2tag, rating.User, true); popmFrame.Rating = Convert.ToByte(rating.Rating); popmFrame.PlayCount = Convert.ToUInt32(rating.PlayCount); } } } else if (song.TagType == "ogg" || song.TagType == "flac") { if (song.Ratings.Count > 0) { XiphComment xiph = file.GetTag(TagLib.TagTypes.Xiph, true) as XiphComment; xiph.SetField("RATING", song.Rating.ToString()); } } #endregion #region Non- Standard Taglib and User Defined Frames if (options.MainSettings.ClearUserFrames) { foreach (Frame frame in song.UserFrames) { ByteVector frameId = new ByteVector(frame.Id); if (frame.Id == "TXXX") { id3v2tag.SetUserTextAsString(frame.Description, "", true); } else { id3v2tag.SetTextFrame(frameId, ""); } } } List <Frame> allFrames = new List <Frame>(); allFrames.AddRange(song.Frames); // The only way to avoid duplicates of User Frames is to delete them by assigning blank values to them if (song.SavedUserFrames != null && !options.MainSettings.ClearUserFrames) { // Clean the previously saved Userframes, to avoid duplicates foreach (Frame frame in song.SavedUserFrames) { ByteVector frameId = new ByteVector(frame.Id); if (frame.Id == "TXXX") { id3v2tag.SetUserTextAsString(frame.Description, "", true); } else { id3v2tag.SetTextFrame(frameId, ""); } } allFrames.AddRange(song.UserFrames); } foreach (Frame frame in allFrames) { ByteVector frameId = new ByteVector(frame.Id); // The only way to avoid duplicates of User Frames is to delete them by assigning blank values to them if (frame.Id == "TXXX") { if (frame.Description != "") { id3v2tag.SetUserTextAsString(frame.Description, "", true); id3v2tag.SetUserTextAsString(frame.Description, frame.Value, true); } } else { id3v2tag.SetTextFrame(frameId, ""); id3v2tag.SetTextFrame(frameId, frame.Value); } } #endregion // Now, depending on which frames the user wants to save, we will remove the other Frames file = Util.FormatID3Tag(file); // Set the encoding for ID3 Tags if (song.IsMp3) { TagLib.Id3v2.Tag.ForceDefaultEncoding = true; switch (options.MainSettings.CharacterEncoding) { case "Latin1": TagLib.Id3v2.Tag.DefaultEncoding = StringType.Latin1; break; case "UTF16": TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF16; break; case "UTF16-BE": TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF16BE; break; case "UTF8": TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF8; break; case "UTF16-LE": TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF16LE; break; } } } // Save the file file.Save(); } catch (Exception ex) { log.Error("File Save: Error processing file: {0} {1}", song.FullFileName, ex.Message); errorMessage = string.Format(LocalizeDictionary.Instance.GetLocalizedObject("MPTagThat", "Strings", "message_ErrorSave", LocalizeDictionary.Instance.Culture).ToString(), song.FullFileName); error = true; } if (error) { return(false); } return(true); }
public override void RemoveTags(TagTypes types) { if ((types == (TagTypes.None | TagTypes.Id3v2)) || (types == ~TagTypes.None)) { this.tag = null; } }
/// <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); }
/// <summary> /// Save the Modified file /// </summary> /// <param name="track"></param> /// <param name="errorMessage"></param> /// <returns></returns> public static bool SaveFile(TrackData track, ref string errorMessage) { errorMessage = ""; if (!track.Changed) { return(true); } if (track.Readonly && !Options.MainSettings.ChangeReadOnlyAttributte && (Options.ReadOnlyFileHandling == 0 || Options.ReadOnlyFileHandling == 2)) { Form dlg = new ReadOnlyDialog(track.FullFileName); DialogResult dlgResult = dlg.ShowDialog(); switch (dlgResult) { case DialogResult.Yes: Options.ReadOnlyFileHandling = 0; // Yes break; case DialogResult.OK: Options.ReadOnlyFileHandling = 1; // Yes to All break; case DialogResult.No: Options.ReadOnlyFileHandling = 2; // No break; case DialogResult.Cancel: Options.ReadOnlyFileHandling = 3; // No to All break; } } if (track.Readonly) { if (!Options.MainSettings.ChangeReadOnlyAttributte && Options.ReadOnlyFileHandling > 1) { errorMessage = "File is readonly"; return(false); } try { System.IO.File.SetAttributes(track.FullFileName, System.IO.File.GetAttributes(track.FullFileName) & ~FileAttributes.ReadOnly); track.Readonly = false; } catch (Exception ex) { log.Error("File Save: Can't reset Readonly attribute: {0} {1}", track.FullFileName, ex.Message); errorMessage = ServiceScope.Get <ILocalisation>().ToString("message", "ErrorResetAttr"); return(false); } } TagLib.File file = null; bool error = false; try { TagLib.ByteVector.UseBrokenLatin1Behavior = true; file = TagLib.File.Create(track.FullFileName); } catch (CorruptFileException) { log.Warn("File Read: Ignoring track {0} - Corrupt File!", track.FullFileName); errorMessage = ServiceScope.Get <ILocalisation>().ToString("message", "CorruptFile"); error = true; } catch (UnsupportedFormatException) { log.Warn("File Read: Ignoring track {0} - Unsupported format!", track.FullFileName); errorMessage = ServiceScope.Get <ILocalisation>().ToString("message", "UnsupportedFormat"); error = true; } catch (FileNotFoundException) { log.Warn("File Read: Ignoring track {0} - Physical file no longer existing!", track.FullFileName); errorMessage = ServiceScope.Get <ILocalisation>().ToString("message", "NonExistingFile"); error = true; } catch (Exception ex) { log.Error("File Read: Error processing file: {0} {1}", track.FullFileName, ex.Message); errorMessage = string.Format(ServiceScope.Get <ILocalisation>().ToString("message", "ErrorReadingFile"), ex.Message); error = true; } if (file == null || error) { log.Error("File Read: Error processing file.: {0}", track.FullFileName); return(false); } try { // Get the ID3 Frame for ID3 specifc frame handling TagLib.Id3v1.Tag id3v1tag = null; TagLib.Id3v2.Tag id3v2tag = null; if (track.IsMp3) { id3v1tag = file.GetTag(TagTypes.Id3v1, true) as TagLib.Id3v1.Tag; id3v2tag = file.GetTag(TagTypes.Id3v2, true) as TagLib.Id3v2.Tag; } // Remove Tags, if they have been removed in TagEdit Panel foreach (TagLib.TagTypes tagType in track.TagsRemoved) { file.RemoveTags(tagType); } #region Main Tags string[] splitValues = track.Artist.Split(new[] { ';', '|' }); file.Tag.Performers = splitValues; splitValues = track.AlbumArtist.Split(new[] { ';', '|' }); file.Tag.AlbumArtists = splitValues; file.Tag.Album = track.Album.Trim(); file.Tag.BeatsPerMinute = (uint)track.BPM; if (track.Comment != "") { file.Tag.Comment = ""; if (track.IsMp3) { id3v1tag.Comment = track.Comment; foreach (Comment comment in track.ID3Comments) { CommentsFrame commentsframe = CommentsFrame.Get(id3v2tag, comment.Description, comment.Language, true); commentsframe.Text = comment.Text; commentsframe.Description = comment.Description; commentsframe.Language = comment.Language; } } else { file.Tag.Comment = track.Comment; } } else { file.Tag.Comment = ""; } if (track.IsMp3) { id3v2tag.IsCompilation = track.Compilation; } file.Tag.Disc = track.DiscNumber; file.Tag.DiscCount = track.DiscCount; splitValues = track.Genre.Split(new[] { ';', '|' }); file.Tag.Genres = splitValues; file.Tag.Title = track.Title; file.Tag.Track = track.TrackNumber; file.Tag.TrackCount = track.TrackCount; file.Tag.Year = (uint)track.Year; file.Tag.ReplayGainTrack = track.ReplayGainTrack; file.Tag.ReplayGainTrackPeak = track.ReplayGainTrackPeak; file.Tag.ReplayGainAlbum = track.ReplayGainAlbum; file.Tag.ReplayGainAlbumPeak = track.ReplayGainAlbumPeak; #endregion #region Detailed Information splitValues = track.Composer.Split(new[] { ';', '|' }); file.Tag.Composers = splitValues; file.Tag.Conductor = track.Conductor; file.Tag.Copyright = track.Copyright; file.Tag.Grouping = track.Grouping; splitValues = track.ArtistSortName.Split(new[] { ';', '|' }); file.Tag.PerformersSort = splitValues; splitValues = track.AlbumArtistSortName.Split(new[] { ';', '|' }); file.Tag.AlbumArtistsSort = splitValues; file.Tag.AlbumSort = track.AlbumSortName; file.Tag.TitleSort = track.TitleSortName; #endregion #region Picture List <TagLib.Picture> pics = new List <TagLib.Picture>(); foreach (Picture pic in track.Pictures) { TagLib.Picture tagPic = new TagLib.Picture(); try { byte[] byteArray = pic.Data; ByteVector data = new ByteVector(byteArray); tagPic.Data = data; tagPic.Description = pic.Description; tagPic.MimeType = "image/jpg"; tagPic.Type = pic.Type; pics.Add(tagPic); } catch (Exception ex) { log.Error("Error saving Picture: {0}", ex.Message); } file.Tag.Pictures = pics.ToArray(); } // Clear the picture if (track.Pictures.Count == 0) { file.Tag.Pictures = pics.ToArray(); } #endregion #region Lyrics if (track.Lyrics != null && track.Lyrics != "") { file.Tag.Lyrics = track.Lyrics; if (track.IsMp3) { foreach (Lyric lyric in track.LyricsFrames) { UnsynchronisedLyricsFrame lyricframe = UnsynchronisedLyricsFrame.Get(id3v2tag, lyric.Description, lyric.Language, true); lyricframe.Text = lyric.Text; lyricframe.Description = lyric.Description; lyricframe.Language = lyric.Language; } } else { file.Tag.Lyrics = track.Lyrics; } } else { file.Tag.Lyrics = ""; } #endregion #region Ratings if (track.IsMp3) { if (track.Ratings.Count > 0) { foreach (PopmFrame rating in track.Ratings) { PopularimeterFrame popmFrame = PopularimeterFrame.Get(id3v2tag, rating.User, true); popmFrame.Rating = Convert.ToByte(rating.Rating); popmFrame.PlayCount = Convert.ToUInt32(rating.PlayCount); } } else { id3v2tag.RemoveFrames("POPM"); } } else if (track.TagType == "ogg" || track.TagType == "flac") { if (track.Ratings.Count > 0) { XiphComment xiph = file.GetTag(TagLib.TagTypes.Xiph, true) as XiphComment; xiph.SetField("RATING", track.Rating.ToString()); } } #endregion #region Non- Standard Taglib and User Defined Frames if (Options.MainSettings.ClearUserFrames) { foreach (Frame frame in track.UserFrames) { ByteVector frameId = new ByteVector(frame.Id); if (frame.Id == "TXXX") { id3v2tag.SetUserTextAsString(frame.Description, ""); } else { id3v2tag.SetTextFrame(frameId, ""); } } } List <Frame> allFrames = new List <Frame>(); allFrames.AddRange(track.Frames); // The only way to avoid duplicates of User Frames is to delete them by assigning blank values to them if (track.SavedUserFrames != null && !Options.MainSettings.ClearUserFrames) { // Clean the previously saved Userframes, to avoid duplicates foreach (Frame frame in track.SavedUserFrames) { ByteVector frameId = new ByteVector(frame.Id); if (frame.Id == "TXXX") { id3v2tag.SetUserTextAsString(frame.Description, ""); } else { id3v2tag.SetTextFrame(frameId, ""); } } allFrames.AddRange(track.UserFrames); } foreach (Frame frame in allFrames) { ByteVector frameId = new ByteVector(frame.Id); // The only way to avoid duplicates of User Frames is to delete them by assigning blank values to them if (frame.Id == "TXXX") { if (frame.Description != "") { id3v2tag.SetUserTextAsString(frame.Description, ""); id3v2tag.SetUserTextAsString(frame.Description, frame.Value); } } else { id3v2tag.SetTextFrame(frameId, ""); id3v2tag.SetTextFrame(frameId, frame.Value); } } #endregion // Now, depending on which frames the user wants to save, we will remove the other Frames file = Util.FormatID3Tag(file); // Set the encoding for ID3 Tags if (track.IsMp3) { TagLib.Id3v2.Tag.ForceDefaultEncoding = true; switch (Options.MainSettings.CharacterEncoding) { case 0: TagLib.Id3v2.Tag.DefaultEncoding = StringType.Latin1; break; case 1: TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF16; break; case 2: TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF16BE; break; case 3: TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF8; break; case 4: TagLib.Id3v2.Tag.DefaultEncoding = StringType.UTF16LE; break; } } // Save the file file.Save(); } catch (Exception ex) { log.Error("File Save: Error processing file: {0} {1}", track.FullFileName, ex.Message); errorMessage = ServiceScope.Get <ILocalisation>().ToString("message", "ErrorSave"); error = true; } if (error) { return(false); } return(true); }
public override void RemoveTags(TagTypes types) { if ((types & (TagTypes.None | TagTypes.Id3v2)) != TagTypes.None) { this.id32_tag = null; } if ((types & TagTypes.RiffInfo) != TagTypes.None) { this.info_tag = null; } if ((types & TagTypes.MovieId) != TagTypes.None) { this.mid_tag = null; } if ((types & TagTypes.DivX) != TagTypes.None) { this.divx_tag = null; } TagLib.Tag[] tags = new TagLib.Tag[] { this.id32_tag, this.info_tag, this.mid_tag, this.divx_tag }; this.tag.SetTags(tags); }