mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-03 17:59:24 +02:00
Send playback position as player event (#1495)
* Send play progress as PlayerEvent::PositionChanged
* Replaced PlayerEvent::PositionChanged with set_progress_callback() method
* Revert "Replaced PlayerEvent::PositionChanged with set_progress_callback() method"
This reverts commit f26e3de07b
.
* Added opt-in config in PlayerConfig for progress event
* Added doc comments and set default position interval to 1sec for standalone
* Remove handling of PositionChanged in standalone binary
* Fixed wrong event handling
This commit is contained in:
parent
6bdc0eb312
commit
d12e1b8549
5 changed files with 34 additions and 0 deletions
|
@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- [connect] Add `volume_steps` to `ConnectConfig` (breaking)
|
||||
- [connect] Add and enforce rustdoc
|
||||
- [playback] Add `track` field to `PlayerEvent::RepeatChanged` (breaking)
|
||||
- [playback] Add `PlayerEvent::PositionChanged` event to notify about the current playback position
|
||||
- [core] Add `request_with_options` and `request_with_protobuf_and_options` to `SpClient`
|
||||
- [oauth] Add `OAuthClient` and `OAuthClientBuilder` structs to achieve a more customizable login process
|
||||
|
||||
|
|
|
@ -139,6 +139,9 @@ pub struct PlayerConfig {
|
|||
// pass function pointers so they can be lazily instantiated *after* spawning a thread
|
||||
// (thereby circumventing Send bounds that they might not satisfy)
|
||||
pub ditherer: Option<DithererBuilder>,
|
||||
/// Setting this will enable periodically sending events during playback informing about the playback position
|
||||
/// To consume the PlayerEvent::PositionChanged event, listen to events via `Player::get_player_event_channel()``
|
||||
pub position_update_interval: Option<Duration>,
|
||||
}
|
||||
|
||||
impl Default for PlayerConfig {
|
||||
|
@ -156,6 +159,7 @@ impl Default for PlayerConfig {
|
|||
normalisation_knee_db: 5.0,
|
||||
passthrough: false,
|
||||
ditherer: Some(mk_ditherer::<TriangularDitherer>),
|
||||
position_update_interval: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ struct PlayerInternal {
|
|||
|
||||
player_id: usize,
|
||||
play_request_id_generator: SeqGenerator<u64>,
|
||||
last_progress_update: Instant,
|
||||
}
|
||||
|
||||
static PLAYER_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||
|
@ -195,6 +196,14 @@ pub enum PlayerEvent {
|
|||
track_id: SpotifyId,
|
||||
position_ms: u32,
|
||||
},
|
||||
/// Requires `PlayerConfig::position_update_interval` to be set to Some.
|
||||
/// Once set this event will be sent periodically while playing the track to inform about the
|
||||
/// current playback position
|
||||
PositionChanged {
|
||||
play_request_id: u64,
|
||||
track_id: SpotifyId,
|
||||
position_ms: u32,
|
||||
},
|
||||
Seeked {
|
||||
play_request_id: u64,
|
||||
track_id: SpotifyId,
|
||||
|
@ -481,6 +490,7 @@ impl Player {
|
|||
|
||||
player_id,
|
||||
play_request_id_generator: SeqGenerator::new(0),
|
||||
last_progress_update: Instant::now(),
|
||||
};
|
||||
|
||||
// While PlayerInternal is written as a future, it still contains blocking code.
|
||||
|
@ -1340,6 +1350,22 @@ impl Future for PlayerInternal {
|
|||
position_ms: new_stream_position_ms,
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(interval) =
|
||||
self.config.position_update_interval
|
||||
{
|
||||
let last_progress_update_since_ms =
|
||||
now.duration_since(self.last_progress_update);
|
||||
|
||||
if last_progress_update_since_ms > interval {
|
||||
self.last_progress_update = now;
|
||||
self.send_event(PlayerEvent::PositionChanged {
|
||||
play_request_id,
|
||||
track_id,
|
||||
position_ms: new_stream_position_ms,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Skipping to next track, unable to decode samples for track <{:?}>: {:?}", track_id, e);
|
||||
|
|
|
@ -1818,6 +1818,7 @@ fn get_setup() -> Setup {
|
|||
normalisation_release_cf,
|
||||
normalisation_knee_db,
|
||||
ditherer,
|
||||
position_update_interval: None,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -243,6 +243,8 @@ impl EventHandler {
|
|||
);
|
||||
env_vars.insert("FILTER", filter.to_string());
|
||||
}
|
||||
// Ignore event irrelevant for standalone binary like PositionChanged
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if !env_vars.is_empty() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue