Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,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

Expand Down
3 changes: 3 additions & 0 deletions playback/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ 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 informing about playback position
Comment thread
fragsalat marked this conversation as resolved.
Outdated
pub position_update_interval: Option<Duration>,
}

impl Default for PlayerConfig {
Expand All @@ -156,6 +158,7 @@ impl Default for PlayerConfig {
normalisation_knee_db: 5.0,
passthrough: false,
ditherer: Some(mk_ditherer::<TriangularDitherer>),
position_update_interval: None,
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions playback/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -195,6 +196,12 @@ pub enum PlayerEvent {
track_id: SpotifyId,
position_ms: u32,
},
// Will be sent periodically while playing the track to inform about the current playback position
Comment thread
fragsalat marked this conversation as resolved.
Outdated
PositionChanged {
play_request_id: u64,
track_id: SpotifyId,
position_ms: u32,
},
Seeked {
play_request_id: u64,
track_id: SpotifyId,
Expand Down Expand Up @@ -481,6 +488,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.
Expand Down Expand Up @@ -1340,6 +1348,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);
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1796,6 +1796,7 @@ fn get_setup() -> Setup {
normalisation_release_cf,
normalisation_knee_db,
ditherer,
position_update_interval: None,
Comment thread
photovoltex marked this conversation as resolved.
}
};

Expand Down
14 changes: 14 additions & 0 deletions src/player_event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,20 @@ impl EventHandler {
env_vars.insert("POSITION_MS", position_ms.to_string());
}
},
PlayerEvent::PositionChanged {
track_id,
position_ms,
..
} => match track_id.to_base62() {
Err(e) => {
warn!("PlayerEvent::PositionChanged: Invalid track id: {}", e)
}
Ok(id) => {
env_vars.insert("PLAYER_EVENT", "position_changed".to_string());
env_vars.insert("TRACK_ID", id);
env_vars.insert("POSITION_MS", position_ms.to_string());
}
},
PlayerEvent::SessionConnected {
connection_id,
user_name,
Expand Down