mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Support playing multiple tracks in a row
This commit is contained in:
parent
506f3e624e
commit
1d76658fdf
2 changed files with 39 additions and 15 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
39
src/spirc.rs
39
src/spirc.rs
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue