Files
minstrel/flutter_client/lib
bvandeusen 154626ae94 feat(player): stall watchdog + bounded retry + skip-to-cached (#66)
Reported: on poor coverage a track ends and the next (uncached) track
never starts — streams, hangs, no retry. Root cause: a buffering stall
emits NO error event so the onError path never fires and there was no
stall watchdog; even on a real error _handlePlaybackError immediately
skipped the literal-next (likely also-unreachable) source with no retry.

- _reconcileStallWatchdog: while playing+buffering, a 15s window; if
  buffered position hasn't advanced it's a dead stream → recover; if
  progressing, re-arm (slow-but-downloading is fine). Driven from
  _broadcastState like the idle/position reconcilers.
- _recoverPlayback unifies stall + onError: retry the SAME track once
  (skipToQueueItem rebuilds a fresh source/HTTP — a transient blip no
  longer loses it); on exhaustion, surface via the #58 SnackBar and
  skip to the next cached track, else pause (no thrashing through
  unreachable streams).
- per-track retry budget resets when a track reaches ready+playing.
- _handlePlaybackError now delegates into the unified path.

Core playback change — device-verify on a throttled connection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 14:14:25 -04:00
..