From c9117542eb290795b458f59fd4af99e6f6cd03da Mon Sep 17 00:00:00 2001 From: Konstantin Seiler Date: Thu, 12 Mar 2020 23:01:45 +1100 Subject: [PATCH 1/6] Refactor TrackMetaData in the player and add the metadata to the player events. Fire more events in the --onevent script and set more variables. --- playback/src/player.rs | 354 +++++++++++++++++++----------------- src/main.rs | 1 + src/player_event_handler.rs | 29 +++ 3 files changed, 217 insertions(+), 167 deletions(-) diff --git a/playback/src/player.rs b/playback/src/player.rs index a26d3583..def9371c 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -66,44 +66,62 @@ enum PlayerCommand { #[derive(Debug, Clone)] pub enum PlayerEvent { + // Fired when the player is stopped (e.g. by issuing a "stop" command to the player). Stopped { play_request_id: u64, track_id: SpotifyId, }, - Loading { - play_request_id: u64, - track_id: SpotifyId, - position_ms: u32, - }, + // The player started working on playback of a track while it was in a stopped state. + // This is always immediately followed up by a "Loading" or "Playing" event. Started { play_request_id: u64, track_id: SpotifyId, position_ms: u32, }, + // Same as started but in the case that the player already had a track loaded. + // The player was either playing the loaded track or it was paused. Changed { old_track_id: SpotifyId, new_track_id: SpotifyId, }, + // The player is delayed by loading a track. + Loading { + play_request_id: u64, + track_id: SpotifyId, + position_ms: u32, + }, + // The player is playing a track. + // This event is issued at the start of playback of whenever the position must be communicated + // because it is out of sync. This includes: + // start of a track + // un-pausing + // after a seek + // after a buffer-underrun Playing { play_request_id: u64, - track_id: SpotifyId, + track_meta_data: TrackMetaData, position_ms: u32, - duration_ms: u32, }, + // The player entered a paused state. Paused { play_request_id: u64, - track_id: SpotifyId, + track_meta_data: TrackMetaData, position_ms: u32, - duration_ms: u32, }, + // The player thinks it's a good idea to issue a preload command for the next track now. + // This event is intended for use within spirc. TimeToPreloadNextTrack { play_request_id: u64, track_id: SpotifyId, }, + // The player reached the end of a track. + // This event is intended for use within spirc. Spirc will respond by issuing another command + // which will trigger another event (e.g. Changed or Stopped) EndOfTrack { play_request_id: u64, - track_id: SpotifyId, + track_meta_data: TrackMetaData, }, + // The mixer volume was set to a new level. VolumeSet { volume: u16, }, @@ -306,12 +324,19 @@ impl Drop for Player { } } +#[derive(Debug, Clone)] +pub struct TrackMetaData { + pub track_id: SpotifyId, + pub normalisation_factor: f32, + pub duration_ms: u32, + pub bytes_per_second: usize, + pub title: String, +} + struct PlayerLoadedTrackData { + track_meta_data: TrackMetaData, decoder: Decoder, - normalisation_factor: f32, stream_loader_controller: StreamLoaderController, - bytes_per_second: usize, - duration_ms: u32, stream_position_pcm: u64, } @@ -322,7 +347,6 @@ enum PlayerPreload { loader: Box>, }, Ready { - track_id: SpotifyId, loaded_track: PlayerLoadedTrackData, }, } @@ -338,32 +362,25 @@ enum PlayerState { loader: Box>, }, Paused { - track_id: SpotifyId, + track_meta_data: TrackMetaData, play_request_id: u64, decoder: Decoder, - normalisation_factor: f32, stream_loader_controller: StreamLoaderController, - bytes_per_second: usize, - duration_ms: u32, stream_position_pcm: u64, suggested_to_preload_next_track: bool, }, Playing { - track_id: SpotifyId, + track_meta_data: TrackMetaData, play_request_id: u64, decoder: Decoder, - normalisation_factor: f32, stream_loader_controller: StreamLoaderController, - bytes_per_second: usize, - duration_ms: u32, stream_position_pcm: u64, reported_nominal_start_time: Option, suggested_to_preload_next_track: bool, }, EndOfTrack { - track_id: SpotifyId, play_request_id: u64, - loaded_track: Option, + loaded_track: PlayerLoadedTrackData, }, Invalid, } @@ -420,27 +437,21 @@ impl PlayerState { use self::PlayerState::*; match mem::replace(self, Invalid) { Playing { - track_id, + track_meta_data, play_request_id, decoder, - duration_ms, - bytes_per_second, - normalisation_factor, stream_loader_controller, stream_position_pcm, .. } => { *self = EndOfTrack { - track_id, play_request_id, - loaded_track: Some(PlayerLoadedTrackData { + loaded_track: PlayerLoadedTrackData { + track_meta_data, decoder, - duration_ms, - bytes_per_second, - normalisation_factor, stream_loader_controller, stream_position_pcm, - }), + }, }; } _ => panic!("Called playing_to_end_of_track in non-playing state."), @@ -451,24 +462,18 @@ impl PlayerState { use self::PlayerState::*; match ::std::mem::replace(self, Invalid) { Paused { - track_id, + track_meta_data, play_request_id, decoder, - normalisation_factor, stream_loader_controller, - duration_ms, - bytes_per_second, stream_position_pcm, suggested_to_preload_next_track, } => { *self = Playing { - track_id, + track_meta_data, play_request_id, decoder, - normalisation_factor, stream_loader_controller, - duration_ms, - bytes_per_second, stream_position_pcm, reported_nominal_start_time: None, suggested_to_preload_next_track, @@ -482,25 +487,19 @@ impl PlayerState { use self::PlayerState::*; match ::std::mem::replace(self, Invalid) { Playing { - track_id, + track_meta_data, play_request_id, decoder, - normalisation_factor, stream_loader_controller, - duration_ms, - bytes_per_second, stream_position_pcm, reported_nominal_start_time: _, suggested_to_preload_next_track, } => { *self = Paused { - track_id, + track_meta_data, play_request_id, decoder, - normalisation_factor, stream_loader_controller, - duration_ms, - bytes_per_second, stream_position_pcm, suggested_to_preload_next_track, }; @@ -670,11 +669,15 @@ impl PlayerTrackLoader { let stream_position_pcm = PlayerInternal::position_ms_to_pcm(position_ms); info!("<{}> ({} ms) loaded", audio.name, audio.duration); Some(PlayerLoadedTrackData { + track_meta_data: TrackMetaData { + track_id: spotify_id, + normalisation_factor, + bytes_per_second, + duration_ms, + title: audio.name.clone(), + }, decoder, - normalisation_factor, stream_loader_controller, - bytes_per_second, - duration_ms, stream_position_pcm, }) } @@ -709,19 +712,14 @@ impl Future for PlayerInternal { // Handle loading of a new track to play if let PlayerState::Loading { ref mut loader, - track_id, start_playback, play_request_id, + .. } = self.state { match loader.poll() { Ok(Async::Ready(loaded_track)) => { - self.start_playback( - track_id, - play_request_id, - loaded_track, - start_playback, - ); + self.start_playback(play_request_id, loaded_track, start_playback); if let PlayerState::Loading { .. } = self.state { panic!("The state wasn't changed by start_playback()"); } @@ -735,17 +733,10 @@ impl Future for PlayerInternal { } // handle pending preload requests. - if let PlayerPreload::Loading { - ref mut loader, - track_id, - } = self.preload - { + if let PlayerPreload::Loading { ref mut loader, .. } = self.preload { match loader.poll() { Ok(Async::Ready(loaded_track)) => { - self.preload = PlayerPreload::Ready { - track_id, - loaded_track, - }; + self.preload = PlayerPreload::Ready { loaded_track }; } Ok(Async::NotReady) => (), Err(_) => { @@ -758,16 +749,16 @@ impl Future for PlayerInternal { self.ensure_sink_running(); if let PlayerState::Playing { - track_id, + ref track_meta_data, play_request_id, ref mut decoder, - normalisation_factor, ref mut stream_position_pcm, ref mut reported_nominal_start_time, - duration_ms, .. } = self.state { + let track_meta_data = track_meta_data.clone(); + let normalisation_factor = track_meta_data.normalisation_factor; let packet = decoder.next_packet().expect("Vorbis error"); if let Some(ref packet) = packet { @@ -795,10 +786,9 @@ impl Future for PlayerInternal { - Duration::from_millis(stream_position_millis as u64), ); self.send_event(PlayerEvent::Playing { - track_id, + track_meta_data, play_request_id, position_ms: stream_position_millis as u32, - duration_ms, }); } } @@ -810,18 +800,16 @@ impl Future for PlayerInternal { } if let PlayerState::Playing { - track_id, + ref track_meta_data, play_request_id, - duration_ms, stream_position_pcm, ref mut stream_loader_controller, ref mut suggested_to_preload_next_track, .. } | PlayerState::Paused { - track_id, + ref track_meta_data, play_request_id, - duration_ms, stream_position_pcm, ref mut stream_loader_controller, ref mut suggested_to_preload_next_track, @@ -829,13 +817,15 @@ impl Future for PlayerInternal { } = self.state { if (!*suggested_to_preload_next_track) - && ((duration_ms as i64 - Self::position_pcm_to_ms(stream_position_pcm) as i64) + && ((track_meta_data.duration_ms as i64 + - Self::position_pcm_to_ms(stream_position_pcm) as i64) < PRELOAD_NEXT_TRACK_BEFORE_END_DURATION_MS as i64) && stream_loader_controller.range_to_end_available() { *suggested_to_preload_next_track = true; + let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::TimeToPreloadNextTrack { - track_id, + track_id: track_meta_data.track_id, play_request_id, }); } @@ -882,17 +872,21 @@ impl PlayerInternal { fn handle_player_stop(&mut self) { match self.state { PlayerState::Playing { - track_id, + track_meta_data: TrackMetaData { track_id, .. }, play_request_id, .. } | PlayerState::Paused { - track_id, + track_meta_data: TrackMetaData { track_id, .. }, play_request_id, .. } | PlayerState::EndOfTrack { - track_id, + loaded_track: + PlayerLoadedTrackData { + track_meta_data: TrackMetaData { track_id, .. }, + .. + }, play_request_id, .. } @@ -915,21 +909,20 @@ impl PlayerInternal { fn handle_play(&mut self) { if let PlayerState::Paused { - track_id, + ref track_meta_data, play_request_id, stream_position_pcm, - duration_ms, .. } = self.state { + let track_meta_data = track_meta_data.clone(); self.state.paused_to_playing(); let position_ms = Self::position_pcm_to_ms(stream_position_pcm); self.send_event(PlayerEvent::Playing { - track_id, + track_meta_data, play_request_id, position_ms, - duration_ms, }); self.ensure_sink_running(); } else { @@ -939,22 +932,22 @@ impl PlayerInternal { fn handle_pause(&mut self) { if let PlayerState::Playing { - track_id, + ref track_meta_data, play_request_id, stream_position_pcm, - duration_ms, .. } = self.state { + let track_meta_data = track_meta_data.clone(); + self.state.playing_to_paused(); self.ensure_sink_stopped(); let position_ms = Self::position_pcm_to_ms(stream_position_pcm); self.send_event(PlayerEvent::Paused { - track_id, + track_meta_data, play_request_id, position_ms, - duration_ms, }); } else { warn!("Player::pause called from invalid state"); @@ -985,13 +978,18 @@ impl PlayerInternal { None => { self.state.playing_to_end_of_track(); if let PlayerState::EndOfTrack { - track_id, + loaded_track: + PlayerLoadedTrackData { + ref track_meta_data, + .. + }, play_request_id, .. } = self.state { + let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::EndOfTrack { - track_id, + track_meta_data, play_request_id, }) } else { @@ -1003,7 +1001,6 @@ impl PlayerInternal { fn start_playback( &mut self, - track_id: SpotifyId, play_request_id: u64, loaded_track: PlayerLoadedTrackData, start_playback: bool, @@ -1014,20 +1011,16 @@ impl PlayerInternal { self.ensure_sink_running(); self.send_event(PlayerEvent::Playing { - track_id, + track_meta_data: loaded_track.track_meta_data.clone(), play_request_id, position_ms, - duration_ms: loaded_track.duration_ms, }); self.state = PlayerState::Playing { - track_id: track_id, + track_meta_data: loaded_track.track_meta_data, play_request_id: play_request_id, decoder: loaded_track.decoder, - normalisation_factor: loaded_track.normalisation_factor, stream_loader_controller: loaded_track.stream_loader_controller, - duration_ms: loaded_track.duration_ms, - bytes_per_second: loaded_track.bytes_per_second, stream_position_pcm: loaded_track.stream_position_pcm, reported_nominal_start_time: Some( Instant::now() - Duration::from_millis(position_ms as u64), @@ -1037,23 +1030,21 @@ impl PlayerInternal { } else { self.ensure_sink_stopped(); + let track_meta_data = loaded_track.track_meta_data.clone(); + self.state = PlayerState::Paused { - track_id: track_id, + track_meta_data: loaded_track.track_meta_data, play_request_id: play_request_id, decoder: loaded_track.decoder, - normalisation_factor: loaded_track.normalisation_factor, stream_loader_controller: loaded_track.stream_loader_controller, - duration_ms: loaded_track.duration_ms, - bytes_per_second: loaded_track.bytes_per_second, stream_position_pcm: loaded_track.stream_position_pcm, suggested_to_preload_next_track: false, }; self.send_event(PlayerEvent::Paused { - track_id, + track_meta_data, play_request_id, position_ms, - duration_ms: loaded_track.duration_ms, }); } } @@ -1071,15 +1062,31 @@ impl PlayerInternal { // emit the correct player event match self.state { PlayerState::Playing { - track_id: old_track_id, + track_meta_data: + TrackMetaData { + track_id: old_track_id, + .. + }, .. } | PlayerState::Paused { - track_id: old_track_id, + track_meta_data: + TrackMetaData { + track_id: old_track_id, + .. + }, .. } | PlayerState::EndOfTrack { - track_id: old_track_id, + loaded_track: + PlayerLoadedTrackData { + track_meta_data: + TrackMetaData { + track_id: old_track_id, + .. + }, + .. + }, .. } | PlayerState::Loading { @@ -1103,49 +1110,56 @@ impl PlayerInternal { // Check if there's a matching loaded track in the EndOfTrack player state. // This is the case if we're repeating the same track again. if let PlayerState::EndOfTrack { - track_id: previous_track_id, ref mut loaded_track, .. } = self.state { - if previous_track_id == track_id { - let loaded_track = mem::replace(&mut *loaded_track, None); - if let Some(mut loaded_track) = loaded_track { - if Self::position_ms_to_pcm(position_ms) != loaded_track.stream_position_pcm { - loaded_track - .stream_loader_controller - .set_random_access_mode(); - let _ = loaded_track.decoder.seek(position_ms as i64); // This may be blocking. - // But most likely the track is fully - // loaded already because we played - // to the end of it. - loaded_track.stream_loader_controller.set_stream_mode(); - loaded_track.stream_position_pcm = Self::position_ms_to_pcm(position_ms); - } - self.preload = PlayerPreload::None; - self.start_playback(track_id, play_request_id, loaded_track, play); - return; + if loaded_track.track_meta_data.track_id == track_id { + let mut loaded_track = match mem::replace(&mut self.state, PlayerState::Invalid) { + PlayerState::EndOfTrack { loaded_track, .. } => loaded_track, + _ => unreachable!(), + }; + + //let loaded_track = mem::replace(&mut *loaded_track, None); + //if let Some(mut loaded_track) = loaded_track { + if Self::position_ms_to_pcm(position_ms) != loaded_track.stream_position_pcm { + loaded_track + .stream_loader_controller + .set_random_access_mode(); + let _ = loaded_track.decoder.seek(position_ms as i64); // This may be blocking. + // But most likely the track is fully + // loaded already because we played + // to the end of it. + loaded_track.stream_loader_controller.set_stream_mode(); + loaded_track.stream_position_pcm = Self::position_ms_to_pcm(position_ms); } + self.preload = PlayerPreload::None; + self.start_playback(play_request_id, loaded_track, play); + if let PlayerState::Invalid = self.state { + panic!("start_playback() hasn't set a valid player state."); + } + return; + //} } } // Check if we are already playing the track. If so, just do a seek and update our info. if let PlayerState::Playing { - track_id: current_track_id, + ref track_meta_data, ref mut stream_position_pcm, ref mut decoder, ref mut stream_loader_controller, .. } | PlayerState::Paused { - track_id: current_track_id, + ref track_meta_data, ref mut stream_position_pcm, ref mut decoder, ref mut stream_loader_controller, .. } = self.state { - if current_track_id == track_id { + if track_meta_data.track_id == track_id { // we can use the current decoder. Ensure it's at the correct position. if Self::position_ms_to_pcm(position_ms) != *stream_position_pcm { stream_loader_controller.set_random_access_mode(); @@ -1159,35 +1173,29 @@ impl PlayerInternal { let old_state = mem::replace(&mut self.state, PlayerState::Invalid); if let PlayerState::Playing { + track_meta_data, stream_position_pcm, decoder, stream_loader_controller, - bytes_per_second, - duration_ms, - normalisation_factor, .. } | PlayerState::Paused { + track_meta_data, stream_position_pcm, decoder, stream_loader_controller, - bytes_per_second, - duration_ms, - normalisation_factor, .. } = old_state { let loaded_track = PlayerLoadedTrackData { + track_meta_data, decoder, - normalisation_factor, stream_loader_controller, - bytes_per_second, - duration_ms, stream_position_pcm, }; self.preload = PlayerPreload::None; - self.start_playback(track_id, play_request_id, loaded_track, play); + self.start_playback(play_request_id, loaded_track, play); if let PlayerState::Invalid = self.state { panic!("start_playback() hasn't set a valid player state."); @@ -1202,17 +1210,17 @@ impl PlayerInternal { // Check if the requested track has been preloaded already. If so use the preloaded data. if let PlayerPreload::Ready { - track_id: loaded_track_id, + loaded_track: + PlayerLoadedTrackData { + ref track_meta_data, + .. + }, .. } = self.preload { - if track_id == loaded_track_id { + if track_id == track_meta_data.track_id { let preload = std::mem::replace(&mut self.preload, PlayerPreload::None); - if let PlayerPreload::Ready { - track_id, - mut loaded_track, - } = preload - { + if let PlayerPreload::Ready { mut loaded_track } = preload { if Self::position_ms_to_pcm(position_ms) != loaded_track.stream_position_pcm { loaded_track .stream_loader_controller @@ -1220,7 +1228,7 @@ impl PlayerInternal { let _ = loaded_track.decoder.seek(position_ms as i64); // This may be blocking loaded_track.stream_loader_controller.set_stream_mode(); } - self.start_playback(track_id, play_request_id, loaded_track, play); + self.start_playback(play_request_id, loaded_track, play); return; } else { unreachable!(); @@ -1285,7 +1293,15 @@ impl PlayerInternal { .. } | PlayerPreload::Ready { - track_id: currently_loading, + loaded_track: + PlayerLoadedTrackData { + track_meta_data: + TrackMetaData { + track_id: currently_loading, + .. + }, + .. + }, .. } = self.preload { @@ -1299,25 +1315,29 @@ impl PlayerInternal { } if let PlayerState::Playing { - track_id: current_track_id, + ref track_meta_data, .. } | PlayerState::Paused { - track_id: current_track_id, + ref track_meta_data, .. } | PlayerState::EndOfTrack { - track_id: current_track_id, + loaded_track: + PlayerLoadedTrackData { + ref track_meta_data, + .. + }, .. } = self.state { - if current_track_id == track_id { + if track_meta_data.track_id == track_id { // we already have the requested track loaded. preload_track = false; } } - // schedule the preload if the current track if desired. + // schedule the preload of the current track if desired. if preload_track { let loader = self.load_track(track_id, 0); self.preload = PlayerPreload::Loading { track_id, loader } @@ -1358,34 +1378,32 @@ impl PlayerInternal { self.preload_data_before_playback(); if let PlayerState::Playing { - track_id, + ref track_meta_data, play_request_id, ref mut reported_nominal_start_time, - duration_ms, .. } = self.state { *reported_nominal_start_time = Some(Instant::now() - Duration::from_millis(position_ms as u64)); + let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::Playing { - track_id, + track_meta_data, play_request_id, position_ms, - duration_ms, }); } if let PlayerState::Paused { - track_id, + ref track_meta_data, play_request_id, - duration_ms, .. } = self.state { + let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::Paused { - track_id, + track_meta_data, play_request_id, position_ms, - duration_ms, }); } } @@ -1462,7 +1480,7 @@ impl PlayerInternal { fn preload_data_before_playback(&mut self) { if let PlayerState::Playing { - bytes_per_second, + ref track_meta_data, ref mut stream_loader_controller, .. } = self.state @@ -1471,8 +1489,9 @@ impl PlayerInternal { let request_data_length = max( (READ_AHEAD_DURING_PLAYBACK_ROUNDTRIPS * (0.001 * stream_loader_controller.ping_time_ms() as f64) - * bytes_per_second as f64) as usize, - (READ_AHEAD_DURING_PLAYBACK_SECONDS * bytes_per_second as f64) as usize, + * track_meta_data.bytes_per_second as f64) as usize, + (READ_AHEAD_DURING_PLAYBACK_SECONDS * track_meta_data.bytes_per_second as f64) + as usize, ); stream_loader_controller.fetch_next(request_data_length); @@ -1480,8 +1499,9 @@ impl PlayerInternal { let wait_for_data_length = max( (READ_AHEAD_BEFORE_PLAYBACK_ROUNDTRIPS * (0.001 * stream_loader_controller.ping_time_ms() as f64) - * bytes_per_second as f64) as usize, - (READ_AHEAD_BEFORE_PLAYBACK_SECONDS * bytes_per_second as f64) as usize, + * track_meta_data.bytes_per_second as f64) as usize, + (READ_AHEAD_BEFORE_PLAYBACK_SECONDS * track_meta_data.bytes_per_second as f64) + as usize, ); stream_loader_controller.fetch_next_blocking(wait_for_data_length); } diff --git a/src/main.rs b/src/main.rs index ef8dbd7b..bdf13e80 100644 --- a/src/main.rs +++ b/src/main.rs @@ -543,6 +543,7 @@ impl Future for Main { if let Some(ref mut player_event_channel) = self.player_event_channel { if let Async::Ready(Some(event)) = player_event_channel.poll().unwrap() { + progress = true; if let Some(ref program) = self.player_event_program { if let Some(child) = run_program_on_events(event, program) { let child = child diff --git a/src/player_event_handler.rs b/src/player_event_handler.rs index 2fa34d2b..36c5adc1 100644 --- a/src/player_event_handler.rs +++ b/src/player_event_handler.rs @@ -1,4 +1,5 @@ use librespot::playback::player::PlayerEvent; +use librespot_playback::player::TrackMetaData; use log::info; use std::collections::HashMap; use std::io; @@ -14,6 +15,12 @@ fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result, track_meta_data: TrackMetaData) { + env_vars.insert("TRACK_ID", track_meta_data.track_id.to_base62()); + env_vars.insert("DURATION_MS", track_meta_data.duration_ms.to_string()); + env_vars.insert("TITLE", track_meta_data.title); +} + pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> Option> { let mut env_vars = HashMap::new(); match event { @@ -33,6 +40,28 @@ pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> Option { + env_vars.insert("PLAYER_EVENT", "playing".to_string()); + add_meta_data_to_env_vars(&mut env_vars, track_meta_data); + env_vars.insert("POSITION_MS", position_ms.to_string()); + } + PlayerEvent::Paused { + track_meta_data, + position_ms, + .. + } => { + env_vars.insert("PLAYER_EVENT", "paused".to_string()); + add_meta_data_to_env_vars(&mut env_vars, track_meta_data); + env_vars.insert("POSITION_MS", position_ms.to_string()); + } + PlayerEvent::VolumeSet { volume } => { + env_vars.insert("PLAYER_EVENT", "volume_set".to_string()); + env_vars.insert("VOLUME", volume.to_string()); + } _ => return None, } Some(run_program(onevent, env_vars)) From b562ec6015f3caf709a3d5bf2375cad7eaa4f945 Mon Sep 17 00:00:00 2001 From: Konstantin Seiler Date: Thu, 12 Mar 2020 23:29:24 +1100 Subject: [PATCH 2/6] rename variable. --- src/player_event_handler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player_event_handler.rs b/src/player_event_handler.rs index 36c5adc1..4809fc22 100644 --- a/src/player_event_handler.rs +++ b/src/player_event_handler.rs @@ -18,7 +18,7 @@ fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result, track_meta_data: TrackMetaData) { env_vars.insert("TRACK_ID", track_meta_data.track_id.to_base62()); env_vars.insert("DURATION_MS", track_meta_data.duration_ms.to_string()); - env_vars.insert("TITLE", track_meta_data.title); + env_vars.insert("TRACK_TITLE", track_meta_data.title); } pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> Option> { From 223b8d611e7c354cb1d784f71b89d8a3d851af19 Mon Sep 17 00:00:00 2001 From: Konstantin Seiler Date: Fri, 20 Mar 2020 17:31:18 +1100 Subject: [PATCH 3/6] Roll back the meta data processing. --- playback/src/player.rs | 282 ++++++++++++++++++------------------ src/player_event_handler.rs | 19 +-- 2 files changed, 151 insertions(+), 150 deletions(-) diff --git a/playback/src/player.rs b/playback/src/player.rs index def9371c..2dd8f3bd 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -99,14 +99,16 @@ pub enum PlayerEvent { // after a buffer-underrun Playing { play_request_id: u64, - track_meta_data: TrackMetaData, + track_id: SpotifyId, position_ms: u32, + duration_ms: u32, }, // The player entered a paused state. Paused { play_request_id: u64, - track_meta_data: TrackMetaData, + track_id: SpotifyId, position_ms: u32, + duration_ms: u32, }, // The player thinks it's a good idea to issue a preload command for the next track now. // This event is intended for use within spirc. @@ -119,7 +121,7 @@ pub enum PlayerEvent { // which will trigger another event (e.g. Changed or Stopped) EndOfTrack { play_request_id: u64, - track_meta_data: TrackMetaData, + track_id: SpotifyId, }, // The mixer volume was set to a new level. VolumeSet { @@ -324,19 +326,12 @@ impl Drop for Player { } } -#[derive(Debug, Clone)] -pub struct TrackMetaData { - pub track_id: SpotifyId, - pub normalisation_factor: f32, - pub duration_ms: u32, - pub bytes_per_second: usize, - pub title: String, -} - struct PlayerLoadedTrackData { - track_meta_data: TrackMetaData, decoder: Decoder, + normalisation_factor: f32, stream_loader_controller: StreamLoaderController, + bytes_per_second: usize, + duration_ms: u32, stream_position_pcm: u64, } @@ -347,6 +342,7 @@ enum PlayerPreload { loader: Box>, }, Ready { + track_id: SpotifyId, loaded_track: PlayerLoadedTrackData, }, } @@ -362,23 +358,30 @@ enum PlayerState { loader: Box>, }, Paused { - track_meta_data: TrackMetaData, + track_id: SpotifyId, play_request_id: u64, decoder: Decoder, + normalisation_factor: f32, stream_loader_controller: StreamLoaderController, + bytes_per_second: usize, + duration_ms: u32, stream_position_pcm: u64, suggested_to_preload_next_track: bool, }, Playing { - track_meta_data: TrackMetaData, + track_id: SpotifyId, play_request_id: u64, decoder: Decoder, + normalisation_factor: f32, stream_loader_controller: StreamLoaderController, + bytes_per_second: usize, + duration_ms: u32, stream_position_pcm: u64, reported_nominal_start_time: Option, suggested_to_preload_next_track: bool, }, EndOfTrack { + track_id: SpotifyId, play_request_id: u64, loaded_track: PlayerLoadedTrackData, }, @@ -437,18 +440,24 @@ impl PlayerState { use self::PlayerState::*; match mem::replace(self, Invalid) { Playing { - track_meta_data, + track_id, play_request_id, decoder, + duration_ms, + bytes_per_second, + normalisation_factor, stream_loader_controller, stream_position_pcm, .. } => { *self = EndOfTrack { + track_id, play_request_id, loaded_track: PlayerLoadedTrackData { - track_meta_data, decoder, + duration_ms, + bytes_per_second, + normalisation_factor, stream_loader_controller, stream_position_pcm, }, @@ -462,18 +471,24 @@ impl PlayerState { use self::PlayerState::*; match ::std::mem::replace(self, Invalid) { Paused { - track_meta_data, + track_id, play_request_id, decoder, + normalisation_factor, stream_loader_controller, + duration_ms, + bytes_per_second, stream_position_pcm, suggested_to_preload_next_track, } => { *self = Playing { - track_meta_data, + track_id, play_request_id, decoder, + normalisation_factor, stream_loader_controller, + duration_ms, + bytes_per_second, stream_position_pcm, reported_nominal_start_time: None, suggested_to_preload_next_track, @@ -487,19 +502,25 @@ impl PlayerState { use self::PlayerState::*; match ::std::mem::replace(self, Invalid) { Playing { - track_meta_data, + track_id, play_request_id, decoder, + normalisation_factor, stream_loader_controller, + duration_ms, + bytes_per_second, stream_position_pcm, reported_nominal_start_time: _, suggested_to_preload_next_track, } => { *self = Paused { - track_meta_data, + track_id, play_request_id, decoder, + normalisation_factor, stream_loader_controller, + duration_ms, + bytes_per_second, stream_position_pcm, suggested_to_preload_next_track, }; @@ -669,15 +690,11 @@ impl PlayerTrackLoader { let stream_position_pcm = PlayerInternal::position_ms_to_pcm(position_ms); info!("<{}> ({} ms) loaded", audio.name, audio.duration); Some(PlayerLoadedTrackData { - track_meta_data: TrackMetaData { - track_id: spotify_id, - normalisation_factor, - bytes_per_second, - duration_ms, - title: audio.name.clone(), - }, decoder, + normalisation_factor, stream_loader_controller, + bytes_per_second, + duration_ms, stream_position_pcm, }) } @@ -712,14 +729,19 @@ impl Future for PlayerInternal { // Handle loading of a new track to play if let PlayerState::Loading { ref mut loader, + track_id, start_playback, play_request_id, - .. } = self.state { match loader.poll() { Ok(Async::Ready(loaded_track)) => { - self.start_playback(play_request_id, loaded_track, start_playback); + self.start_playback( + track_id, + play_request_id, + loaded_track, + start_playback, + ); if let PlayerState::Loading { .. } = self.state { panic!("The state wasn't changed by start_playback()"); } @@ -733,10 +755,17 @@ impl Future for PlayerInternal { } // handle pending preload requests. - if let PlayerPreload::Loading { ref mut loader, .. } = self.preload { + if let PlayerPreload::Loading { + ref mut loader, + track_id, + } = self.preload + { match loader.poll() { Ok(Async::Ready(loaded_track)) => { - self.preload = PlayerPreload::Ready { loaded_track }; + self.preload = PlayerPreload::Ready { + track_id, + loaded_track, + }; } Ok(Async::NotReady) => (), Err(_) => { @@ -749,16 +778,16 @@ impl Future for PlayerInternal { self.ensure_sink_running(); if let PlayerState::Playing { - ref track_meta_data, + track_id, play_request_id, ref mut decoder, + normalisation_factor, ref mut stream_position_pcm, ref mut reported_nominal_start_time, + duration_ms, .. } = self.state { - let track_meta_data = track_meta_data.clone(); - let normalisation_factor = track_meta_data.normalisation_factor; let packet = decoder.next_packet().expect("Vorbis error"); if let Some(ref packet) = packet { @@ -786,9 +815,10 @@ impl Future for PlayerInternal { - Duration::from_millis(stream_position_millis as u64), ); self.send_event(PlayerEvent::Playing { - track_meta_data, + track_id, play_request_id, position_ms: stream_position_millis as u32, + duration_ms, }); } } @@ -800,16 +830,18 @@ impl Future for PlayerInternal { } if let PlayerState::Playing { - ref track_meta_data, + track_id, play_request_id, + duration_ms, stream_position_pcm, ref mut stream_loader_controller, ref mut suggested_to_preload_next_track, .. } | PlayerState::Paused { - ref track_meta_data, + track_id, play_request_id, + duration_ms, stream_position_pcm, ref mut stream_loader_controller, ref mut suggested_to_preload_next_track, @@ -817,15 +849,13 @@ impl Future for PlayerInternal { } = self.state { if (!*suggested_to_preload_next_track) - && ((track_meta_data.duration_ms as i64 - - Self::position_pcm_to_ms(stream_position_pcm) as i64) + && ((duration_ms as i64 - Self::position_pcm_to_ms(stream_position_pcm) as i64) < PRELOAD_NEXT_TRACK_BEFORE_END_DURATION_MS as i64) && stream_loader_controller.range_to_end_available() { *suggested_to_preload_next_track = true; - let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::TimeToPreloadNextTrack { - track_id: track_meta_data.track_id, + track_id, play_request_id, }); } @@ -872,21 +902,17 @@ impl PlayerInternal { fn handle_player_stop(&mut self) { match self.state { PlayerState::Playing { - track_meta_data: TrackMetaData { track_id, .. }, + track_id, play_request_id, .. } | PlayerState::Paused { - track_meta_data: TrackMetaData { track_id, .. }, + track_id, play_request_id, .. } | PlayerState::EndOfTrack { - loaded_track: - PlayerLoadedTrackData { - track_meta_data: TrackMetaData { track_id, .. }, - .. - }, + track_id, play_request_id, .. } @@ -909,20 +935,21 @@ impl PlayerInternal { fn handle_play(&mut self) { if let PlayerState::Paused { - ref track_meta_data, + track_id, play_request_id, stream_position_pcm, + duration_ms, .. } = self.state { - let track_meta_data = track_meta_data.clone(); self.state.paused_to_playing(); let position_ms = Self::position_pcm_to_ms(stream_position_pcm); self.send_event(PlayerEvent::Playing { - track_meta_data, + track_id, play_request_id, position_ms, + duration_ms, }); self.ensure_sink_running(); } else { @@ -932,22 +959,22 @@ impl PlayerInternal { fn handle_pause(&mut self) { if let PlayerState::Playing { - ref track_meta_data, + track_id, play_request_id, stream_position_pcm, + duration_ms, .. } = self.state { - let track_meta_data = track_meta_data.clone(); - self.state.playing_to_paused(); self.ensure_sink_stopped(); let position_ms = Self::position_pcm_to_ms(stream_position_pcm); self.send_event(PlayerEvent::Paused { - track_meta_data, + track_id, play_request_id, position_ms, + duration_ms, }); } else { warn!("Player::pause called from invalid state"); @@ -978,18 +1005,13 @@ impl PlayerInternal { None => { self.state.playing_to_end_of_track(); if let PlayerState::EndOfTrack { - loaded_track: - PlayerLoadedTrackData { - ref track_meta_data, - .. - }, + track_id, play_request_id, .. } = self.state { - let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::EndOfTrack { - track_meta_data, + track_id, play_request_id, }) } else { @@ -1001,6 +1023,7 @@ impl PlayerInternal { fn start_playback( &mut self, + track_id: SpotifyId, play_request_id: u64, loaded_track: PlayerLoadedTrackData, start_playback: bool, @@ -1011,16 +1034,20 @@ impl PlayerInternal { self.ensure_sink_running(); self.send_event(PlayerEvent::Playing { - track_meta_data: loaded_track.track_meta_data.clone(), + track_id, play_request_id, position_ms, + duration_ms: loaded_track.duration_ms, }); self.state = PlayerState::Playing { - track_meta_data: loaded_track.track_meta_data, + track_id: track_id, play_request_id: play_request_id, decoder: loaded_track.decoder, + normalisation_factor: loaded_track.normalisation_factor, stream_loader_controller: loaded_track.stream_loader_controller, + duration_ms: loaded_track.duration_ms, + bytes_per_second: loaded_track.bytes_per_second, stream_position_pcm: loaded_track.stream_position_pcm, reported_nominal_start_time: Some( Instant::now() - Duration::from_millis(position_ms as u64), @@ -1030,21 +1057,23 @@ impl PlayerInternal { } else { self.ensure_sink_stopped(); - let track_meta_data = loaded_track.track_meta_data.clone(); - self.state = PlayerState::Paused { - track_meta_data: loaded_track.track_meta_data, + track_id: track_id, play_request_id: play_request_id, decoder: loaded_track.decoder, + normalisation_factor: loaded_track.normalisation_factor, stream_loader_controller: loaded_track.stream_loader_controller, + duration_ms: loaded_track.duration_ms, + bytes_per_second: loaded_track.bytes_per_second, stream_position_pcm: loaded_track.stream_position_pcm, suggested_to_preload_next_track: false, }; self.send_event(PlayerEvent::Paused { - track_meta_data, + track_id, play_request_id, position_ms, + duration_ms: loaded_track.duration_ms, }); } } @@ -1062,31 +1091,15 @@ impl PlayerInternal { // emit the correct player event match self.state { PlayerState::Playing { - track_meta_data: - TrackMetaData { - track_id: old_track_id, - .. - }, + track_id: old_track_id, .. } | PlayerState::Paused { - track_meta_data: - TrackMetaData { - track_id: old_track_id, - .. - }, + track_id: old_track_id, .. } | PlayerState::EndOfTrack { - loaded_track: - PlayerLoadedTrackData { - track_meta_data: - TrackMetaData { - track_id: old_track_id, - .. - }, - .. - }, + track_id: old_track_id, .. } | PlayerState::Loading { @@ -1110,18 +1123,16 @@ impl PlayerInternal { // Check if there's a matching loaded track in the EndOfTrack player state. // This is the case if we're repeating the same track again. if let PlayerState::EndOfTrack { - ref mut loaded_track, + track_id: previous_track_id, .. } = self.state { - if loaded_track.track_meta_data.track_id == track_id { + if previous_track_id == track_id { let mut loaded_track = match mem::replace(&mut self.state, PlayerState::Invalid) { PlayerState::EndOfTrack { loaded_track, .. } => loaded_track, _ => unreachable!(), }; - //let loaded_track = mem::replace(&mut *loaded_track, None); - //if let Some(mut loaded_track) = loaded_track { if Self::position_ms_to_pcm(position_ms) != loaded_track.stream_position_pcm { loaded_track .stream_loader_controller @@ -1134,32 +1145,31 @@ impl PlayerInternal { loaded_track.stream_position_pcm = Self::position_ms_to_pcm(position_ms); } self.preload = PlayerPreload::None; - self.start_playback(play_request_id, loaded_track, play); + self.start_playback(track_id, play_request_id, loaded_track, play); if let PlayerState::Invalid = self.state { panic!("start_playback() hasn't set a valid player state."); } return; - //} } } // Check if we are already playing the track. If so, just do a seek and update our info. if let PlayerState::Playing { - ref track_meta_data, + track_id: current_track_id, ref mut stream_position_pcm, ref mut decoder, ref mut stream_loader_controller, .. } | PlayerState::Paused { - ref track_meta_data, + track_id: current_track_id, ref mut stream_position_pcm, ref mut decoder, ref mut stream_loader_controller, .. } = self.state { - if track_meta_data.track_id == track_id { + if current_track_id == track_id { // we can use the current decoder. Ensure it's at the correct position. if Self::position_ms_to_pcm(position_ms) != *stream_position_pcm { stream_loader_controller.set_random_access_mode(); @@ -1173,29 +1183,35 @@ impl PlayerInternal { let old_state = mem::replace(&mut self.state, PlayerState::Invalid); if let PlayerState::Playing { - track_meta_data, stream_position_pcm, decoder, stream_loader_controller, + bytes_per_second, + duration_ms, + normalisation_factor, .. } | PlayerState::Paused { - track_meta_data, stream_position_pcm, decoder, stream_loader_controller, + bytes_per_second, + duration_ms, + normalisation_factor, .. } = old_state { let loaded_track = PlayerLoadedTrackData { - track_meta_data, decoder, + normalisation_factor, stream_loader_controller, + bytes_per_second, + duration_ms, stream_position_pcm, }; self.preload = PlayerPreload::None; - self.start_playback(play_request_id, loaded_track, play); + self.start_playback(track_id, play_request_id, loaded_track, play); if let PlayerState::Invalid = self.state { panic!("start_playback() hasn't set a valid player state."); @@ -1210,17 +1226,17 @@ impl PlayerInternal { // Check if the requested track has been preloaded already. If so use the preloaded data. if let PlayerPreload::Ready { - loaded_track: - PlayerLoadedTrackData { - ref track_meta_data, - .. - }, + track_id: loaded_track_id, .. } = self.preload { - if track_id == track_meta_data.track_id { + if track_id == loaded_track_id { let preload = std::mem::replace(&mut self.preload, PlayerPreload::None); - if let PlayerPreload::Ready { mut loaded_track } = preload { + if let PlayerPreload::Ready { + track_id, + mut loaded_track, + } = preload + { if Self::position_ms_to_pcm(position_ms) != loaded_track.stream_position_pcm { loaded_track .stream_loader_controller @@ -1228,7 +1244,7 @@ impl PlayerInternal { let _ = loaded_track.decoder.seek(position_ms as i64); // This may be blocking loaded_track.stream_loader_controller.set_stream_mode(); } - self.start_playback(play_request_id, loaded_track, play); + self.start_playback(track_id, play_request_id, loaded_track, play); return; } else { unreachable!(); @@ -1293,15 +1309,7 @@ impl PlayerInternal { .. } | PlayerPreload::Ready { - loaded_track: - PlayerLoadedTrackData { - track_meta_data: - TrackMetaData { - track_id: currently_loading, - .. - }, - .. - }, + track_id: currently_loading, .. } = self.preload { @@ -1315,23 +1323,19 @@ impl PlayerInternal { } if let PlayerState::Playing { - ref track_meta_data, + track_id: current_track_id, .. } | PlayerState::Paused { - ref track_meta_data, + track_id: current_track_id, .. } | PlayerState::EndOfTrack { - loaded_track: - PlayerLoadedTrackData { - ref track_meta_data, - .. - }, + track_id: current_track_id, .. } = self.state { - if track_meta_data.track_id == track_id { + if current_track_id == track_id { // we already have the requested track loaded. preload_track = false; } @@ -1378,32 +1382,34 @@ impl PlayerInternal { self.preload_data_before_playback(); if let PlayerState::Playing { - ref track_meta_data, + track_id, play_request_id, ref mut reported_nominal_start_time, + duration_ms, .. } = self.state { *reported_nominal_start_time = Some(Instant::now() - Duration::from_millis(position_ms as u64)); - let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::Playing { - track_meta_data, + track_id, play_request_id, position_ms, + duration_ms, }); } if let PlayerState::Paused { - ref track_meta_data, + track_id, play_request_id, + duration_ms, .. } = self.state { - let track_meta_data = track_meta_data.clone(); self.send_event(PlayerEvent::Paused { - track_meta_data, + track_id, play_request_id, position_ms, + duration_ms, }); } } @@ -1480,7 +1486,7 @@ impl PlayerInternal { fn preload_data_before_playback(&mut self) { if let PlayerState::Playing { - ref track_meta_data, + bytes_per_second, ref mut stream_loader_controller, .. } = self.state @@ -1489,9 +1495,8 @@ impl PlayerInternal { let request_data_length = max( (READ_AHEAD_DURING_PLAYBACK_ROUNDTRIPS * (0.001 * stream_loader_controller.ping_time_ms() as f64) - * track_meta_data.bytes_per_second as f64) as usize, - (READ_AHEAD_DURING_PLAYBACK_SECONDS * track_meta_data.bytes_per_second as f64) - as usize, + * bytes_per_second as f64) as usize, + (READ_AHEAD_DURING_PLAYBACK_SECONDS * bytes_per_second as f64) as usize, ); stream_loader_controller.fetch_next(request_data_length); @@ -1499,9 +1504,8 @@ impl PlayerInternal { let wait_for_data_length = max( (READ_AHEAD_BEFORE_PLAYBACK_ROUNDTRIPS * (0.001 * stream_loader_controller.ping_time_ms() as f64) - * track_meta_data.bytes_per_second as f64) as usize, - (READ_AHEAD_BEFORE_PLAYBACK_SECONDS * track_meta_data.bytes_per_second as f64) - as usize, + * bytes_per_second as f64) as usize, + (READ_AHEAD_BEFORE_PLAYBACK_SECONDS * bytes_per_second as f64) as usize, ); stream_loader_controller.fetch_next_blocking(wait_for_data_length); } diff --git a/src/player_event_handler.rs b/src/player_event_handler.rs index 4809fc22..f2ac0c62 100644 --- a/src/player_event_handler.rs +++ b/src/player_event_handler.rs @@ -1,5 +1,4 @@ use librespot::playback::player::PlayerEvent; -use librespot_playback::player::TrackMetaData; use log::info; use std::collections::HashMap; use std::io; @@ -15,12 +14,6 @@ fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result, track_meta_data: TrackMetaData) { - env_vars.insert("TRACK_ID", track_meta_data.track_id.to_base62()); - env_vars.insert("DURATION_MS", track_meta_data.duration_ms.to_string()); - env_vars.insert("TRACK_TITLE", track_meta_data.title); -} - pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> Option> { let mut env_vars = HashMap::new(); match event { @@ -41,21 +34,25 @@ pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> Option { env_vars.insert("PLAYER_EVENT", "playing".to_string()); - add_meta_data_to_env_vars(&mut env_vars, track_meta_data); + env_vars.insert("TRACK_ID", track_id.to_base62()); + env_vars.insert("DURATION_MS", duration_ms.to_string()); env_vars.insert("POSITION_MS", position_ms.to_string()); } PlayerEvent::Paused { - track_meta_data, + track_id, + duration_ms, position_ms, .. } => { env_vars.insert("PLAYER_EVENT", "paused".to_string()); - add_meta_data_to_env_vars(&mut env_vars, track_meta_data); + env_vars.insert("TRACK_ID", track_id.to_base62()); + env_vars.insert("DURATION_MS", duration_ms.to_string()); env_vars.insert("POSITION_MS", position_ms.to_string()); } PlayerEvent::VolumeSet { volume } => { From 98e69ab0c43f435cdc355c5ddec09b18f3ad6318 Mon Sep 17 00:00:00 2001 From: ashthespy Date: Sat, 9 May 2020 16:33:06 +0200 Subject: [PATCH 4/6] Fetch context for Spotify Collection types as well Liked songs for example --- connect/src/spirc.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 453327c5..77785e3c 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -917,7 +917,9 @@ impl SpircTask { ); let context_uri = self.state.get_context_uri().to_owned(); if (context_uri.starts_with("spotify:station:") - || context_uri.starts_with("spotify:dailymix:")) + || context_uri.starts_with("spotify:dailymix:") + // spotify:user:xxx:collection + || context_uri.starts_with(&format!("spotify:user:{}:collection",self.session.username()))) && ((self.state.get_track().len() as u32) - new_index) < CONTEXT_FETCH_THRESHOLD { self.context_fut = self.resolve_station(&context_uri); From e275f0a80d72c9414308589e6a54ffe11ab61dc6 Mon Sep 17 00:00:00 2001 From: Will Stott Date: Wed, 13 May 2020 22:04:42 +0100 Subject: [PATCH 5/6] Bump libmdns to 0.2.6 (fixes #478) (#479) * Bump libmdns to 0.2.6 (fixes #478) * Update Cargo.lock --- Cargo.lock | 20 ++++++++++---------- connect/Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cfa63a12..e2ad8883 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,7 +585,7 @@ dependencies = [ [[package]] name = "hostname" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", @@ -752,18 +752,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libmdns" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hostname 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -834,7 +834,7 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", - "libmdns 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libmdns 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "librespot-core 0.1.1", "librespot-playback 0.1.1", "librespot-protocol 0.1.1", @@ -1069,7 +1069,7 @@ dependencies = [ [[package]] name = "multimap" -version = "0.4.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2391,7 +2391,7 @@ dependencies = [ "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -"checksum hostname 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc5260e6c63877196b6fca5a7fb4eaff751134045ad3415716192baa36f5b9a0" +"checksum hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" @@ -2409,7 +2409,7 @@ dependencies = [ "checksum libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd38073de8f7965d0c17d30546d4bb6da311ab428d1c7a3fc71dff7f9d4979b9" "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" "checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" -"checksum libmdns 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf720e60dd4443fc6694f2791974061b38f9f332c2f30796fa7c3ac66f367f8" +"checksum libmdns 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "966e0f9cc15be41e9dbfcd74fd9c04cf69d3c0ec43fc56aa28f5e4da4e545c38" "checksum libpulse-sys 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9bb11b06faf883500c1b625cf4453e6c7737e9df9c7ba01df3f84b22b083e4ac" "checksum librespot-tremor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b155a7dc4e4d272e01c37a1b85c1ee1bee7f04980ad4a7784c1a6e0f2de5929b" "checksum linear-map 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee" @@ -2427,7 +2427,7 @@ dependencies = [ "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" -"checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" +"checksum multimap 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" "checksum nalgebra 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e12856109b5cb8e2934b5e45e4624839416e1c6c1f7d286711a7a66b79db29d" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32" diff --git a/connect/Cargo.toml b/connect/Cargo.toml index 67bce1eb..469ee85e 100644 --- a/connect/Cargo.toml +++ b/connect/Cargo.toml @@ -35,7 +35,7 @@ aes-ctr = "0.3" block-modes = "0.3" dns-sd = { version = "0.1.3", optional = true } -libmdns = { version = "0.2.5", optional = true } +libmdns = { version = "0.2.6", optional = true } [features] default = ["libmdns"] From e8ec5feb2260e9d2e3b8bfc927cc5211d626e015 Mon Sep 17 00:00:00 2001 From: kaymes Date: Thu, 28 May 2020 03:51:56 +1000 Subject: [PATCH 6/6] Don't send kPlayStatusLoading. (#483) fixes #461 --- connect/src/spirc.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 77785e3c..b4c657f7 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -1191,10 +1191,11 @@ impl SpircTask { self.play_request_id = Some(self.player.load(track, start_playing, position_ms)); self.update_state_position(position_ms); - self.state.set_status(PlayStatus::kPlayStatusLoading); if start_playing { + self.state.set_status(PlayStatus::kPlayStatusPlay); self.play_status = SpircPlayStatus::LoadingPlay { position_ms }; } else { + self.state.set_status(PlayStatus::kPlayStatusPause); self.play_status = SpircPlayStatus::LoadingPause { position_ms }; } }