private void btnRemoveID3v1_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(m_Filename)) { MessageBox.Show("No file loaded", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { DialogResult result = MessageBox.Show(string.Format("Remove ID3v1 tag from '{0}'?", Path.GetFileName(m_Filename)), "", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { Boolean success = ID3v1Tag.RemoveTag(m_Filename); if (success) { MessageBox.Show("ID3v1 tag successfully removed", "", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("ID3v1 tag not found", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } btnRemoveID3v1.Enabled = ID3v1Tag.DoesTagExist(m_Filename); ucID3v1.LoadFile(m_Filename); }
public void RemoveTag(string filePath) { try { ID3v1Tag.RemoveTag(filePath); } catch (Exception e) { throw new Exception("Removing ID3v1 error"); } }
public static Boolean removeID3v1(string fname) { Boolean success = false; var trackxml = new XMLutils(appPath + "\\trackxml.xml"); if (!String.IsNullOrEmpty(fname) && File.Exists(fname)) { success = ID3v1Tag.RemoveTag(fname); } if (success) { trackxml.Updaterecord(fname); } return(success); }
/// <summary>Saves the tag to the specified path.</summary> /// <param name="path">The full path of the file.</param> private void Save(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } if (VorbisComment.VorbisComment.IsFlac(path)) { VorbisComment.VorbisComment vc = new VorbisComment.VorbisComment(path); vc.Title = Title; vc.Artist = Artist; vc.Album = Album; vc.Year = Year; vc.Genre = Genre; vc.TrackNumber = TrackNumber; vc.Comment = Comment; vc.Save(path); ID3v2Tag.RemoveTag(path); ID3v1Tag.RemoveTag(path); } else { ID3v2Tag id3v2 = new ID3v2Tag(path); id3v2.Title = Title; id3v2.Artist = Artist; id3v2.Album = Album; id3v2.Year = Year; id3v2.Genre = Genre; id3v2.TrackNumber = TrackNumber; if (id3v2.CommentsList.Count > 0) { id3v2.CommentsList[0].Description = Comment; } else { if (!string.IsNullOrEmpty(Comment)) { id3v2.CommentsList.AddNew().Description = Comment; } } ID3v1Tag id3v1 = new ID3v1Tag(path); id3v1.Title = Title; id3v1.Artist = Artist; id3v1.Album = Album; id3v1.Year = Year; id3v1.GenreIndex = GenreHelper.GetGenreIndex(Genre); id3v1.Comment = Comment; int trackNumber; if (int.TryParse(TrackNumber, out trackNumber)) { id3v1.TrackNumber = trackNumber; } else { // Handle ##/## format if (TrackNumber.Contains("/")) { if (int.TryParse(TrackNumber.Split('/')[0], out trackNumber)) { id3v1.TrackNumber = trackNumber; } else { id3v1.TrackNumber = 0; } } else { id3v1.TrackNumber = 0; } } id3v2.Save(path); id3v1.Save(path); } Read(path); }
public bool WriteTags(AudioMetaData metaData, string filename, bool force = false) { try { if (!metaData.IsValid) { this.Logger.LogWarning($"Invalid MetaData `{ metaData }` to save to file [{ filename }]"); return(false); } ID3v1Tag.RemoveTag(filename); var trackNumber = metaData.TrackNumber ?? 1; var totalTrackNumber = metaData.TotalTrackNumbers ?? trackNumber; var disc = metaData.Disk ?? 1; var discCount = metaData.TotalDiscCount ?? disc; IID3v2Tag id3v2 = new ID3v2Tag(filename) { Artist = metaData.Artist, Album = metaData.Release, Title = metaData.Title, Year = metaData.Year.Value.ToString(), TrackNumber = totalTrackNumber < 99 ? $"{trackNumber.ToString("00")}/{totalTrackNumber.ToString("00")}" : $"{trackNumber.ToString()}/{totalTrackNumber.ToString()}", DiscNumber = discCount < 99 ? $"{disc.ToString("00")}/{discCount.ToString("00")}" : $"{disc.ToString()}/{discCount.ToString()}" }; if (metaData.TrackArtists.Any()) { id3v2.OriginalArtist = string.Join("/", metaData.TrackArtists); } if (this.Configuration.Processing.DoClearComments) { if (id3v2.CommentsList.Any()) { for (var i = 0; i < id3v2.CommentsList.Count; i++) { id3v2.CommentsList[i].Description = null; id3v2.CommentsList[i].Value = null; } } } id3v2.Save(filename); //// Delete first embedded picture (let's say it exists) //theTrack.EmbeddedPictures.RemoveAt(0); //// Add 'CD' embedded picture //PictureInfo newPicture = new PictureInfo(Commons.ImageFormat.Gif, PictureInfo.PIC_TYPE.CD); //newPicture.PictureData = System.IO.File.ReadAllBytes("E:/temp/_Images/pic1.gif"); //theTrack.EmbeddedPictures.Add(newPicture); //// Save modifications on the disc //theTrack.Save(); //tagFile.Tag.Pictures = metaData.Images == null ? null : metaData.Images.Select(x => new TagLib.Picture //{ // Data = new TagLib.ByteVector(x.Data), // Description = x.Description, // MimeType = x.MimeType, // Type = (TagLib.PictureType)x.Type //}).ToArray(); //tagFile.Save(); return(true); } catch (Exception ex) { this.Logger.LogError(ex, string.Format("MetaData [{0}], Filename [{1}]", metaData.ToString(), filename)); } return(false); }
/// <summary> /// Main output routine. /// </summary> public void Output(int storageId) { // Get correctly formed output folder. string outputFolderName = OutputFolder; if (string.IsNullOrEmpty(outputFolderName)) { throw new InvalidOperationException("An output folder has not been specified."); } // Add a slash on to the output folder so that all file processing works correctly. if (!outputFolderName.EndsWith("\\")) { outputFolderName += "\\"; } // Check that the output folder exists. if (!Directory.Exists(outputFolderName)) { throw new InvalidOperationException($"The output folder '{outputFolderName}' does not exist."); } // Notify that we've started. StatusChangedEventArgs startArgs = new StatusChangedEventArgs(0, "Starting...", false); StatusChanged?.Invoke(startArgs); // Set up error handling so that events can be raised OutputErrorEventArgs outputErrorEventArgs; // Find card so we know what playlists to export. Storage storage = new Storage(); if (storage.Find(storageId)) { // Add on name of storage. outputFolderName += FileSystem.ValidWindowsFileName(storage.StorageDescription); // If the folder doesn't exist, create it. if (!Directory.Exists(outputFolderName)) { try { Directory.CreateDirectory(outputFolderName); } catch (Exception ex) { outputErrorEventArgs = new OutputErrorEventArgs($"There was a problem creating the folder at '{outputFolderName}': {ex.Message}."); OutputError?.Invoke(outputErrorEventArgs); if (outputErrorEventArgs.Cancel) { return; } } } // Check if stuff exists in the folder, if it does then warn. DirectoryInfo outputFolder = new DirectoryInfo(outputFolderName); if (outputFolder.GetDirectories().Any() | outputFolder.GetFiles().Any()) { // Files and/or folders exist in the output folder therefore offer to delete them first. DeleteFilesEventArgs deleteFilesEventArgs = new DeleteFilesEventArgs(outputFolderName); DeleteFiles?.Invoke(deleteFilesEventArgs); if (deleteFilesEventArgs.Response == DeleteFilesResponse.Yes) { // Delete everything in the folder (recursively). foreach (DirectoryInfo directory in outputFolder.GetDirectories()) { try { directory.Delete(true); } catch (Exception ex) { outputErrorEventArgs = new OutputErrorEventArgs(string.Format("Sorry, there was a problem deleting '{0}' : {1}{2}{2}", directory.FullName, ex.Message, Environment.NewLine)); OutputError?.Invoke(outputErrorEventArgs); if (outputErrorEventArgs.Cancel) { return; } } } foreach (FileInfo file in outputFolder.GetFiles()) { try { file.Delete(); } catch (Exception ex) { outputErrorEventArgs = new OutputErrorEventArgs(string.Format("Sorry, there was a problem deleting '{0}' : {1}{2}{2}", file.FullName, ex.Message, Environment.NewLine)); OutputError?.Invoke(outputErrorEventArgs); if (outputErrorEventArgs.Cancel) { return; } } } } else if (deleteFilesEventArgs.Response == DeleteFilesResponse.Cancel) { // Cancel the export altogether. return; } } // In the output handler, the tracks needed to be added first, and then the playlists after. foreach (string playlistId in storage.Playlists) { Playlist playlist = AppMusicLibrary.PlaylistDictionary[playlistId]; if (playlist != null) { // Add MP3 music. foreach (Track track in playlist.AllTracks.Where(t => t.FileName.ToLower().EndsWith(".mp3"))) { if (track.InLibrary) { AddTrack(track.Id, track.Artist, track.Name, track.TrackTime, AppMusicLibrary.MusicFolder + track.Location); } else { AddTrack(track.Id, track.Artist, track.Name, track.TrackTime, track.Location); } } AddPlaylist(playlist.PersistentId, playlist.Name, playlist.AllTracks); } } } // Check for sensible limits. if (FileNameLengthLimit < 64) { throw new InvalidOperationException("File name length limit must be 64 characters or more."); } if (FolderTrackLimit < 0) { throw new InvalidOperationException("Folder Track limit must be 0 or more."); } if (PlaylistTrackLimit < 0) { throw new InvalidOperationException("Playlist Track limit must be 0 or more."); } // To work out a percentage, look at the total tracks to output. int totalOutputTracks = TotalOutputTracks(); int totalOutputTracksSoFar = 0; // Set up a counter to count number of tracks output so far. // Get a divisor (first 95% = the music)... double divisor = 95.0 / totalOutputTracks; if (totalOutputTracks > 0) { // Apply names, e.g. just "Music", or "Music 1", "Music 2" etc. ApplyOutputMusicFolderNames(); // Deal with one music folder at a time. foreach (OutputMusicFolder outputMusicFolder in _outputMusicFolders) { // Establish the name of the music folder string musicFolderPath = $"{outputFolderName}\\{outputMusicFolder.Name}\\"; // Folder should not exist already because whole output folder should have been wiped. if (!Directory.Exists(musicFolderPath)) { try { Directory.CreateDirectory(musicFolderPath); } catch (Exception ex) { outputErrorEventArgs = new OutputErrorEventArgs($"There was a problem creating the folder at '{musicFolderPath}': {ex.Message}."); OutputError?.Invoke(outputErrorEventArgs); // If the user pressed cancel then exit. if (outputErrorEventArgs.Cancel) { return; } } } foreach (OutputTrack outputTrack in outputMusicFolder.Tracks.Values) { // Copy all the music into this folder. string sourceFileName = outputTrack.SourceFileName; // Eliminate any characters that the RNS-E might not agree with. string destinationBaseFileName = FileSystem.ValidRnseFileName(outputTrack.Name + " - " + outputTrack.Artist); // Make sure that full path in M3U is no longer than the specified limit. // // e.g. 64 characters minus the Folder name + slash + .mp3 int maximumFileNameLength = FileNameLengthLimit - (outputMusicFolder.Name.Length + 5); // If necessary, truncate the base file name (i.e. the Name - Artist) to the maximum allowed. if (destinationBaseFileName.Length > maximumFileNameLength) { destinationBaseFileName = destinationBaseFileName.Substring(0, maximumFileNameLength); } // Test for some files being the same name when truncated. string destinationFileName = musicFolderPath + destinationBaseFileName + ".mp3"; int fileNameSuffixCount = 0; // If the file doesn't exist already, then this loop will be skipped over. while (File.Exists(destinationFileName)) { // If file does exist there may be some tracks which are lengthy in name, but only different in the last few characters.. this may have been // truncated before we get to here. Therefore we still need to give them a different file name by applying a "1", "2" etc. on the end. fileNameSuffixCount += 1; // Get a proposed file name for when the suffix is added. Just trim off however many characters needed at the end, and add number. string amendedDestinationBaseFileName = destinationBaseFileName.Substring(0, destinationBaseFileName.Length - fileNameSuffixCount.ToString().Length); // Append number so now overall filename should still be no more than the limit. destinationFileName = musicFolderPath + amendedDestinationBaseFileName + fileNameSuffixCount + ".mp3"; } outputTrack.DestinationFileName = destinationFileName; // Check that the source file exists before trying to copy it. if (File.Exists(sourceFileName)) { // Check whether destination file exists. It shouldn't because of logic further up, but still... if (File.Exists(outputTrack.DestinationFileName)) { outputErrorEventArgs = new OutputErrorEventArgs($"The file '{outputTrack.DestinationFileName}' already exists. Continue the export?"); OutputError?.Invoke(outputErrorEventArgs); // If the user pressed cancel then exit. if (outputErrorEventArgs.Cancel) { return; } } // Work out a percentage complete figure. int percentProgress = Convert.ToInt32(totalOutputTracksSoFar * divisor); // Check for cancellation. StatusChangedEventArgs exportingFileArgs = new StatusChangedEventArgs(percentProgress, "Exporting '" + Path.GetFileName(outputTrack.DestinationFileName) + "'...", false); StatusChanged?.Invoke(exportingFileArgs); if (exportingFileArgs.Cancel) { return; } try { File.Copy(sourceFileName, outputTrack.DestinationFileName, true); } catch (Exception) { outputErrorEventArgs = new OutputErrorEventArgs("There was a problem copying from '" + sourceFileName + "' to '" + outputTrack.DestinationFileName + "'."); OutputError?.Invoke(outputErrorEventArgs); // If the user pressed cancel then exit. if (outputErrorEventArgs.Cancel) { return; } } if (StripId3V1Tags) { // Should Remove ID3V1 tag for two reasons: // (a) Just in case any "helpful" Windows software comes along and tries to automatically add a V2 tag back. // (b) The description output in the M3U playlist is recognised and shown by the RNS-E on the DIS and so this makes any tag redundant anyway. try { ID3v1Tag.RemoveTag(outputTrack.DestinationFileName); } catch (Exception) { // Ignore any error (e.g. if no tag there anyway). } } if (StripId3V2Tags) { // Should Remove any ID3V2 tag because my RNS-E doesn't play any MP3 with this tag (contrary to the Audi instruction manual). try { ID3v2Tag.RemoveTag(outputTrack.DestinationFileName); } catch (Exception) { // Ignore any error (e.g. if no tag there anyway). } } } else { outputErrorEventArgs = new OutputErrorEventArgs($"The file '{sourceFileName}' does not exist."); OutputError?.Invoke(outputErrorEventArgs); // If the user pressed cancel then exit/ if (outputErrorEventArgs.Cancel) { return; } } // Add to value so that percentage can update properly/ totalOutputTracksSoFar += 1; } } // Check for cancellation. StatusChangedEventArgs exportingPlaylistsArgs = new StatusChangedEventArgs(97, "Exporting Playlists...", false); StatusChanged?.Invoke(exportingPlaylistsArgs); if (exportingPlaylistsArgs.Cancel) { return; } // Apply names to playlists before they are output. ApplyOutputPlaylistNames(); // Create all the playlists on disk. foreach (OutputPlaylist outputPlaylist in _outputPlaylists) { if (outputPlaylist.Tracks.Any()) { // Create an M3U file for the playlist in the output folder (make sure this is OK within RNS-E rules). FileStream fileM3U = null; string m3UFileName = Path.Combine(outputFolderName, FileSystem.ValidRnseFileName(outputPlaylist.Name) + ".m3u"); try { fileM3U = File.Create(m3UFileName); } catch (Exception) { outputErrorEventArgs = new OutputErrorEventArgs("There was a problem creating the '" + m3UFileName + "' file."); OutputError?.Invoke(outputErrorEventArgs); // If the user pressed cancel then exit. if (outputErrorEventArgs.Cancel) { return; } } if (fileM3U != null) { // Open the file for writing based upon this stream. StreamWriter writeM3U = new StreamWriter(fileM3U); writeM3U.WriteLine("#EXTM3U"); foreach (string outputTrack in outputPlaylist.Tracks) { // Find which music folder we put the track into, in the end. OutputMusicFolder trackOutputMusicFolder = FindOutputMusicFolderByTrack(outputTrack); if (trackOutputMusicFolder != null && trackOutputMusicFolder.Tracks.ContainsKey(outputTrack)) { // Get the exact file being referred to by the Id. OutputTrack track = trackOutputMusicFolder.Tracks[outputTrack]; // Write an entry in the M3U. writeM3U.WriteLine("#EXTINF:{0},{1} - {2}", track.TrackTime, track.Name, track.Artist); writeM3U.WriteLine("{0}\\{1}", trackOutputMusicFolder.Name, Path.GetFileName(track.DestinationFileName)); } } // Clean up. writeM3U.Flush(); writeM3U.Close(); fileM3U.Close(); } } } } StatusChanged?.Invoke(new StatusChangedEventArgs(100, "Completed.", false)); }