public static bool SaveToFile(TrackInfo track, bool write_metadata, bool write_rating, bool write_play_count) { // Note: this should be kept in sync with the metadata read in StreamTagger.cs TagLib.File file = ProcessUri(track.Uri); if (file == null) { return(false); } if (write_metadata) { file.Tag.Performers = new string [] { track.ArtistName }; file.Tag.PerformersSort = new string [] { track.ArtistNameSort }; file.Tag.Album = track.AlbumTitle; file.Tag.AlbumSort = track.AlbumTitleSort; file.Tag.MusicBrainzReleaseId = track.AlbumMusicBrainzId; file.Tag.AlbumArtists = track.AlbumArtist == null ? new string [0] : new string [] { track.AlbumArtist }; file.Tag.AlbumArtistsSort = (track.AlbumArtistSort == null ? new string [0] : new string [] { track.AlbumArtistSort }); file.Tag.MusicBrainzArtistId = track.ArtistMusicBrainzId; // Bug in taglib-sharp-2.0.3.0: Crash if you send it a genre of "{ null }" // on a song with both ID3v1 and ID3v2 metadata. It's happy with "{}", though. // (see http://forum.taglib-sharp.com/viewtopic.php?f=5&t=239 ) file.Tag.Genres = (track.Genre == null) ? new string[] {} : new string [] { track.Genre }; file.Tag.Title = track.TrackTitle; file.Tag.TitleSort = track.TrackTitleSort; file.Tag.MusicBrainzTrackId = track.MusicBrainzId; file.Tag.Track = (uint)track.TrackNumber; file.Tag.TrackCount = (uint)track.TrackCount; file.Tag.Composers = new string [] { track.Composer }; file.Tag.Conductor = track.Conductor; file.Tag.Grouping = track.Grouping; file.Tag.Copyright = track.Copyright; file.Tag.Comment = track.Comment; file.Tag.Disc = (uint)track.DiscNumber; file.Tag.DiscCount = (uint)track.DiscCount; file.Tag.Year = (uint)track.Year; file.Tag.BeatsPerMinute = (uint)track.Bpm; SaveIsCompilation(file, track.IsCompilation); } if (write_rating) { // FIXME move StreamRatingTagger to taglib# StreamRatingTagger.StoreRating(track.Rating, file); } if (write_play_count) { StreamRatingTagger.StorePlayCount(track.PlayCount, file); } file.Save(); file.Dispose(); track.FileSize = Banshee.IO.File.GetSize(track.Uri); track.FileModifiedStamp = Banshee.IO.File.GetModifiedTime(track.Uri); track.LastSyncedStamp = DateTime.Now; return(true); }
public static void TrackInfoMerge(TrackInfo track, TagLib.File file, bool preferTrackInfo, bool import_rating_and_play_count) { // TODO support these as arrays: // Performers[] (track artists), AlbumArtists[], Composers[], Genres[] // Note: this should be kept in sync with the metadata written in SaveTrackMetadataJob.cs if (file != null) { track.Uri = new SafeUri(file.Name); track.MimeType = file.MimeType; track.Duration = file.Properties.Duration; track.BitRate = file.Properties.AudioBitrate; track.SampleRate = file.Properties.AudioSampleRate; track.BitsPerSample = file.Properties.BitsPerSample; FindTrackMediaAttributes(track, file); track.ArtistName = Choose(file.Tag.JoinedPerformers, track.ArtistName, preferTrackInfo); track.ArtistNameSort = Choose(file.Tag.JoinedPerformersSort, track.ArtistNameSort, preferTrackInfo); track.ArtistMusicBrainzId = Choose(file.Tag.MusicBrainzArtistId, track.ArtistMusicBrainzId, preferTrackInfo); track.AlbumTitle = Choose(file.Tag.Album, track.AlbumTitle, preferTrackInfo); track.AlbumTitleSort = Choose(file.Tag.AlbumSort, track.AlbumTitleSort, preferTrackInfo); track.AlbumMusicBrainzId = Choose(file.Tag.MusicBrainzReleaseId, track.AlbumMusicBrainzId, preferTrackInfo); // AlbumArtist cannot be set until the track is marked as a compilation. track.IsCompilation = preferTrackInfo ? track.IsCompilation : IsCompilation(file); track.AlbumArtist = Choose(file.Tag.FirstAlbumArtist, track.AlbumArtist, preferTrackInfo); track.AlbumArtistSort = Choose(file.Tag.FirstAlbumArtistSort, track.AlbumArtistSort, preferTrackInfo); track.TrackTitle = Choose(file.Tag.Title, track.TrackTitle, preferTrackInfo); track.TrackTitleSort = Choose(file.Tag.TitleSort, track.TrackTitleSort, preferTrackInfo); track.MusicBrainzId = Choose(file.Tag.MusicBrainzTrackId, track.MusicBrainzId, preferTrackInfo); track.Genre = Choose(file.Tag.FirstGenre, track.Genre, preferTrackInfo); track.Composer = Choose(file.Tag.FirstComposer, track.Composer, preferTrackInfo); track.Conductor = Choose(file.Tag.Conductor, track.Conductor, preferTrackInfo); track.Grouping = Choose(file.Tag.Grouping, track.Grouping, preferTrackInfo); track.Copyright = Choose(file.Tag.Copyright, track.Copyright, preferTrackInfo); track.Comment = Choose(file.Tag.Comment, track.Comment, preferTrackInfo); track.TrackNumber = Choose((int)file.Tag.Track, track.TrackNumber, preferTrackInfo); track.TrackCount = Choose((int)file.Tag.TrackCount, track.TrackCount, preferTrackInfo); track.DiscNumber = Choose((int)file.Tag.Disc, track.DiscNumber, preferTrackInfo); track.DiscCount = Choose((int)file.Tag.DiscCount, track.DiscCount, preferTrackInfo); track.Year = Choose((int)file.Tag.Year, track.Year, preferTrackInfo); track.Bpm = Choose((int)file.Tag.BeatsPerMinute, track.Bpm, preferTrackInfo); if (import_rating_and_play_count) { int file_rating = 0, file_playcount = 0; StreamRatingTagger.GetRatingAndPlayCount(file, ref file_rating, ref file_playcount); track.Rating = Choose(file_rating, track.Rating, preferTrackInfo); track.PlayCount = Choose(file_playcount, track.PlayCount, preferTrackInfo); } } else { track.MediaAttributes = TrackMediaAttributes.AudioStream; if (track.Uri != null && VideoExtensions.IsMatchingFile(track.Uri.AbsoluteUri)) { track.MediaAttributes |= TrackMediaAttributes.VideoStream; } } track.FileSize = Banshee.IO.File.GetSize(track.Uri); track.FileModifiedStamp = Banshee.IO.File.GetModifiedTime(track.Uri); track.LastSyncedStamp = DateTime.Now; if (String.IsNullOrEmpty(track.TrackTitle)) { try { string filename = System.Web.HttpUtility.UrlDecode (System.IO.Path.GetFileNameWithoutExtension(track.Uri.AbsoluteUri)); if (!String.IsNullOrEmpty(filename)) { track.TrackTitle = filename; } } catch {} } // TODO look for track number in the file name if not set? // TODO could also pull artist/album from folders _iff_ files two levels deep in the MusicLibrary folder // TODO these ideas could also be done in an extension that collects such hacks }