Fix playback position timing and stabilize PREV seek

This commit is contained in:
joren
2026-03-31 21:55:42 +02:00
parent 6296acc6dd
commit bb362686b4
2 changed files with 117 additions and 18 deletions

View File

@@ -851,6 +851,7 @@ async fn run_connection(
let mut last_play_command_at: std::time::Instant = std::time::Instant::now();
let mut has_seen_position_progress = false; // true once we've seen pos > 0 after a Play
let mut track_ended = false; // true when player finishes track naturally
let mut ignore_nonzero_seek_until: Option<std::time::Instant> = None;
// Helper macro: send a state update
macro_rules! send_state {
@@ -953,8 +954,19 @@ async fn run_connection(
let target_pos = requested_pos.unwrap_or(0);
let status = player.status();
let current_player_pos = status.position_ms;
let should_seek = target_pos == 0
let mut should_seek = target_pos == 0
|| target_pos.abs_diff(current_player_pos) > 350;
let suppress_nonzero_seek = target_pos > 0
&& ignore_nonzero_seek_until
.map(|deadline| std::time::Instant::now() < deadline)
.unwrap_or(false);
if suppress_nonzero_seek {
should_seek = false;
info!(
"[STATE] Ignoring non-zero seek {}ms during settle window",
target_pos
);
}
info!(
"[STATE] seek-only command: target={}ms local={}ms state={:?} track={} should_seek={}",
@@ -972,6 +984,12 @@ async fn run_connection(
);
player.send(PlayerCommand::Seek(target_pos));
track_ended = false;
if target_pos == 0 {
ignore_nonzero_seek_until = Some(
std::time::Instant::now()
+ std::time::Duration::from_secs(2),
);
}
}
current_position_ms = target_pos;
@@ -998,6 +1016,7 @@ async fn run_connection(
last_play_command_at = std::time::Instant::now();
has_seen_position_progress = false;
track_ended = false;
ignore_nonzero_seek_until = None;
send_state!(ws_tx, msg_id);
let track_id_str = track.track_id.to_string();
@@ -1079,8 +1098,19 @@ async fn run_connection(
let requested = requested_pos.unwrap_or(0);
let status = player.status();
let local = status.position_ms;
let should_seek = requested == 0
let mut should_seek = requested == 0
|| requested.abs_diff(local) > 350;
let suppress_nonzero_seek = requested > 0
&& ignore_nonzero_seek_until
.map(|deadline| std::time::Instant::now() < deadline)
.unwrap_or(false);
if suppress_nonzero_seek {
should_seek = false;
info!(
"[STATE] Ignoring non-zero position control {}ms during settle window",
requested
);
}
info!(
"[STATE] position-control command: playing_state={:?} target={}ms local={}ms state={:?} track={} should_seek={}",
playing_state,
@@ -1098,6 +1128,12 @@ async fn run_connection(
);
player.send(PlayerCommand::Seek(requested));
track_ended = false;
if requested == 0 {
ignore_nonzero_seek_until = Some(
std::time::Instant::now()
+ std::time::Duration::from_secs(2),
);
}
}
current_position_ms = requested;
} else if !loaded_new_track && !is_pause {