LiveStreamPlayerState
Pure description of what the live player should display right now. Computed from the latest LiveStream + LiveStreamPlayData snapshot plus the wall clock — no Android types, no coroutines, no mutable state. Lives here so we can unit-test the entire web-player decision tree without spinning up a player.
The branches mirror Bunny's web player:
Loading — first poll hasn't returned yet.
Offline — one of "Live stream not active", "Live stream ended", "Live stream error", with a reason tag so the UI can render the right copy.
Countdown — Scheduled stream with
enableCountdown == trueand a futurescheduledStartTime. UI ticks the timer locally; transition to playback is driven by the poll, not by the timer hitting zero.Trailer — Pre-stream trailer loop. Only when
preStreamTrailerVideoIdis set, the stream hasn't started (startedAt == null, status in {Created, Scheduled, Error}), and we've already resolved the trailer's HLS URL.LivePlay — Stream is Running. Play hlsUrl.
VodPlay — Stream is Ended or VodProcessing AND
recordVod == trueAND a playable URL is available.
Note that the state resolver does not read LiveStreamPlayData.videoPlaylistUrl directly — the caller is responsible for picking the right URL (videoPlaylistUrl > fallbackUrl > playbackUrlHls) and passing it in. This keeps the resolver decoupled from URL-priority bugs.
Inheritors
Types
Scheduled stream with a live countdown. Carries the title and the background to render behind the timer, mirroring the web player: when a pre-stream trailer is configured and resolved, trailerUrl is set and the overlay loops that video (muted) behind the countdown; otherwise it falls back to the blurred posterUrl thumbnail. The overlay shows "{title} will start in" above a large day/hour/minute/second timer in both cases.
Stream is Running. Play hlsUrl. dvrEnabled mirrors the stream's DVR setting: a DVR live stream shows a seekable timeline (+ jump-to-live); a non-DVR one hides the VOD-style timeline and time counter (its window-relative position is meaningless), leaving just the LIVE badge.
Stream isn't playing. posterUrl is the stream's thumbnail (when available), rendered behind the status message so the thumbnail stays visible before a live stream starts — mirroring the web player's poster.