/// <summary> /// An item failed to open /// </summary> /// <param name="item">The item that failed to open</param> public void ItemFailedToOpen(MediaPlaybackItem item) { App.playbackService.RemoveFromQueue(GetMediaItemId(item), localLock); playlistMediaIds.RemoveAt(playlistMediaIds.IndexOf(GetMediaItemId(item))); long loadingKey = DateTime.Now.Ticks; MainPage.AddLoadingLock(loadingKey); UpdateFailuresCount(1, loadingKey); MainPage.RemoveLoadingLock(loadingKey); }
/// <summary> /// The main constructor /// </summary> /// <param name="currentLock">The global lock when the session was created, session dies when lock changes</param> /// <param name="source">The service to retrieve the song from</param> /// <param name="type">What kind of Spotify resource</param> /// <param name="shuffle">Whether or not shuffling is enabled for session playback</param> /// <param name="tracksHref">The reference to the download location for tracks</param> /// <param name="totalTracks">The total number of tracks in the playback session</param> public PlaybackSession(long currentLock, PlaybackSource source, PlaybackType type, bool shuffle, string tracksHref, int totalTracks) { localLock = currentLock; this.source = source; this.type = type; this.shuffling = shuffle; this.tracksHref = tracksHref; this.totalTracks = totalTracks; prevRemoteAttempts.Add(0); if (App.mainPage != null) { long loadingKey = DateTime.Now.Ticks; MainPage.AddLoadingLock(loadingKey); App.mainPage.SetLoadersMessage("", localLock, loadingKey); MainPage.RemoveLoadingLock(loadingKey); } }
/// <summary> /// Load the range of tracks from the remote playlist in reverse order /// </summary> /// <param name="start">The start position on remote to download to local, the last position added to the queue</param> /// <param name="end">The end position on remote to download to local, the first position added to the queue</param> /// <param name="lockOverride">Whether or not to ignore if the lock is set (Used when recursing into itself)</param> /// <returns>True a total of end - start tracks are downloaded, false otherwise</returns> public async Task <bool> LoadTracksReverse(int start, int end, bool lockOverride) { long loadingKey = DateTime.Now.Ticks; MainPage.AddLoadingLock(loadingKey); if (loadLock && !lockOverride) { return(false); } loadLock = true; int successes = 0; if (start < 0) { start = 0; } nextRemoteAttempts.Add(end); prevRemoteAttempts.Insert(0, start); int limit = end - start + 1; App.mainPage.SetLoadingProgress(source, 0, limit, localLock, loadingKey); if (localLock != App.playbackService.GlobalLock) { return(false); } List <Track> tracks = await GetTracksInRange(start, limit); if (tracks.Count != limit) { UpdateFailuresCount(limit - tracks.Count, loadingKey); } else { List <KeyValuePair <MediaSource, Track> > sources = new List <KeyValuePair <MediaSource, Track> >(); if (this.source == PlaybackSource.Spotify) { for (int i = 0; i < tracks.Count; i++) { Track track = tracks[i]; if (localLock == App.playbackService.GlobalLock) { if (track.previewUrl != "") { sources.Add(new KeyValuePair <MediaSource, Track>(MediaSource.CreateFromUri(new Uri(track.previewUrl)), track)); } else { UpdateFailuresCount(1, loadingKey); } } App.mainPage.SetLoadingProgress(source, i + 1 + limit - tracks.Count, limit, localLock, loadingKey); } } else if (this.source == PlaybackSource.YouTube && localLock == App.playbackService.GlobalLock) { for (int i = 0; i < tracks.Count; i++) { Track track = tracks[i]; string videoId = ""; if (localLock == App.playbackService.GlobalLock) { videoId = await SearchForVideoId(track); } if (localLock == App.playbackService.GlobalLock) { if (videoId == "") { UpdateFailuresCount(1, loadingKey); } else { try { sources.Add(new KeyValuePair <MediaSource, Track>(await GetAudioAsync(videoId, track.name), track)); } catch (Exception) { UpdateFailuresCount(1, loadingKey); } } } App.mainPage.SetLoadingProgress(PlaybackSource.YouTube, i + 1 + limit - tracks.Count, limit, localLock, loadingKey); } } for (int i = sources.Count - 1; i >= 0; i--) { KeyValuePair <MediaSource, Track> pair = sources[i]; if (localLock == App.playbackService.GlobalLock) { MediaPlaybackItem playbackItem = new MediaPlaybackItem(pair.Key); MediaItemDisplayProperties displayProperties = playbackItem.GetDisplayProperties(); displayProperties.Type = MediaPlaybackType.Music; displayProperties.MusicProperties.Title = pair.Value.name; displayProperties.MusicProperties.AlbumTitle = pair.Value.album.name; displayProperties.MusicProperties.Artist = pair.Value.GetMainArtistName(); if (pair.Value.album.imageUrl != "") { displayProperties.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri(pair.Value.album.imageUrl)); } playbackItem.ApplyDisplayProperties(displayProperties); pair.Key.CustomProperties["mediaItemId"] = pair.Value.id; string id = GetMediaItemId(playbackItem); if (!playlistMediaIds.Contains(id)) { App.playbackService.AddToBeginningOfQueue(playbackItem, localLock); playlistMediaIds.Insert(0, id); successes++; } } } } MainPage.RemoveLoadingLock(loadingKey); if (successes != limit && start > 0) { return(await LoadTracks(start - limit - (limit - tracks.Count), start + limit, true)); } loadLock = false; return(tracks.Count == limit); }
/// <summary> /// Load the range of tracks from the remote playlist /// </summary> /// <param name="start">The first track to load from remote</param> /// <param name="end">The last track to load from remote</param> /// <param name="lockOverride">Whether or not to ignore if the lock is set (Used when recursing into itself)</param> /// <returns>True a total of end - start tracks are downloaded, false otherwise</returns> public async Task <bool> LoadTracks(int start, int end, bool lockOverride) { long loadingKey = DateTime.Now.Ticks; MainPage.AddLoadingLock(loadingKey); if (loadLock && !lockOverride) { return(false); } loadLock = true; int successes = 0; int limit; if (shuffling) { if (shufflePositionsAvailable.Count == 0) { ReFillShufflePositionsAvailable(); } if (shufflePositionsAvailable.Count < end - start) { limit = shufflePositionsAvailable.Count; } else { limit = end - start; } } else { if (totalTracks > 0 && end >= totalTracks) { end = totalTracks - 1; } nextRemoteAttempts.Insert(0, end); if (start == 0) { prevRemoteAttempts.Add(start + TRACKS_PER_REQUEST); } else { prevRemoteAttempts.Add(start); } limit = end - start + 1; } App.mainPage.SetLoadingProgress(source, 0, limit, localLock, loadingKey); if (localLock != App.playbackService.GlobalLock) { return(false); } List <Track> tracks = new List <Track>(); if (shuffling) { tracks = await GetTracksRandom(limit); } else { tracks = await GetTracksInRange(start, limit); } if (tracks.Count == totalTracks) { limit = totalTracks; App.mainPage.SetLoadingProgress(source, 0, limit, localLock, loadingKey); } if (tracks.Count != limit) { UpdateFailuresCount(limit - tracks.Count, loadingKey); } List <KeyValuePair <MediaSource, Track> > sources = new List <KeyValuePair <MediaSource, Track> >(); if (source == PlaybackSource.Spotify) { for (int i = 0; i < tracks.Count; i++) { Track track = tracks[i]; if (localLock == App.playbackService.GlobalLock) { if (track.previewUrl != "") { sources.Add(new KeyValuePair <MediaSource, Track>(MediaSource.CreateFromUri(new Uri(track.previewUrl)), track)); } else { UpdateFailuresCount(1, loadingKey); } } App.mainPage.SetLoadingProgress(source, i + 1 + limit - tracks.Count, limit, localLock, loadingKey); } } else if (source == PlaybackSource.YouTube && localLock == App.playbackService.GlobalLock) { for (int i = 0; i < tracks.Count; i++) { Track track = tracks[i]; string videoId = ""; if (localLock == App.playbackService.GlobalLock) { videoId = await SearchForVideoId(track); } if (localLock == App.playbackService.GlobalLock) { if (videoId == "") { UpdateFailuresCount(1, loadingKey); } else { try { sources.Add(new KeyValuePair <MediaSource, Track>(await GetAudioAsync(videoId, track.name), track)); } catch (Exception) { UpdateFailuresCount(1, loadingKey); } } } App.mainPage.SetLoadingProgress(PlaybackSource.YouTube, i + 1 + limit - tracks.Count, limit, localLock, loadingKey); } } bool firstPlay = false; for (int i = 0; i < sources.Count; i++) { KeyValuePair <MediaSource, Track> pair = sources[i]; if (localLock == App.playbackService.GlobalLock) { MediaPlaybackItem playbackItem = new MediaPlaybackItem(pair.Key); MediaItemDisplayProperties displayProperties = playbackItem.GetDisplayProperties(); displayProperties.Type = MediaPlaybackType.Music; displayProperties.MusicProperties.Title = pair.Value.name; displayProperties.MusicProperties.AlbumTitle = pair.Value.album.name; displayProperties.MusicProperties.Artist = pair.Value.GetMainArtistName(); if (pair.Value.album.imageUrl != "") { displayProperties.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri(pair.Value.album.imageUrl)); } playbackItem.ApplyDisplayProperties(displayProperties); pair.Key.CustomProperties["mediaItemId"] = pair.Value.id; string id = GetMediaItemId(playbackItem); if (!playlistMediaIds.Contains(id)) { App.playbackService.AddToQueue(playbackItem, localLock); playlistMediaIds.Add(id); successes++; } if (currentlyPlaying == "") { firstPlay = true; currentlyPlaying = GetMediaItemId(playbackItem); } } } if (firstPlay) { App.playbackService.PlayFromBeginning(localLock); } MainPage.RemoveLoadingLock(loadingKey); if (shuffling) { if (successes != limit && shufflePositionsAvailable.Count > 0) { return(await LoadTracks(0, limit - successes, true)); } } else { if (successes != limit && end < totalTracks - 1) { return(await LoadTracks(start + limit, start + limit + (limit - tracks.Count), true)); } } loadLock = false; return(tracks.Count == limit); }