Quellcode durchsuchen

Handle unplayable tracks during prefetch

ashthespy vor 4 Jahren
Ursprung
Commit
902440925d
2 geänderte Dateien mit 64 neuen und 24 gelöschten Zeilen
  1. 26 20
      connect/src/spirc.rs
  2. 38 4
      playback/src/player.rs

+ 26 - 20
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<SpotifyId> {
-        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<SpotifyId> {
+        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) {

+ 38 - 4
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<dyn Future<Item = PlayerLoadedTrackData, Error = ()>>,
+        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,
+            }
         }
     }