Tweak unavailable track handling

Flag them as `NonPlayable` instead of removing them from the queue
This commit is contained in:
ashthespy 2020-05-13 13:30:30 +02:00
parent 9cacc2d09f
commit 01813cf7c9

View file

@ -454,8 +454,8 @@ impl SpircTask {
Ok(dur) => dur, Ok(dur) => dur,
Err(err) => err.duration(), Err(err) => err.duration(),
}; };
((dur.as_secs() as i64 + self.session.time_delta()) * 1000 (dur.as_secs() as i64 + self.session.time_delta()) * 1000
+ (dur.subsec_nanos() / 1000_000) as i64) + (dur.subsec_nanos() / 1000_000) as i64
} }
fn ensure_mixer_started(&mut self) { fn ensure_mixer_started(&mut self) {
@ -622,7 +622,7 @@ impl SpircTask {
} }
}, },
PlayerEvent::TimeToPreloadNextTrack { .. } => self.handle_preload_next_track(), PlayerEvent::TimeToPreloadNextTrack { .. } => self.handle_preload_next_track(),
PlayerEvent::Unavailable { track_id, .. } => self.handle_unavalable(track_id), PlayerEvent::Unavailable { track_id, .. } => self.handle_unavailable(track_id),
_ => (), _ => (),
} }
} }
@ -910,16 +910,28 @@ impl SpircTask {
| SpircPlayStatus::Stopped => (), | SpircPlayStatus::Stopped => (),
} }
} }
// Mark unavailable tracks so we can skip them later
fn handle_unavalable(&mut self, track_id: SpotifyId) { fn handle_unavailable(&mut self, track_id: SpotifyId) {
let unavalable_index = self.get_track_index_for_spotify_id( let unavailables = self.get_track_index_for_spotify_id(
&track_id, &track_id,
self.state.get_playing_track_index() as usize, self.state.get_playing_track_index() as usize,
); );
if let Some(index) = unavalable_index {
// TODO: Or mark it as NonPlayable? for &index in unavailables.iter() {
debug!("Removing unavailable track_ref at {:?}", index); debug_assert_eq!(self.state.get_track()[index].get_gid(), track_id.to_raw());
self.state.mut_track().remove(index); let mut unplayable_track_ref = TrackRef::new();
unplayable_track_ref.set_gid(self.state.get_track()[index].get_gid().to_vec());
// Misuse context field to flag the track
unplayable_track_ref.set_context(String::from("NonPlayable"));
std::mem::swap(
&mut self.state.mut_track()[index],
&mut unplayable_track_ref,
);
debug!(
"Marked <{:?}> at {:?} as NonPlayable",
self.state.get_track()[index],
index,
);
} }
self.handle_preload_next_track(); self.handle_preload_next_track();
} }
@ -1157,18 +1169,28 @@ impl SpircTask {
}) })
} }
// Helper to find corresponding index(s) for track_id
fn get_track_index_for_spotify_id( fn get_track_index_for_spotify_id(
&self, &self,
track_id: &SpotifyId, track_id: &SpotifyId,
start_index: usize, start_index: usize,
) -> Option<usize> { ) -> Vec<usize> {
let index = self.state.get_track()[start_index..] let index: Vec<usize> = self.state.get_track()[start_index..]
.iter() .iter()
.position(|track_ref| self.get_spotify_id_for_track(track_ref) == Ok(*track_id)); .enumerate()
.filter(|&(_, track_ref)| track_ref.get_gid() == track_id.to_raw())
.map(|(idx, _)| start_index + idx)
.collect();
// Sanity check
debug_assert!(!index.is_empty());
index index
} }
// Broken out here so we can refactor this later when we move to SpotifyObjectID or similar
fn track_ref_is_unavailable(&self, track_ref: &TrackRef) -> bool {
track_ref.get_context() == "NonPlayable"
}
fn get_track_id_to_play_from_playlist(&self, index: u32) -> Option<(SpotifyId, u32)> { fn get_track_id_to_play_from_playlist(&self, index: u32) -> Option<(SpotifyId, u32)> {
let tracks_len = self.state.get_track().len(); let tracks_len = self.state.get_track().len();
@ -1186,7 +1208,10 @@ impl SpircTask {
let mut track_ref = self.state.get_track()[new_playlist_index].clone(); let mut track_ref = self.state.get_track()[new_playlist_index].clone();
let mut track_id = self.get_spotify_id_for_track(&track_ref); let mut track_id = self.get_spotify_id_for_track(&track_ref);
while track_id.is_err() || track_id.unwrap().audio_type == SpotifyAudioType::NonPlayable { while self.track_ref_is_unavailable(&track_ref)
|| track_id.is_err()
|| track_id.unwrap().audio_type == SpotifyAudioType::NonPlayable
{
warn!( warn!(
"Skipping track <{:?}> at position [{}] of {}", "Skipping track <{:?}> at position [{}] of {}",
track_ref.get_uri(), track_ref.get_uri(),