diff --git a/DeepDrftPublic.Client/Services/StreamingAudioPlayerService.cs b/DeepDrftPublic.Client/Services/StreamingAudioPlayerService.cs index d77b8da..44eeb25 100644 --- a/DeepDrftPublic.Client/Services/StreamingAudioPlayerService.cs +++ b/DeepDrftPublic.Client/Services/StreamingAudioPlayerService.cs @@ -327,7 +327,7 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS LoadProgress = 1.0; await NotifyStateChanged(); } - catch (OperationCanceledException) + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { // Cancellation is expected during track switch or seek — propagate cleanly. throw; @@ -432,7 +432,8 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS _streamingCancellation?.Cancel(); await DrainActiveStreamingTaskAsync(); _streamingCancellation?.Dispose(); - _streamingCancellation = new CancellationTokenSource(); + var seekCts = new CancellationTokenSource(); + _streamingCancellation = seekCts; try { @@ -444,7 +445,7 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS var mediaResult = await _trackMediaClient.GetTrackMedia( _currentTrackId, byteOffset, - cancellationToken: _streamingCancellation.Token); + cancellationToken: seekCts.Token); if (!mediaResult.Success || mediaResult.Value == null) { var technicalError = mediaResult.GetMessage() ?? "Failed to load audio from position"; @@ -473,16 +474,21 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS BufferedChunks = 0; // Stream audio from offset - _activeStreamingTask = StreamAudioWithEarlyPlayback(audio, _streamingCancellation.Token); + _activeStreamingTask = StreamAudioWithEarlyPlayback(audio, seekCts.Token); await _activeStreamingTask; IsSeekingBeyondBuffer = false; } - catch (OperationCanceledException) + catch (OperationCanceledException) when (seekCts.IsCancellationRequested) { - // Another seek or stop interrupted this one + // Another seek or stop interrupted this one. Only clear the flag if we are + // still the active seek — if _streamingCancellation has been replaced, a + // newer seek is in progress and owns the flag. _logger.LogDebug("Seek beyond buffer cancelled"); - IsSeekingBeyondBuffer = false; + if (ReferenceEquals(_streamingCancellation, seekCts)) + { + IsSeekingBeyondBuffer = false; + } } catch (Exception ex) {