Support playing multiple tracks in a row

This commit is contained in:
Paul Lietar 2015-07-09 23:09:40 +01:00
parent 506f3e624e
commit 1d76658fdf
2 changed files with 39 additions and 15 deletions

View file

@ -22,7 +22,9 @@ pub struct PlayerState {
status: PlayStatus,
position_ms: u32,
position_measured_at: i64,
update_time: i64
update_time: i64,
end_of_track: bool
}
struct PlayerInternal<'s> {
@ -49,6 +51,7 @@ impl <'s> Player<'s> {
position_ms: 0,
position_measured_at: 0,
update_time: util::now_ms(),
end_of_track: false,
}), Condvar::new()));
let internal = PlayerInternal {
@ -90,6 +93,7 @@ impl <'s> PlayerInternal<'s> {
if state.status == PlayStatus::kPlayStatusPlay {
stream.stop().unwrap();
}
state.end_of_track = false;
state.status = PlayStatus::kPlayStatusLoading;
state.position_ms = position;
state.position_measured_at = util::now_ms();
@ -174,6 +178,7 @@ impl <'s> PlayerInternal<'s> {
None => {
self.update(|state| {
state.status = PlayStatus::kPlayStatusStop;
state.end_of_track = true;
return true;
});
@ -273,5 +278,9 @@ impl SpircState for PlayerState {
fn update_time(&self) -> i64 {
return self.update_time;
}
fn end_of_track(&self) -> bool {
return self.end_of_track;
}
}

View file

@ -33,7 +33,8 @@ pub struct SpircManager<'s, D: SpircDelegate> {
last_command_ident: String,
last_command_msgid: u32,
track: Option<SpotifyId>
tracks: Vec<SpotifyId>,
index: u32
}
pub trait SpircDelegate {
@ -54,6 +55,7 @@ pub trait SpircState {
fn status(&self) -> PlayStatus;
fn position(&self) -> (u32, i64);
fn update_time(&self) -> i64;
fn end_of_track(&self) -> bool;
}
impl <'s, D: SpircDelegate> SpircManager<'s, D> {
@ -82,7 +84,8 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
last_command_ident: String::new(),
last_command_msgid: 0,
track: None
tracks: Vec::new(),
index: 0
}
}
@ -108,12 +111,19 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
}
},
update_time = updates.recv() => {
let end_of_track = self.delegate.state().end_of_track();
if end_of_track {
self.index = (self.index + 1) % self.tracks.len() as u32;
let track = self.tracks[self.index as usize];
self.delegate.load(track, true, 0);
} else {
self.state_update_id = update_time.unwrap();
self.notify(None);
}
}
}
}
}
fn handle(&mut self, frame: protocol::spirc::Frame) {
if frame.get_recipient().len() > 0 {
@ -130,11 +140,16 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
self.became_active_at = util::now_ms();
}
let index = frame.get_state().get_playing_track_index() as usize;
let track = SpotifyId::from_raw(frame.get_state().get_track()[index].get_gid());
self.index = frame.get_state().get_playing_track_index();
self.tracks = frame.get_state().get_track().iter()
.map(|track| SpotifyId::from_raw(track.get_gid()))
.collect();
let play = frame.get_state().get_status() == PlayStatus::kPlayStatusPlay;
self.track = Some(track);
self.delegate.load(track, play, frame.get_state().get_position_ms());
let track = self.tracks[self.index as usize];
let position = frame.get_state().get_position_ms();
self.delegate.load(track, play, position);
}
protocol::spirc::MessageType::kMessageTypePlay => {
self.delegate.play();
@ -190,12 +205,12 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
position_ms: position_ms,
position_measured_at: position_measured_at as u64,
playing_track_index: 0,
track => [
@{
gid: self.track.unwrap().to_raw().to_vec()
}
],
playing_track_index: self.index,
track: self.tracks.iter().map(|track| {
protobuf_init!(protocol::spirc::TrackRef::new(), {
gid: track.to_raw().to_vec()
})
}).collect(),
shuffle: self.shuffle,
repeat: self.repeat,