private static void WriteArtworkFile(string directory, AlbumArtworkSaveFormat saveFormat, Track track, ImageCacheEntry albumArtwork) { string fileName = null; switch (saveFormat) { case AlbumArtworkSaveFormat.DontSave: break; case AlbumArtworkSaveFormat.AsCover: fileName = albumArtwork?.Picture.FileType.Append("cover"); break; case AlbumArtworkSaveFormat.AsArtistAlbum: fileName = albumArtwork?.Picture.FileType.Append($"{track.Artist} - {track.Album.Title}"); if (fileName != null) { fileName = PathHelpers.CleanFilename(fileName); } break; default: throw new ArgumentOutOfRangeException(); } if (fileName == null) { return; } SysFile.WriteAllBytes(Path.Combine(directory, fileName), albumArtwork.Data); }
public async Task StartDownloadAsync(SavePlaylistSetting playlistSetting, bool ignoreSaveArtworkWithPlaylist, AlbumArtworkSaveFormat albumArtworkSaveFormat) { var queueView = new Queue <EnqueuedCollection>(this); while (queueView.Count > 0) { var currentItem = queueView.Dequeue(); OnCollectionDequeued(new CollectionDownloadEventArgs { Collection = currentItem, CurrentCollectionIndex = (Count - queueView.Count) - 1, TotalNumberOfCollections = Count }); if (!(currentItem.MediaCollection is Playlist)) { playlistSetting = SavePlaylistSetting.DontSave; } if (await DownloadCollectionAsync(currentItem, playlistSetting, ignoreSaveArtworkWithPlaylist, albumArtworkSaveFormat)) { continue; } if (skip == ExceptionSkip.Fail) { return; } } }
public static void Write(EnqueuedTrack completedTrack, AlbumArtworkSaveFormat saveFormat, string path) { // Get album artwork from cache PictureCacheEntry albumArtwork = null; if (PictureCache.HasPicture(completedTrack.Smid.ToString())) { albumArtwork = PictureCache.GetPicture(completedTrack.Smid.ToString()); } // Write track tags var track = completedTrack.OriginalTrack; using (var file = File.Create(new File.LocalFileAbstraction(path), completedTrack.TrackFile.FileType.MimeType, ReadStyle.Average)) { file.Tag.Title = track.Title; file.Tag.Performers = new[] { track.Artist.Name }; if (track.Album.Artist != null) { file.Tag.AlbumArtists = new[] { track.Album.Artist.Name }; } file.Tag.Genres = new[] { track.Genre }; file.Tag.Album = track.Album.Title; file.Tag.Track = (uint)track.TrackNumber; file.Tag.TrackCount = (uint)(track.Album.GetNumberOfTracksOnDisc(track.DiscNumber) ?? 0); file.Tag.Disc = (uint)track.DiscNumber; file.Tag.DiscCount = (uint)(track.Album.GetTotalDiscs() ?? 0); file.Tag.Year = (uint)track.Year; file.Tag.Copyright = CopyrightText; file.Tag.Comment = CopyrightText; if (albumArtwork != null) { file.Tag.Pictures = new IPicture[] { new TagLib.Picture(new ByteVector(albumArtwork.FullSize)) }; } file.Save(); } // Write album artwork to file if requested string parentDirectory; if (saveFormat != AlbumArtworkSaveFormat.DontSave && (parentDirectory = Path.GetDirectoryName(path)) != null) { WriteArtworkFile(parentDirectory, saveFormat, track, albumArtwork); } }
public static void Write(string serviceName, Track completedTrack, TrackFile trackFile, AlbumArtworkSaveFormat saveFormat, string path) { // Get album artwork from cache ImageCacheEntry albumArtwork = null; var smid = completedTrack.Album.GetSmid(serviceName).ToString(); if (ImageCache.Instance.HasItem(smid)) { albumArtwork = ImageCache.Instance.Get(smid); } // Write track tags var track = completedTrack; using (var file = File.Create(new File.LocalFileAbstraction(path), trackFile.FileType.MimeType, ReadStyle.Average)) { file.Tag.Title = track.Title; file.Tag.Performers = new[] { track.Artist.Name }; if (track.Album.Artist != null) { file.Tag.AlbumArtists = new[] { track.Album.Artist.Name }; } if (track.Genre != null) { file.Tag.Genres = new[] { track.Genre }; } file.Tag.Album = track.Album.Title; file.Tag.Track = (uint)track.TrackNumber; file.Tag.TrackCount = (uint)(track.Album.GetNumberOfTracksOnDisc(track.DiscNumber) ?? 0); file.Tag.Disc = (uint)track.DiscNumber; file.Tag.DiscCount = (uint)(track.Album.GetTotalDiscs() ?? 0); file.Tag.Year = (uint)track.Year; file.Tag.Copyright = CopyrightText; file.Tag.Comment = CopyrightText; if (albumArtwork != null) { file.Tag.Pictures = new IPicture[] { new TagLib.Picture(new ByteVector(albumArtwork.Data)) }; } file.Save(); } // Write album artwork to file if requested if (albumArtwork == null) { return; } string parentDirectory; if (saveFormat != AlbumArtworkSaveFormat.DontSave && (parentDirectory = Path.GetDirectoryName(path)) != null) { WriteArtworkFile(parentDirectory, saveFormat, track, albumArtwork); } }
private async Task <bool> DownloadCollectionAsync(EnqueuedCollection collection, SavePlaylistSetting savePlaylistSetting, bool ignoreSaveArtworkWithPlaylist, AlbumArtworkSaveFormat albumArtworkSaveFormat) { var tracksCollectionLength = collection.MediaCollection.Tracks.Count; var tracksQueue = new Queue <Track>(collection.MediaCollection.Tracks); var trackFiles = new List <TrackFile>(collection.MediaCollection.Tracks.Count); TrackDownloadEventArgs gEventArgs = null; while (tracksQueue.Count > 0) { var eventArgs = gEventArgs = new TrackDownloadEventArgs { CurrentItemIndex = (tracksCollectionLength - tracksQueue.Count), PercentCompleted = 0M, State = DownloadState.PreProcess, TotalItems = tracksCollectionLength, TrackFile = null }; var currentItem = tracksQueue.Dequeue(); OnTrackDequeued(eventArgs); try { if (!currentItem.IsDownloadable) { continue; } OnTrackDownloadProgress(eventArgs); if (currentItem.Album?.CoverPicture != null) { // Download album artwork if it's not cached var albumSmid = currentItem.Album.GetSmid(collection.Service.Info.Name).ToString(); if (!ImageCache.Instance.HasItem(albumSmid)) { eventArgs.State = DownloadState.DownloadingAlbumArtwork; OnTrackDownloadProgress(eventArgs); try { await ImageCache.Instance.AddByDownload(albumSmid, currentItem.Album.CoverPicture); } catch (Exception ex) { ImageCache.Instance.AddNull(albumSmid); Log.WriteException(Level.Warning, Tag, ex, "Exception occurred when download album artwork:"); } } } // Get the TrackFile eventArgs.TrackFile = await collection.Service.GetDownloadableTrackAsync(currentItem); var downloader = collection.Service.GetDownloader(eventArgs.TrackFile); downloader.Progress += (sender, args) => { eventArgs.Update(args); OnTrackDownloadProgress(eventArgs); }; downloader.Done += (sender, args) => { eventArgs.State = DownloadState.PostProcess; OnTrackDownloadProgress(eventArgs); }; // Generate the path var path = collection.GetPath(eventArgs.TrackFile); var tempPath = path; if (useTempFile) { tempPath += "-temp"; } EnsureParentDirectories(tempPath); eventArgs.State = DownloadState.Downloading; // Begin download await downloader.DownloadAsyncTask(eventArgs.TrackFile, tempPath); trackFiles.Add(eventArgs.TrackFile); // Attempt to dispose the downloader, since the most probable case will be that it will // implement IDisposable if it uses sockets var disposableDownloader = downloader as IDisposable; disposableDownloader?.Dispose(); // Write the tag eventArgs.State = DownloadState.WritingTags; OnTrackDownloadProgress(eventArgs); var setting = albumArtworkSaveFormat; if (ignoreSaveArtworkWithPlaylist && collection.Type == MediaType.Playlist) { setting = AlbumArtworkSaveFormat.DontSave; } TrackTagger.Write(collection.Service.Info.Name, currentItem, eventArgs.TrackFile, setting, tempPath); // Rename to proper path if (useTempFile) { if (File.Exists(path)) { File.Delete(path); } File.Move(tempPath, path); } } catch (Exception ex) { var exEventArgs = new ExceptionEventArgs { CurrentState = eventArgs, Exception = ex }; OnException(exEventArgs); switch (exEventArgs.SkipTo) { case ExceptionSkip.Item: continue; case ExceptionSkip.Collection: case ExceptionSkip.Fail: skip = exEventArgs.SkipTo; return(false); default: throw new ArgumentOutOfRangeException(); } } // Raise the completed event even if an error occurred OnTrackDownloadCompleted(eventArgs); } // Write playlist if possible try { var writer = new PlaylistWriter(collection, trackFiles); switch (savePlaylistSetting) { case SavePlaylistSetting.DontSave: break; case SavePlaylistSetting.M3U: writer.WriteM3U8(); break; case SavePlaylistSetting.PLS: writer.WritePLS(); break; default: throw new ArgumentOutOfRangeException(nameof(savePlaylistSetting), savePlaylistSetting, null); } } catch (Exception ex) { var exEventArgs = new ExceptionEventArgs { CurrentState = gEventArgs, Exception = ex }; OnException(exEventArgs); switch (exEventArgs.SkipTo) { case ExceptionSkip.Item: break; case ExceptionSkip.Collection: case ExceptionSkip.Fail: skip = exEventArgs.SkipTo; return(false); default: throw new ArgumentOutOfRangeException(); } } return(true); }