fix(player): surface a persistent HTTP 503 at open instead of retrying forever

ffmpeg's reconnect loop deliberately retries 503 without bound (#1520), so a
server that keeps refusing the stream at open time left a silent black screen:
ExoPlayer fell back to MPV, MPV reconnected forever, and no error ever reached
the screen. A new open-phase watchdog arms on the first 503 seen before any
frame renders and, after 20s without one, synthesizes a server-http-503 error
that shows an actionable dialog. Mid-stream 503s and live TV keep their
existing ride-out paths.

close #1830
This commit is contained in:
edde746
2026-08-08 12:06:32 +02:00
parent f0debe2c32
commit e6be5f9fef
38 changed files with 321 additions and 12 deletions
+23
View File
@@ -152,6 +152,29 @@ Future<void> showMediaUnreadableDialog(BuildContext context) async {
);
}
/// Shows the server-side 503 modal: the server kept refusing to serve the
/// stream for the whole open-phase watchdog window, so the reconnect loop is
/// not going to start this playback (#1830).
Future<void> showServerBusyDialog(BuildContext context) async {
await showScopedDialog<void>(
context: context,
barrierDismissible: false,
builder: (ctx) => AlertDialog(
title: Text(t.messages.serverBusyTitle),
content: Text(t.messages.serverBusyBody),
actions: [
DialogActionButton(
autofocus: true,
onPressed: () => Navigator.of(ctx).pop(),
label: t.common.close,
isPrimary: true,
style: FilledButton.styleFrom(padding: _buttonPadding, shape: _buttonShape),
),
],
),
);
}
/// Shows a delete confirmation dialog.
/// Convenience wrapper around [showConfirmDialog] with destructive styling.
Future<bool> showDeleteConfirmation(