Example #1
0
        /// <summary>
        /// Retrieve a tag with an arbitrary name.
        /// Returns an empty tag if the value isn't found or if no Xiph tags are present.
        /// </summary>
        /// <param name="TagName">
        /// A <see cref="System.String"/> containing the name of the tag to find
        /// </param>
        /// <returns>
        /// An <see cref="OggTag"/> containing the returned tag
        /// </returns>
        public OggTag GetTag(string TagName)
        {
            if (TagName.Length <= 0)
            {
                return(OggUtilities.GetEmptyTag());
            }                                                                         // Save some processing time and just exit if we haven't been given a tag name
            // Based on tasty examples @ "Accessing Hidden Gems": http://developer.novell.com/wiki/index.php/TagLib_Sharp:_Examples
            XiphComment XC = (XiphComment)m_TagLibFile.GetTag(TagTypes.Xiph);

            if (XC != null)
            {
                string[] TagValue = XC.GetField(TagName);
                if (TagValue.Length == 0)
                {
                    // Tag doesn't exist, return empty
                    return(OggUtilities.GetEmptyTag());
                }
                else
                {
                    OggTag tmpTag;
                    tmpTag.Name    = TagName;
                    tmpTag.IsArray = (TagValue.Length > 1);
                    tmpTag.IsEmpty = false;
                    tmpTag.Values  = TagValue;
                    tmpTag.Value   = TagValue[0];
                    return(tmpTag);
                }
            }
            else
            {
                // No valid Xiph tags found
                return(OggUtilities.GetEmptyTag());
            }
        }
Example #2
0
        protected override void SetPicture(TagLib.File file, Tag tag)
        {
            TagLib.Ogg.File oggFile           = (TagLib.Ogg.File)file;
            GroupedComment  groupedCommentTag = (GroupedComment)tag;

            if (string.IsNullOrWhiteSpace(CoverFilePath))
            {
                return;
            }

            // Is there a way to get Ogg file header using TagLib#?
            PropertyInfo headerProp = oggFile.GetType().GetProperty("LastPageHeader", BindingFlags.Instance | BindingFlags.NonPublic);
            PageHeader   header     = (PageHeader)headerProp.GetValue(oggFile);

            // Add cover art to Vorbis Comment approved METADATA_BLOCK_PICTURE field.
            TagLib.Flac.Picture pic = new TagLib.Flac.Picture(new Picture(CoverFilePath))
            {
                Description = ""
            };
            ByteVector picData = pic.Render();

            XiphComment xiphComment = groupedCommentTag.GetComment(header.StreamSerialNumber);

            xiphComment.SetField("METADATA_BLOCK_PICTURE", Convert.ToBase64String(picData.Data));
        }
Example #3
0
        /// <summary>
        ///    Replaces the comment packet in a collection of packets
        ///    with the rendered version of a Xiph comment or inserts a
        ///    comment packet if the stream lacks one.
        /// </summary>
        /// <param name="packets">
        ///    A <see cref="ByteVectorCollection" /> object containing
        ///    a collection of packets.
        /// </param>
        /// <param name="comment">
        ///    A <see cref="XiphComment" /> object to store the rendered
        ///    version of in <paramref name="packets" />.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="packets" /> or <paramref name="comment"
        ///    /> is <see langword="null" />.
        /// </exception>
        public override void SetCommentPacket(ByteVectorCollection packets,
                                              XiphComment comment)
        {
            if (packets == null)
            {
                throw new ArgumentNullException("packets");
            }

            if (comment == null)
            {
                throw new ArgumentNullException("comment");
            }

            ByteVector data = new ByteVector((byte)0x03);

            data.Add(id);
            data.Add(comment.Render(true));
            if (packets.Count > 1 && PacketType(packets [1]) == 0x03)
            {
                if (data.Count < packets [1].Count)
                {
                    data.Add(new ByteVector(packets [1].Count - data.Count, 0));
                }
                packets [1] = data;
            }
            else
            {
                packets.Insert(1, data);
            }
        }
Example #4
0
        /// <summary>
        /// Remove a tag from the file.
        /// This command writes to disk.
        /// </summary>
        /// <param name="TagName">
        /// A <see cref="System.String"/> indicating which tag to remove
        /// </param>
        /// <returns>
        /// An <see cref="OggTagWriteCommandReturn"/> indicating the result of the operation
        /// </returns>
        public OggTagWriteCommandReturn RemoveTag(string TagName)
        {
            // Check that the tag name contains at least one character
            if (TagName.Length < 1)
            {
                return(OggTagWriteCommandReturn.UnknownTag);
            }
            XiphComment XC = (XiphComment)m_TagLibFile.GetTag(TagTypes.Xiph, false);

            if (XC != null)
            {
                // Remove the tag
                XC.RemoveField(TagName);
                // Copy the XC instance into our file (might need to clear the Xiph block first, but we'll see)
                XC.CopyTo(m_TagLibFile.Tag, true);
                // Save
                m_TagLibFile.Save();
                return(OggTagWriteCommandReturn.Success);
            }
            else
            {
                // Either there isn't a Xiph comment block or something went wrong
                return(OggTagWriteCommandReturn.Error);
            }
        }
Example #5
0
        /// <summary>
        ///    Replaces the comment packet in a collection of packets
        ///    with the rendered version of a Xiph comment or inserts a
        ///    comment packet if the stream lacks one.
        /// </summary>
        /// <param name="packets">
        ///    A <see cref="ByteVectorCollection" /> object containing
        ///    a collection of packets.
        /// </param>
        /// <param name="comment">
        ///    A <see cref="XiphComment" /> object to store the rendered
        ///    version of in <paramref name="packets" />.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="packets" /> or <paramref name="comment"
        ///    /> is <see langword="null" />.
        /// </exception>
        public override void SetCommentPacket(ByteVectorCollection packets,
                                              XiphComment comment)
        {
            if (packets == null)
            {
                throw new ArgumentNullException("packets");
            }

            if (comment == null)
            {
                throw new ArgumentNullException("comment");
            }

            ByteVector data = new ByteVector();

            data.Add(magic_signature_comment);
            data.Add(comment.Render(true));
            if (packets.Count > 1 && MagicSignature(packets [1])
                == magic_signature_comment)
            {
                packets [1] = data;
            }
            else
            {
                packets.Insert(1, data);
            }
        }
Example #6
0
        public void TestWriteFlacUid()
        {
            var flacFile = string.Format("{0}\\{1:N}.flac", Path.GetTempPath(), Guid.NewGuid());

            System.IO.File.Copy(@"TestData\hei.flac", flacFile, true);

            var file = File.Create(flacFile);

            Metadata metadata = (Metadata)file.GetTag(TagTypes.FlacMetadata, true);

            XiphComment xiphComment = (XiphComment)metadata.Tags.First();

            xiphComment.SetField("SW-AlbumUid", Guid.NewGuid().ToString("N"));
            file.Save();
            //metadata.SetTextFrame((ReadOnlyByteVector) "UFID", "http://www.id3.org/dummy/ufid.html", Guid.NewGuid().ToString("N"));

            //file.Save();

            //File actualFile = File.Create(mp3File);

            //metadata = (Tag)actualFile.GetTag(TagTypes.Id3v2, true);
            //// Get the private frame, create if necessary.
            //var frame = metadata.GetFrames().FirstOrDefault(f => f.FrameId == "UFID");
            //frame.Should().NotBeNull();

            System.IO.File.Delete(flacFile);
        }
Example #7
0
        /// <summary>
        /// Write a single Xiph tag to the file
        /// This will overwrite the tag if it already exists, or create it if it doesn't
        /// It will also create the Xiph tag block within the file if it doesn't already have one
        /// This function writes to disk. If setting multiple tags consider using SetTags(OggTag[] Tags) to reduce the number of write operations
        /// If setting an array, Tag.Values must contain at least one item. Tag.Value is ignored in this case
        /// If setting a single value, Tag.Value must contain at least one character. Tag.Values is ignored in this case
        /// </summary>
        /// <param name="Tag">
        /// The <see cref="OggTag"/> to write
        /// </param>
        /// <returns>
        /// An <see cref="OggTagWriteCommandReturn"/> indicating the result of the operation
        /// </returns>
        public OggTagWriteCommandReturn SetTag(OggTag Tag)
        {
            // Validate Tag
            if (Tag.IsEmpty)
            {
                return(OggTagWriteCommandReturn.InvalidValue);
            }
            if (Tag.Name.Length <= 0)
            {
                return(OggTagWriteCommandReturn.UnknownTag);
            }
            if (Tag.IsArray)
            {
                if (Tag.Values.Length <= 0)
                {
                    return(OggTagWriteCommandReturn.InvalidValue);
                }
            }
            else
            {
                if (Tag.Value.Length <= 0)
                {
                    return(OggTagWriteCommandReturn.InvalidValue);
                }
            }
            // Tag valid, try and write it
            XiphComment XC = (XiphComment)m_TagLibFile.GetTag(TagTypes.Xiph, true);

            if (XC != null)
            {
                string[] tmpStrArray;
                if (Tag.IsArray)
                {
                    tmpStrArray = Tag.Values;
                }
                else
                {
                    tmpStrArray = new string[1]; tmpStrArray[0] = Tag.Value;
                }
                // Set field
                XC.SetField(Tag.Name, tmpStrArray);
                // Copy the XC instance into our file (not sure if this is needed)
                XC.CopyTo(m_TagLibFile.Tag, true);
                // Commit
                m_TagLibFile.Save();
                return(OggTagWriteCommandReturn.Success);
            }
            else
            {
                // If we're null something went wrong (we tried to create the XiphComment block and it failed probably)
                return(OggTagWriteCommandReturn.Error);
            }
        }
Example #8
0
 public override void SetCommentPacket (ByteVectorCollection packets, XiphComment comment)
 {
    if (packets == null)
       throw new ArgumentNullException ("packets");
    
    if (comment == null)
       throw new ArgumentNullException ("comment");
    
    ByteVector data = new ByteVector ((byte) 0x03);
    data.Add (id);
    data.Add (comment.Render (true));
    if (packets.Count > 1 && PacketType (packets [1]) == 0x03)
       packets [1] = data;
    else
       packets.Insert (1, data);
 }
Example #9
0
        /// <summary>
        /// Retrieve an array of all tag values
        /// Returns a zero-length array if no Xiph tags are found
        /// </summary>
        /// <returns>
        /// An <see cref="OggTag[]"/> containing the returned values
        /// </returns>
        public OggTag[] GetTags()
        {
            XiphComment XC = (XiphComment)m_TagLibFile.GetTag(TagTypes.Xiph);

            if (XC != null)
            {
                if (XC.FieldCount > 0)
                {
                    OggTag[] tmpOggTag = new OggTag[XC.FieldCount];
                    int      Index     = 0;
                    foreach (string FieldName in XC)
                    {
                        string[] TagValue = XC.GetField(FieldName);
                        if (TagValue.Length == 0)
                        {
                            tmpOggTag[Index] = OggUtilities.GetEmptyTag();                                      // This should never happen, but I bet if I don't check it it will!
                        }
                        else
                        {
                            // Populate this tag
                            tmpOggTag[Index].Name    = FieldName;
                            tmpOggTag[Index].IsArray = (TagValue.Length > 1);
                            tmpOggTag[Index].IsEmpty = false;
                            tmpOggTag[Index].Values  = TagValue;
                            tmpOggTag[Index].Value   = TagValue[0];
                        }
                        ++Index;                                // Increment the index so we know which OggTag we're molesting
                    }
                    // Done! Return the heap of tags
                    return(tmpOggTag);
                }
                else
                {
                    // Xiph tags contain no items
                    return(new OggTag[0]);
                }
            }
            else
            {
                // No valid Xiph tags found
                return(new OggTag[0]);
            }
        }
 public XiphComment GetComment(bool create, Tag copy)
 {
     foreach (Tag tag in this.Tags)
     {
         if (tag is XiphComment)
         {
             return (tag as XiphComment);
         }
     }
     if (!create)
     {
         return null;
     }
     XiphComment target = new XiphComment();
     if (copy != null)
     {
         copy.CopyTo(target, true);
     }
     base.AddTag(target);
     return target;
 }
Example #11
0
 public override void SetCommentPacket(ByteVectorCollection packets, XiphComment comment)
 {
     if (packets == null)
     {
         throw new ArgumentNullException("packets");
     }
     if (comment == null)
     {
         throw new ArgumentNullException("comment");
     }
     byte[] data = new byte[] { 0x81 };
     ByteVector item = new ByteVector(data) {
         id,
         comment.Render(1)
     };
     if ((packets.Count > 1) && (PacketType(packets[1]) == 0x81))
     {
         packets[1] = item;
     }
     else
     {
         packets.Insert(1, item);
     }
 }
Example #12
0
		/// <summary>
		///    Replaces the comment packet in a collection of packets
		///    with the rendered version of a Xiph comment or inserts a
		///    comment packet if the stream lacks one.
		/// </summary>
		/// <param name="packets">
		///    A <see cref="ByteVectorCollection" /> object containing
		///    a collection of packets.
		/// </param>
		/// <param name="comment">
		///    A <see cref="XiphComment" /> object to store the rendered
		///    version of in <paramref name="packets" />.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///    <paramref name="packets" /> or <paramref name="comment"
		///    /> is <see langword="null" />.
		/// </exception>
		public override void SetCommentPacket (ByteVectorCollection packets,
		                                       XiphComment comment)
		{
			if (packets == null)
				throw new ArgumentNullException ("packets");

			if (comment == null)
				throw new ArgumentNullException ("comment");

			ByteVector data = new ByteVector ();
			data.Add (magic_signature_comment);
			data.Add (comment.Render (true));
			if (packets.Count > 1 && MagicSignature (packets [1])
						  == magic_signature_comment)
				packets [1] = data;
			else
				packets.Insert (1, data);
		}
Example #13
0
        /// <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);
        }
Example #14
0
        /// <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);
        }
Example #15
0
 /// <summary>
 ///    Stores a Xiph comment in the codec-specific comment
 ///    packet.
 /// </summary>
 /// <param name="comment">
 ///    A <see cref="XiphComment" /> object to store in the
 ///    comment packet.
 /// </param>
 public void SetComment(XiphComment comment)
 {
     codec.SetCommentPacket(packets, comment);
 }
Example #16
0
		/// <summary>
		///    Replaces the comment packet in a collection of packets
		///    with the rendered version of a Xiph comment or inserts a
		///    comment packet if the stream lacks one.
		/// </summary>
		/// <param name="packets">
		///    A <see cref="ByteVectorCollection" /> object containing
		///    a collection of packets.
		/// </param>
		/// <param name="comment">
		///    A <see cref="XiphComment" /> object to store the rendered
		///    version of in <paramref name="packets" />.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///    <paramref name="packets" /> or <paramref name="comment"
		///    /> is <see langword="null" />.
		/// </exception>
		public abstract void SetCommentPacket (ByteVectorCollection packets,
		                                       XiphComment comment);
Example #17
0
        /// <summary>
        ///    Adds a Xiph comment to the current instance.
        /// </summary>
        /// <param name="streamSerialNumber">
        ///    A <see cref="uint" /> value containing the serial number
        ///    of the stream containing the comment.
        /// </param>
        /// <param name="comment">
        ///    A <see cref="XiphComment" /> object to add to the current
        ///    instance.
        /// </param>
        public void AddComment(uint streamSerialNumber,
		                        XiphComment comment)
        {
            comment_hash.Add (streamSerialNumber, comment);
            tags.Add (comment);
        }
Example #18
0
 /// <summary>
 ///    Replaces the comment packet in a collection of packets
 ///    with the rendered version of a Xiph comment or inserts a
 ///    comment packet if the stream lacks one.
 /// </summary>
 /// <param name="packets">
 ///    A <see cref="ByteVectorCollection" /> object containing
 ///    a collection of packets.
 /// </param>
 /// <param name="comment">
 ///    A <see cref="XiphComment" /> object to store the rendered
 ///    version of in <paramref name="packets" />.
 /// </param>
 /// <exception cref="ArgumentNullException">
 ///    <paramref name="packets" /> or <paramref name="comment"
 ///    /> is <see langword="null" />.
 /// </exception>
 public abstract void SetCommentPacket(ByteVectorCollection packets,
                                       XiphComment comment);
Example #19
0
        /// <summary>
        /// Write multiple Xiph tags to the file
        /// This will overwrite any existing tags, and create them if they don't exist
        /// It will also create the Xiph tag block within the file if it doesn't already have one
        /// This function writes to disk. If setting only a single tag, consider using SetTag(OggTag Tag) to reduce the array handling overheads
        /// If setting an array value Tags[i].Values must contain at least one item. Tags[i].Value is ignored in this case
        /// If setting a single value, Tags[i].Value must contain at least one character. Tags[i].Values is ignored in this case
        /// If AbortOnError is true, this function will abort (and not write) if any item in the Tags array is invalid.
        /// If AbortOnError is false, this function will continue (and write) if items in the Tags array are invalid. It will still abort (and not write) if there are other errors.
        /// </summary>
        /// <param name="Tags">
        /// An <see cref="OggTag[]"/> containing the tags to be written
        /// </param>
        /// <param name="AbortOnError">
        /// A <see cref="System.bool"/> indicating whether to invalid items in the Tags array.
        /// <returns>
        /// An <see cref="OggTagWriteCommandReturn"/> indicating the result of the operation
        /// </returns>
        public OggTagWriteCommandReturn SetTags(OggTag[] Tags, bool AbortOnError)
        {
            // Check that the Tags array has at least one item in it
            if (Tags.Length < 1)
            {
                return(OggTagWriteCommandReturn.UnknownTag);
            }
            XiphComment XC = (XiphComment)m_TagLibFile.GetTag(TagTypes.Xiph, true);

            if (XC != null)
            {
                // Write the tags to the 'virtual' file
                foreach (OggTag Tag in Tags)
                {
                    // Validate tag
                    if (Tag.IsEmpty)
                    {
                        if (AbortOnError)
                        {
                            return(OggTagWriteCommandReturn.InvalidValue);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    if (Tag.Name.Length <= 0)
                    {
                        if (AbortOnError)
                        {
                            return(OggTagWriteCommandReturn.UnknownTag);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    if (Tag.IsArray)
                    {
                        if (Tag.Values.Length <= 0)
                        {
                            if (AbortOnError)
                            {
                                return(OggTagWriteCommandReturn.InvalidValue);
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                    else
                    {
                        if (Tag.Value.Length <= 0)
                        {
                            if (AbortOnError)
                            {
                                return(OggTagWriteCommandReturn.InvalidValue);
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                    string[] tmpStrArray;
                    if (Tag.IsArray)
                    {
                        tmpStrArray = Tag.Values;
                    }
                    else
                    {
                        tmpStrArray = new string[1]; tmpStrArray[0] = Tag.Value;
                    }
                    // Write tag
                    XC.SetField(Tag.Name, tmpStrArray);
                }
                // Copy the XC instance into our file (not sure if this is needed)
                XC.CopyTo(m_TagLibFile.Tag, true);
                // Save to disk
                m_TagLibFile.Save();
                return(OggTagWriteCommandReturn.Success);
            }
            else
            {
                // If we're null something went wrong (we tried to create the XiphComment block and it failed probably)
                return(OggTagWriteCommandReturn.Error);
            }
        }
Example #20
0
        /// <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 void SetComment(XiphComment comment)
 {
     this.codec.SetCommentPacket(this.packets, comment);
 }
Example #22
0
		/// <summary>
		///    Stores a Xiph comment in the codec-specific comment
		///    packet.
		/// </summary>
		/// <param name="comment">
		///    A <see cref="XiphComment" /> object to store in the
		///    comment packet.
		/// </param>
		public void SetComment (XiphComment comment)
		{
			codec.SetCommentPacket (packets, comment);
		}