diag(flutter): surface player errors + state transitions
Tap→audio measured at ~370ms — that path's fast. Real symptom: a few seconds of audio, then silence with no event surfaced to Flutter. ExoPlayer is failing/completing somewhere and we have no log to act on. Three changes, all log-only: - Add onError to playbackEventStream so stream failures (404, range- request bugs, decoder errors, network drops) print instead of silently halting playback. - Subscribe to playerStateStream and log playing + processingState on every transition. Silent stops will now show as a state shift to completed / idle / buffering with no resumption. - Subscribe to processingStateStream separately to catch fine-grained state transitions ExoPlayer reports between source advances. After hot-restart, tap-then-go-quiet should produce a sequence we can read — most likely either "processingState=completed" partway through (server returning premature EOS or wrong Content-Length) or a thrown error from ExoPlayer's source-loading path.
This commit is contained in:
@@ -12,7 +12,16 @@ import 'album_cover_cache.dart';
|
||||
|
||||
class MinstrelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
||||
MinstrelAudioHandler() {
|
||||
_player.playbackEventStream.listen(_broadcastState);
|
||||
_player.playbackEventStream.listen(
|
||||
_broadcastState,
|
||||
// ExoPlayer surfaces stream errors (404, premature EOS, decoder
|
||||
// failure, network drop) here. Without an error sink, the
|
||||
// player just goes quiet — exactly the "starts then stops"
|
||||
// symptom we hit.
|
||||
onError: (Object e, StackTrace st) {
|
||||
debugPrint('audio_handler: playbackEventStream error: $e\n$st');
|
||||
},
|
||||
);
|
||||
_player.currentIndexStream.listen(_onCurrentIndexChanged);
|
||||
// Re-broadcast on shuffle/repeat changes so the PlaybackState's
|
||||
// shuffleMode + repeatMode fields stay current for UI subscribers.
|
||||
@@ -24,6 +33,15 @@ class MinstrelAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandl
|
||||
// the index and the eviction loop can't reclaim them.
|
||||
_player.bufferedPositionStream
|
||||
.listen((_) => unawaited(_maybeRegisterStreamCache()));
|
||||
// Diagnostic: log every player-state transition so silent stops
|
||||
// surface as something we can read in the log.
|
||||
_player.playerStateStream.listen((s) {
|
||||
debugPrint(
|
||||
'audio_handler: state playing=${s.playing} processing=${s.processingState}');
|
||||
});
|
||||
_player.processingStateStream.listen((ps) {
|
||||
debugPrint('audio_handler: processingState=$ps');
|
||||
});
|
||||
}
|
||||
|
||||
final AudioPlayer _player = AudioPlayer();
|
||||
|
||||
Reference in New Issue
Block a user