Reconnect strategy: back off instead of retrying instantly after a stream drops #12
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
Channels regularly come up as the provider's "Stream Offline" still image. Leaving the channel and re-entering it once or twice usually fixes it.
Why it happens
The provider limits concurrent connections per subscription and does not free a session the moment the client disconnects. Two things make the app run straight into that window:
Server side (fixed separately): Dispatcharr's
channel_shutdown_delaywas0, so the upstream connection was torn down the instant the last viewer left, and re-entering immediately opened a brand-new one while the old session was still counted. Raised to 30 s, so returning within that window now reuses the existing connection instead of asking the provider for a second one.App side (this issue):
PlayerController.onPlayerError()retries twice with no delay at all —setMediaItem/prepare/playfire back to back. If the provider is briefly rate-limiting, all three attempts land inside the same blocked window and burn the retry budget in well under a second. Worse, the "Stream Offline" still image is valid video, so ExoPlayer reports no error and the retry logic never even runs.Suggested fix
Notes
The still image cannot be detected reliably from the client side (it decodes as normal video). The realistic levers are the connection reuse window on the server and the pacing described above.
Fixed in
dd612fc, shipped in v0.9.0 — on both sides.Server:
channel_shutdown_delaywas0, so Dispatcharr tore down the upstream connection the instant the last viewer left and opened a brand-new one on return, while the provider still counted the old session. Raised to 30 s, so returning within that window reuses the existing connection.App:
1 s / 3 s / 8 s(RETRY_DELAYS_MS) instead of three immediate attempts, scheduled on a handler and cancelled onplay()/stop()/release().reconnectingand the overlay shows "Verbindung wird wiederhergestellt…" instead of looking frozen.REENTRY_GRACE_MSinAppState.play()), which is exactly the window where the provider hands back its "Stream Offline" placeholder.Still true and unchanged: the placeholder itself is valid video, so it cannot be detected client-side. Per-channel failover streams in Dispatcharr remain the real cure for chronically flaky upstreams.