diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 453327c5..06bf37fc 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -621,24 +621,26 @@ impl SpircTask { self.play_status = SpircPlayStatus::Stopped; } }, - PlayerEvent::TimeToPreloadNextTrack { .. } => match self.play_status { - SpircPlayStatus::Paused { - ref mut preloading_of_next_track_triggered, - .. - } - | SpircPlayStatus::Playing { - ref mut preloading_of_next_track_triggered, - .. - } => { - *preloading_of_next_track_triggered = true; - if let Some(track_id) = self.preview_next_track() { - self.player.preload(track_id); + PlayerEvent::TimeToPreloadNextTrack { preload_index, .. } => { + match self.play_status { + SpircPlayStatus::Paused { + ref mut preloading_of_next_track_triggered, + .. } + | SpircPlayStatus::Playing { + ref mut preloading_of_next_track_triggered, + .. + } => { + *preloading_of_next_track_triggered = true; + if let Some(track_id) = self.preview_next_track(preload_index) { + self.player.preload(track_id); + } + } + SpircPlayStatus::LoadingPause { .. } + | SpircPlayStatus::LoadingPlay { .. } + | SpircPlayStatus::Stopped => (), } - SpircPlayStatus::LoadingPause { .. } - | SpircPlayStatus::LoadingPlay { .. } - | SpircPlayStatus::Stopped => (), - }, + } _ => (), } } @@ -777,7 +779,8 @@ impl SpircTask { } = self.play_status { if preloading_of_next_track_triggered { - if let Some(track_id) = self.preview_next_track() { + // Get the next track_id in the playlist + if let Some(track_id) = self.preview_next_track(1) { self.player.preload(track_id); } } @@ -899,9 +902,12 @@ impl SpircTask { } } - fn preview_next_track(&mut self) -> Option { - self.get_track_id_to_play_from_playlist(self.state.get_playing_track_index() + 1) - .and_then(|(track_id, _)| Some(track_id)) + fn preview_next_track(&mut self, preview_index: u32) -> Option { + trace!("Previewing {:}", preview_index); + self.get_track_id_to_play_from_playlist( + self.state.get_playing_track_index() + preview_index, + ) + .and_then(|(track_id, _)| Some(track_id)) } fn handle_next(&mut self) { diff --git a/playback/src/player.rs b/playback/src/player.rs index 0a6fd41f..4ea50419 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -99,6 +99,7 @@ pub enum PlayerEvent { TimeToPreloadNextTrack { play_request_id: u64, track_id: SpotifyId, + preload_index: u32, }, EndOfTrack { play_request_id: u64, @@ -320,6 +321,10 @@ enum PlayerPreload { Loading { track_id: SpotifyId, loader: Box>, + preload_index: u32, + }, + Missing { + preload_index: u32, }, Ready { track_id: SpotifyId, @@ -753,6 +758,7 @@ impl Future for PlayerInternal { if let PlayerPreload::Loading { ref mut loader, track_id, + preload_index, } = self.preload { match loader.poll() { @@ -764,8 +770,26 @@ impl Future for PlayerInternal { } Ok(Async::NotReady) => (), Err(_) => { - warn!("Unable to preload {:?}", track_id); - self.preload = PlayerPreload::None; + warn!("Unable to preload {:?}[{}]", track_id, preload_index,); + // Preemptively fetch next track? + self.preload = PlayerPreload::Missing { preload_index }; + if let PlayerState::Playing { + play_request_id, .. + } + | PlayerState::Paused { + play_request_id, .. + } = self.state + { + debug!( + "Requesting track_id for preload_index: {}", + preload_index + 1 + ); + self.send_event(PlayerEvent::TimeToPreloadNextTrack { + track_id, + play_request_id, + preload_index: preload_index + 1, + }); + } } } } @@ -853,6 +877,7 @@ impl Future for PlayerInternal { self.send_event(PlayerEvent::TimeToPreloadNextTrack { track_id, play_request_id, + preload_index: 1, }); } } @@ -1294,7 +1319,12 @@ impl PlayerInternal { fn handle_command_preload(&mut self, track_id: SpotifyId) { debug!("Preloading track"); let mut preload_track = true; - + let preload_index = match self.preload { + PlayerPreload::Loading { preload_index, .. } => preload_index, + // The last preload was missing, so increment it + PlayerPreload::Missing { preload_index, .. } => preload_index + 1, + _ => 1, + }; // check whether the track is already loaded somewhere or being loaded. if let PlayerPreload::Loading { track_id: currently_loading, @@ -1336,7 +1366,11 @@ impl PlayerInternal { // schedule the preload if the current track if desired. if preload_track { let loader = self.load_track(track_id, 0); - self.preload = PlayerPreload::Loading { track_id, loader } + self.preload = PlayerPreload::Loading { + track_id, + loader, + preload_index, + } } }