Skip to content

feat(player): richer stats for nerds on phone and TV - #34

Merged
JonahMMay merged 3 commits into
mainfrom
feat/android-stats-richer
Sep 30, 2026
Merged

JonahMMay merged 3 commits into
mainfrom
feat/android-stats-richer

Conversation

@JonahMMay

Copy link
Copy Markdown

Problem

The phone stats sheet and the TV HUD Stats pane list decoder and format facts, but nothing that explains a failure. There is no server plan or planner reason, no record of which audio track or stream is actually playing, and no player errors. prairie-smarttv added all of this in Silo-Server#116.

Solution

Both panels now show the same set, built from data the ViewModels already hold:

  • Plan: play method, v3 delivery, container and codecs on one line (e.g. Remux · server_remux_progressive · container=mp4 · video=hevc 3840x1600 hdr10 · audio=eac3), then the planner reason (decision trace, then degradation warnings, then the audio/Dolby Vision claim reason) and server transformations.
  • Audio track: ordinal, language, codec, channels and title.
  • Stream: the kind (HLS / DASH / Progressive / Local file) and the path of the URL actually mounted. Query strings, userinfo and token-like path segments are never displayed.
  • Quality preference, declared video bitrate (separate from the existing network "Estimated bandwidth"), audio channels, buffer ahead, rebuffers and startup time.
  • Recent player events: the last 8 Media3 analytics events (decoder init, format changes, buffering/ready/ended, dropped frames, underruns, load and player errors), stamped with wall-clock time. URLs in error text lose their query strings. Identical consecutive events collapse into one entry with a count, so a burst cannot push the error out of the window. The log survives finishPlayerStats, so a retry still shows why the previous attempt failed.

Where the code lives:

  • shared/.../playback/stats/StatsForNerds.kt (commonMain): the ring buffer, the redaction, the plan/track/quality/buffer formatting and the row builder, all pure. StatsForNerdsTest covers them for the Kover gate.
  • android-shared/.../PlayerStatsEvents.kt: maps Media3 events to log lines (PlayerStatsEventsTest). PlayerStatsSnapshot gains the declared bitrate, audio channels and the event log. The reducer stays pure; the ViewModels stamp events with the wall clock.
  • UI: PlaybackStatsSheet gets a playbackContext from PlayerOverlay. TvPlayerHud takes the mounted streamUrl and builds the same context from its selected audio and quality rows.

Live TV players still have no stats panel, the same as smarttv.

Validation

  • New unit tests: StatsForNerdsTest (:shared) and PlayerStatsEventsTest (android-shared). The existing reducer tests still apply; the reducer contract is unchanged.
  • Gradle build, tests and lint run in CI only (host memory limits); see checks.

Follow-up

AI disclosure: written by Claude Opus 5.5 (claude-opus-5-5[1m]) in Claude Code (Claude Agent SDK); no other AI tooling.

🤖 Generated with Claude Code

Bring the phone stats sheet and the TV HUD Stats pane to parity with
prairie-smarttv Silo-Server#116:

- Plan: play method, v3 delivery, container and codecs in one line,
  plus the planner's reason (decision trace, degradation warnings or the
  audio/DV claim reason) and server transformations.
- The selected audio track (ordinal, language, codec, channels, title).
- The stream actually mounted: kind (HLS/DASH/Progressive/Local file)
  and path only; query strings, userinfo and token-like segments are
  never shown.
- Quality preference, declared video bitrate, audio channels, buffer
  ahead, rebuffers and startup time.
- The last 8 player events (decoder init, format changes, state,
  dropped frames, underruns, load/player errors), wall-clock stamped,
  with URL queries stripped from error text. Identical consecutive
  events collapse with a repeat count so a burst cannot evict the
  error. The log survives finishPlayerStats so a retry still shows why
  the previous attempt failed.

Formatting, redaction and the ring buffer live in :shared
(playback/stats/StatsForNerds.kt) with commonTest coverage; the Media3
event mapping lives in android-shared with unit tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 31 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 26a0b06e-6e16-4382-89fb-bd6a102fd04a

📥 Commits

Reviewing files that changed from the base of the PR and between 996df85 and baafd69.

📒 Files selected for processing (11)
  • android-shared/src/androidMain/kotlin/org/prairieserver/prairie/common/player/PlayerStatsEvents.kt
  • android-shared/src/androidMain/kotlin/org/prairieserver/prairie/common/player/PlayerStatsSnapshot.kt
  • android-shared/src/androidUnitTest/kotlin/org/prairieserver/prairie/common/player/PlayerStatsEventsTest.kt
  • androidApp/src/androidMain/kotlin/org/prairieserver/prairie/android/ui/screens/player/PlaybackStatsSheet.kt
  • androidApp/src/androidMain/kotlin/org/prairieserver/prairie/android/ui/screens/player/PlayerOverlay.kt
  • androidApp/src/androidMain/kotlin/org/prairieserver/prairie/android/ui/screens/player/PlayerViewModel.kt
  • androidTvApp/src/androidMain/kotlin/org/prairieserver/prairie/tv/ui/screens/player/TvPlayerHud.kt
  • androidTvApp/src/androidMain/kotlin/org/prairieserver/prairie/tv/ui/screens/player/TvPlayerScreen.kt
  • androidTvApp/src/androidMain/kotlin/org/prairieserver/prairie/tv/ui/screens/player/TvPlayerViewModel.kt
  • shared/src/commonMain/kotlin/org/prairieserver/prairie/playback/stats/StatsForNerds.kt
  • shared/src/commonTest/kotlin/org/prairieserver/prairie/playback/stats/StatsForNerdsTest.kt
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

JonahMMay and others added 2 commits September 30, 2026 13:42
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@JonahMMay
JonahMMay merged commit 3dc9d6a into main Sep 30, 2026
8 of 9 checks passed
@JonahMMay
JonahMMay deleted the feat/android-stats-richer branch September 30, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant