// Write a media-file's metadata (tags) from a SongInfo struct... // Returns true if success. //--------------------------------------------------------------------------- public bool Write(SongInfo si, string file) { bool bRet = false; // Presume error if (FilterInList(Path.GetExtension(file).ToLower())) { try { // Attribute types: // WM_TYPE_DWORD = 0; // WM_TYPE_STRING = 1; // WM_TYPE_BINARY = 2; // WM_TYPE_BOOL = 3; // WM_TYPE_QWORD = 4; // WM_TYPE_WORD = 5; // WM_TYPE_GUID = 6; using (MediaDataManager Editor = new MediaDataManager()) // WMA Editor... { // See the end of this file for a list of windows media attributes... if (si.bAlbumTag) Editor.SetAttrib(file, 0, "WM/AlbumTitle", WmTypes.WM_TYPE_STRING, si.Album); if (si.bTitleTag) Editor.SetAttrib(file, 0, "Title", WmTypes.WM_TYPE_STRING, si.Title); if (si.bArtistTag) Editor.SetAttrib(file, 0, "WM/AlbumArtist", WmTypes.WM_TYPE_STRING, si.Artist); if (si.bPerformerTag) Editor.SetAttrib(file, 0, "Author", WmTypes.WM_TYPE_STRING, si.Performer); if (si.bCommentsTag) Editor.SetAttrib(file, 0, "WM/Text", WmTypes.WM_TYPE_STRING, si.Comments); if (si.bGenreTag) Editor.SetAttrib(file, 0, "WM/Genre", WmTypes.WM_TYPE_STRING, si.Genre); if (si.bPublisherTag) Editor.SetAttrib(file, 0, "WM/Publisher", WmTypes.WM_TYPE_STRING, si.Publisher); if (si.bComposerTag) Editor.SetAttrib(file, 0, "WM/Composer", WmTypes.WM_TYPE_STRING, si.Composer); if (si.bConductorTag) Editor.SetAttrib(file, 0, "WM/Conductor", WmTypes.WM_TYPE_STRING, si.Conductor); if (si.bYearTag) Editor.SetAttrib(file, 0, "WM/Year", WmTypes.WM_TYPE_STRING, si.Year); if (si.bLyricsTag) Editor.SetAttrib(file, 0, "WM/Lyrics", WmTypes.WM_TYPE_STRING, si.Lyrics); // This is at https://picard.musicbrainz.org/docs/mappings/ if (si.bAcoustIDTag) Editor.SetAttrib(file, 0, "Acoustid/Id", WmTypes.WM_TYPE_STRING, si.AcoustID); if (si.bMBIDTag) Editor.SetAttrib(file, 0, "MusicBrainz/Track Id", WmTypes.WM_TYPE_STRING, si.MBID); // Additional Info: if (si.bCopyrightTag) Editor.SetAttrib(file, 0, "Copyright", WmTypes.WM_TYPE_STRING, si.Copyright); if (si.bDescriptionTag) Editor.SetAttrib(file, 0, "Description", WmTypes.WM_TYPE_STRING, si.Description); try { if (si.bTrackTag) Editor.SetAttrib(file, 0, "WM/TrackNumber", WmTypes.WM_TYPE_DWORD, si.Track); if (si.bBitrateTag) Editor.SetAttrib(file, 0, "Bitrate", WmTypes.WM_TYPE_DWORD, si.BitRate.ToString()); if (si.bFilesizeTag) Editor.SetAttrib(file, 0, "FileSize", WmTypes.WM_TYPE_QWORD, si.FileSize.ToString()); } catch { } // Duration is read-only! // These don't exist for windows media files... // .TrackCount = (uint)si.TrackCount; // .Disc = (uint)si.Disc; // .DiscCount = (uint)si.DiscCount; // .AudioChannels = si.Channels; // .BitsPerSample = si.BitsPerSample; // .AudioSampleRate = si.SampleRate; bRet = true; } // end using } catch { } } else try { using (TagLib.File f = TagLib.File.Create(file)) // Use taglib-sharp... { // Get the tag-frame and create it if necessary... TagLib.Id3v2.Tag tag = (TagLib.Id3v2.Tag)f.GetTag(TagLib.TagTypes.Id3v2, true); if (tag == null) return false; if (si.bAlbumTag) tag.Album = si.Album; if (si.bTitleTag) tag.Title = si.Title; if (si.bCommentsTag) tag.Comment = si.Comments; if (si.bGenreTag) { // Get list of artists, if any, and re-write string[] Genres = tag.Genres; if (Genres.Length == 0) tag.Genres = new string[] { si.Genre }; else { Genres[0] = si.Genre; tag.Genres = Genres; } } if (si.bComposerTag) { // Get list of artists, if any, and re-write string[] Composers = tag.Composers; if (Composers.Length == 0) tag.Composers = new string[] { si.Composer }; else { Composers[0] = si.Composer; tag.Composers = Composers; } } if (si.bArtistTag) { // Get list of artists, if any, and re-write string[] Artists = tag.AlbumArtists; if (Artists.Length == 0) tag.AlbumArtists = new string[] { si.Artist }; else { Artists[0] = si.Artist; tag.AlbumArtists = Artists; } } if (si.bPerformerTag) { // Get list of performers, if any, and re-write string[] Performers = tag.Performers; if (Performers.Length == 0) tag.Performers = new string[] { si.Performer }; else { Performers[0] = si.Performer; tag.Performers = Performers; } } if (si.bPublisherTag) tag.Publisher = si.Publisher; if (si.bConductorTag) tag.Conductor = si.Conductor; if (si.bYearTag) { try { tag.Year = Convert.ToUInt32(si.Year); } catch { tag.Year = 0; } } if (si.bTrackTag) { try { tag.Track = Convert.ToUInt32(si.Track); } catch { tag.Track = 0; } } // if (si.bDurationTag) // DURATION IS READ-ONLY! // Additional Info: if (si.bLyricsTag) tag.Lyrics = si.Lyrics; if (si.bAcoustIDTag) tag.MusicIpId = si.AcoustID; if (si.bMBIDTag) tag.MusicBrainzTrackId = si.MBID; if (si.bCopyrightTag) tag.Copyright = si.Copyright; if (si.bTrackCountTag) tag.TrackCount = (uint)si.TrackCount; if (si.bDiscTag) tag.Disc = (uint)si.Disc; if (si.bDiscCountTag) tag.DiscCount = (uint)si.DiscCount; // CAN'T SET THESE in taglib-sharp because they are read-only! //f.Properties.Description = si.Description; //f.Properties.AudioBitrate = si.BitRate; //f.Properties.AudioChannels = si.Channels; //f.Properties.BitsPerSample = si.BitsPerSample; //f.Properties.AudioSampleRate = si.SampleRate; //f.Length = si.FileSize; tag.CopyTo(f.Tag, true); // Overwrite the song file's tag... f.Save(); // Save tag bRet = true; } // end using } catch { } return bRet; }
// Read a media-file's metadata (tags) into a SongInfo struct... //--------------------------------------------------------------------------- public SongInfo Read(string file) { SongInfo si = new SongInfo(); si.FilePath = file; if (FilterInList(Path.GetExtension(file).ToLower())) { try { si.FileType = SongInfo.FT_WMA; // wma tag info MediaDataManager mdm = new MediaDataManager(); if (mdm == null) { si.bException = true; // Error return si; } TrackInfo ti; try { ti = mdm.RetrieveTrackInfo(file); } catch { si.bException = true; return si; } si.Duration = ti.Duration; if (si.Duration.TotalSeconds > 0) si.bDurationTag = true; if (ti.Title != null) { si.Title = ti.Title.Trim(); if (!string.IsNullOrEmpty(si.Title)) si.bTitleTag = true; } if (ti.AlbumArtist != null) { si.Artist = ti.AlbumArtist.Trim(); if (!string.IsNullOrEmpty(si.Artist)) si.bArtistTag = true; } // ti.Author: The Author attribute is the name of a media artist or actor associated with the content. // This attribute may have multiple values. To retrieve all of the values for a multi-valued attribute, you must use // the Media.getItemInfoByType method, not the Media.getItemInfo (WinMediaLib project) method. // Same as FirstPerformer in a mp3 file if (ti.Author != null) { si.Performer = ti.Author.Trim(); if (!string.IsNullOrEmpty(si.Performer)) si.bPerformerTag = true; } if (ti.AlbumTitle != null) { si.Album = ti.AlbumTitle.Trim(); if (!string.IsNullOrEmpty(si.Album)) si.bAlbumTag = true; } if (ti.Composer != null) { si.Composer = ti.Composer.Trim(); if (!string.IsNullOrEmpty(si.Composer)) si.bComposerTag = true; } if (ti.Genre != null) { si.Genre = ti.Genre.Trim(); if (!string.IsNullOrEmpty(si.Genre)) si.bGenreTag = true; } if (ti.Text != null) { si.Comments = ti.Text.Trim(); if (!string.IsNullOrEmpty(si.Comments)) si.bCommentsTag = true; } if (ti.Lyrics != null) { si.Lyrics = ti.Lyrics.Trim(); if (!string.IsNullOrEmpty(si.Lyrics)) si.bLyricsTag = true; } if (ti.AcoustID != null) { si.AcoustID = ti.AcoustID.Trim(); if (!string.IsNullOrEmpty(si.AcoustID)) si.bAcoustIDTag = true; } if (ti.MBID != null) { si.MBID = ti.MBID.Trim(); if (!string.IsNullOrEmpty(si.MBID)) si.bMBIDTag = true; } if (ti.Conductor != null) { si.Conductor = ti.Conductor.Trim(); if (!string.IsNullOrEmpty(si.Conductor)) si.bConductorTag = true; } if (ti.Publisher != null) { si.Publisher = ti.Publisher.Trim(); if (!string.IsNullOrEmpty(si.Publisher)) si.bPublisherTag = true; } if (ti.Year != null) { si.Year = ti.Year.Trim(); if (!string.IsNullOrEmpty(si.Year)) si.bYearTag = true; } si.Track = ti.Track.ToString(); if (!string.IsNullOrEmpty(si.Track)) si.bTrackTag = true; // Extra info... si.FileSize = (long)ti.FileSize; if (si.FileSize >= 0) si.bFilesizeTag = true; si.BitRate = (int)ti.BitRate; if (si.BitRate >= 0) si.bBitrateTag = true; si.bProtected = ti.IsProtected; } catch { si.ClearAll(); si.bException = true; // Threw an exception } } else using (TagLib.File tagFile = TagLib.File.Create(file)) // Use taglib-sharp... { // Note - checking Length on a null string throws an exception! // Snippet to read rating sio... (not sure if for mp3 or wma!) but cool :) // //TagLib.Tag tag123 = tagsio.GetTag(TagTypes.Id3v2); //var usr = "******"; //TagLib.Id3v2.PopularimeterFrame frame = TagLib.Id3v2.PopularimeterFrame.Get( // (TagLib.Id3v2.Tag)tag123, usr, true); //ulong PlayCount = frame.PlayCount; //int Rating = frame.Rating; // To WRITE: //Id3v2.Tag tag = (Id3v2.Tag)file.GetTag(TagTypes.Id3v2, true); // set create flag //tag.SetTextFrame(FrameType.TRCK, "03"); try { //TagLib.dll Usage: // //TagLib.File tagFile = TagLib.File.Create(mp3file); //uint year = tagFile.Tag.Year; // //You set the tags like this: //tagFile.Tag.Year = year; // //And then save the changes: //tagFile.Save(); si.FileType = SongInfo.FT_MP3; // mp3 tag info if (tagFile == null) { si.bException = true; // Error return si; } si.Duration = tagFile.Properties.Duration; if (si.Duration.TotalSeconds > 0) si.bDurationTag = true; if (tagFile.Properties.Description != null) { si.Description = tagFile.Properties.Description.Trim(); if (!string.IsNullOrEmpty(si.Description)) si.bDescriptionTag = true; } si.BitRate = tagFile.Properties.AudioBitrate; si.bBitrateTag = true; si.FileSize = tagFile.Length; si.bFilesizeTag = true; // add flags??? si.Channels = tagFile.Properties.AudioChannels; si.BitsPerSample = tagFile.Properties.BitsPerSample; si.SampleRate = tagFile.Properties.AudioSampleRate; // Try to read the v2 tag-frame... TagLib.Id3v2.Tag tagv2 = (TagLib.Id3v2.Tag)tagFile.GetTag(TagLib.TagTypes.Id3v2); if (tagv2 != null) { if (tagv2.Title != null) { si.Title = tagv2.Title.Trim(); if (!string.IsNullOrEmpty(si.Title)) si.bTitleTag = true; } if (tagv2.FirstAlbumArtist != null) { si.Artist = tagv2.FirstAlbumArtist.Trim(); if (!string.IsNullOrEmpty(si.Artist)) si.bArtistTag = true; } if (tagv2.FirstPerformer != null) { si.Performer = tagv2.FirstPerformer.Trim(); if (!string.IsNullOrEmpty(si.Performer)) si.bPerformerTag = true; } // Same as Author in a wma file if (tagv2.FirstComposer != null) { si.Composer = tagv2.FirstComposer.Trim(); if (!string.IsNullOrEmpty(si.Composer)) si.bComposerTag = true; } if (tagv2.Album != null) { si.Album = tagv2.Album.Trim(); if (!string.IsNullOrEmpty(si.Album)) si.bAlbumTag = true; } if (tagv2.FirstGenre != null) { si.Genre = tagv2.FirstGenre.Trim(); if (!string.IsNullOrEmpty(si.Genre)) si.bGenreTag = true; } if (tagv2.Comment != null) { si.Comments = tagv2.Comment.Trim(); if (!string.IsNullOrEmpty(si.Comments)) si.bCommentsTag = true; } if (tagv2.Lyrics != null) { si.Lyrics = tagv2.Lyrics.Trim(); if (!string.IsNullOrEmpty(si.Lyrics)) si.bLyricsTag = true; } if (tagv2.MusicIpId != null) { si.AcoustID = tagv2.MusicIpId.Trim(); if (!string.IsNullOrEmpty(si.AcoustID)) si.bAcoustIDTag = true; } if (tagv2.MusicBrainzTrackId != null) { si.MBID = tagv2.MusicBrainzTrackId.Trim(); if (!string.IsNullOrEmpty(si.MBID)) si.bMBIDTag = true; } if (tagv2.Conductor != null) { si.Conductor = tagv2.Conductor.Trim(); if (!string.IsNullOrEmpty(si.Conductor)) si.bConductorTag = true; } if (tagv2.Publisher != null) { si.Publisher = tagv2.Publisher.Trim(); if (!string.IsNullOrEmpty(si.Publisher)) si.bPublisherTag = true; } if (tagv2.Year > 0) { si.Year = tagv2.Year.ToString(); if (!string.IsNullOrEmpty(si.Year)) si.bYearTag = true; } if (tagv2.Track > 0) { si.Track = tagv2.Track.ToString(); if (!string.IsNullOrEmpty(si.Track)) si.bTrackTag = true; } if (tagv2.Copyright != null) { si.Copyright = tagv2.Copyright.Trim(); if (!string.IsNullOrEmpty(si.Copyright)) si.bCopyrightTag = true; } // Extra info si.TrackCount = (int)tagv2.TrackCount; si.Disc = (int)tagv2.Disc; si.DiscCount = (int)tagv2.DiscCount; } else // Try to read the old v1 tag { // Try to read the v1 tag-frame... TagLib.Id3v1.Tag tagv1 = (TagLib.Id3v1.Tag)tagFile.GetTag(TagLib.TagTypes.Id3v1); if (tagv1 == null) { si.ClearAll(); si.bException = true; // Error return si; } if (tagv1.Title != null) { si.Title = tagv1.Title.Trim(); if (!string.IsNullOrEmpty(si.Title)) si.bTitleTag = true; } if (tagv1.FirstAlbumArtist != null) { si.Artist = tagv1.FirstAlbumArtist.Trim(); if (!string.IsNullOrEmpty(si.Artist)) si.bArtistTag = true; } if (tagv1.FirstPerformer != null) { si.Performer = tagv1.FirstPerformer.Trim(); if (!string.IsNullOrEmpty(si.Performer)) si.bPerformerTag = true; } // Same as Author in a wma file if (tagv1.FirstComposer != null) { si.Composer = tagv1.FirstComposer.Trim(); if (!string.IsNullOrEmpty(si.Composer)) si.bComposerTag = true; } if (tagv1.Album != null) { si.Album = tagv1.Album.Trim(); if (!string.IsNullOrEmpty(si.Album)) si.bAlbumTag = true; } if (tagv1.FirstGenre != null) { si.Genre = tagv1.FirstGenre.Trim(); if (!string.IsNullOrEmpty(si.Genre)) si.bGenreTag = true; } if (tagv1.Comment != null) { si.Comments = tagv1.Comment.Trim(); if (!string.IsNullOrEmpty(si.Comments)) si.bCommentsTag = true; } if (tagv1.Lyrics != null) { si.Lyrics = tagv1.Lyrics.Trim(); if (!string.IsNullOrEmpty(si.Lyrics)) si.bLyricsTag = true; } if (tagv1.MusicIpId != null) { si.AcoustID = tagv1.MusicIpId.Trim(); if (!string.IsNullOrEmpty(si.AcoustID)) si.bAcoustIDTag = true; } if (tagv1.MusicBrainzTrackId != null) { si.MBID = tagv1.MusicBrainzTrackId.Trim(); if (!string.IsNullOrEmpty(si.MBID)) si.bMBIDTag = true; } if (tagv1.Conductor != null) { si.Conductor = tagv1.Conductor.Trim(); if (!string.IsNullOrEmpty(si.Conductor)) si.bConductorTag = true; } if (tagv1.Year > 0) { si.Year = tagv1.Year.ToString(); if (!string.IsNullOrEmpty(si.Year)) si.bYearTag = true; } if (tagv1.Track > 0) { si.Track = tagv1.Track.ToString(); if (!string.IsNullOrEmpty(si.Track)) si.bTrackTag = true; } if (tagv1.Copyright != null) { si.Copyright = tagv1.Copyright.Trim(); if (!string.IsNullOrEmpty(si.Copyright)) si.bCopyrightTag = true; } // Extra info si.TrackCount = (int)tagv1.TrackCount; si.Disc = (int)tagv1.Disc; si.DiscCount = (int)tagv1.DiscCount; } } catch { si.ClearAll(); si.bException = true; // Threw an exception } } // Trim it up si.TrimAll(); return si; }