v2.49.6 — Async-Exceptions abgesichert (kein Crash bei nicht-seekbaren Quellen)
## Fix (Code-Review Finding 4, MED) - PlayerService.play/playPause/pause/seek: try/catch mit MeloLogger — schützt ALLE Aufrufer (Buttons, Listener, System-Controls) - naechstes: Repeat-Titel-Zweig (seek+play) try/catch — Live-Streams ohne Seek-Unterstützung crashen nicht mehr - vorheriges: kompletter Ablauf try/catch (Seek-Pfad + Songwechsel) - NowPlayingScreen: Lyrics-Tap + Slider-Seek laufen über die abgesicherte seek()-Methode — keine unhandled async Exceptions aus Fire-and-Forget
This commit is contained in:
@@ -160,59 +160,91 @@ class PlayerService extends ChangeNotifier {
|
||||
|
||||
Future<void> playPause() async {
|
||||
if (_player == null) return;
|
||||
if (_p.playing) {
|
||||
await _p.pause();
|
||||
} else if (aktuellerSong != null) {
|
||||
await _p.play();
|
||||
try {
|
||||
if (_p.playing) {
|
||||
await _p.pause();
|
||||
} else if (aktuellerSong != null) {
|
||||
await _p.play();
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Play/Pause fehlgeschlagen: $e');
|
||||
MeloLogger().fehler('player_playpause', e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Explizit abspielen (kein Toggle) — für System-Controls (Bluetooth, etc.)
|
||||
Future<void> play() async {
|
||||
if (_player == null || aktuellerSong == null) return;
|
||||
await _p.play();
|
||||
try {
|
||||
await _p.play();
|
||||
} catch (e) {
|
||||
debugPrint('Play fehlgeschlagen: $e');
|
||||
MeloLogger().fehler('player_play', e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Explizit pausieren (kein Toggle) — für System-Controls (Bluetooth, etc.)
|
||||
Future<void> pause() async {
|
||||
if (_player == null) return;
|
||||
await _p.pause();
|
||||
try {
|
||||
await _p.pause();
|
||||
} catch (e) {
|
||||
debugPrint('Pause fehlgeschlagen: $e');
|
||||
MeloLogger().fehler('player_pause', e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Nur seeken ohne Reload der Quelle
|
||||
Future<void> seek(Duration position) async {
|
||||
if (_player == null) return;
|
||||
await _p.seek(position);
|
||||
try {
|
||||
await _p.seek(position);
|
||||
} catch (e) {
|
||||
// Live-Streams ohne Seek-Unterstützung werfen hier — nicht crashen
|
||||
debugPrint('Seek fehlgeschlagen: $e');
|
||||
MeloLogger().fehler('player_seek', e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> vorheriges() async {
|
||||
if (_player == null || aktuellerSong == null) return;
|
||||
final pos = _p.position;
|
||||
if (pos.inSeconds > 5) {
|
||||
await _p.seek(Duration.zero);
|
||||
return;
|
||||
}
|
||||
if (_zufallsmodus && _shuffleReihenfolge.isNotEmpty) {
|
||||
_shufflePos--;
|
||||
if (_shufflePos < 0) _shufflePos = 0;
|
||||
final idx = _shuffleReihenfolge[_shufflePos];
|
||||
if (idx >= 0 && idx < _warteschlange.length) {
|
||||
await spiele(_warteschlange[idx]);
|
||||
try {
|
||||
final pos = _p.position;
|
||||
if (pos.inSeconds > 5) {
|
||||
await _p.seek(Duration.zero);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
final neuerIndex = _aktuellerIndex - 1;
|
||||
if (neuerIndex >= 0) {
|
||||
await spiele(_warteschlange[neuerIndex]);
|
||||
if (_zufallsmodus && _shuffleReihenfolge.isNotEmpty) {
|
||||
_shufflePos--;
|
||||
if (_shufflePos < 0) _shufflePos = 0;
|
||||
final idx = _shuffleReihenfolge[_shufflePos];
|
||||
if (idx >= 0 && idx < _warteschlange.length) {
|
||||
await spiele(_warteschlange[idx]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final neuerIndex = _aktuellerIndex - 1;
|
||||
if (neuerIndex >= 0) {
|
||||
await spiele(_warteschlange[neuerIndex]);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Vorheriger Song fehlgeschlagen: $e');
|
||||
MeloLogger().fehler('player_vorheriges', e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> naechstes() async {
|
||||
if (_player == null || aktuellerSong == null) return;
|
||||
if (_wiederholmodus == Wiederholmodus.titel) {
|
||||
// Gleichen Song von vorn wiederholen
|
||||
await _p.seek(Duration.zero);
|
||||
await _p.play();
|
||||
// Gleichen Song von vorn wiederholen — seek/play können bei nicht
|
||||
// seekbaren Quellen (Live-Streams) werfen, daher abgesichert.
|
||||
try {
|
||||
await _p.seek(Duration.zero);
|
||||
await _p.play();
|
||||
} catch (e) {
|
||||
debugPrint('Repeat-Titel fehlgeschlagen: $e');
|
||||
MeloLogger().fehler('player_repeat_titel', e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
final idx = naechsterIndex();
|
||||
|
||||
Reference in New Issue
Block a user