Beispiel #1
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);
        }
Beispiel #2
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.TagType.ToLower() == "mp3")
            {
              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.TagType.ToLower() == "mp3")
              {
            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.TagType.ToLower() == "mp3")
            {
              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;

            #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;

            #endregion

            #region Picture

            List<TagLib.Picture> pics = new List<TagLib.Picture>();
            foreach (Picture pic in track.Pictures)
            {
              ImageConverter imgConverter = new ImageConverter();
              TagLib.Picture tagPic = new TagLib.Picture();

              try
              {
            byte[] byteArray = Picture.ImageToByte(pic.Data);
            ByteVector data = new ByteVector(byteArray);
            tagPic.Data = data;
            tagPic.Description = pic.Description;
            tagPic.MimeType = pic.MimeType;
            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.TagType.ToLower() == "mp3")
              {
            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.TagType.ToLower() == "mp3")
            {
              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");
            }

            #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, "");
            }
              }
            }

            // 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)
            {
              foreach (Frame frame in track.SavedUserFrames)
              {
            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);
              allFrames.AddRange(track.UserFrames);

              foreach (Frame frame in allFrames)
              {
            ByteVector frameId = new ByteVector(frame.Id);

            if (frame.Id == "TXXX")
            {
              if (frame.Description != "")
              {
                id3v2tag.SetUserTextAsString(frame.Description, frame.Value);
              }
            }
            else
            {
              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.TagType.ToLower() == "mp3")
            {
              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;
        }