feat: live stats/uptime card in Settings + LIVE pill (#18) - #30
Merged
Conversation
The broadcast computed BroadcastNetworkHealth (queue, zero-output, target bitrate) and the ABR's effective fps/bitrate internally but never surfaced them — the controller exposed only isLive/errorMessage/thermalNotice. Plumb the telemetry through the @observable controller and display it: - StreamCore: new pure LiveStats value type (bitRate, frameRate, queueBytes, zeroOutputSeconds) with an uplink-health classification (Good/Fair/Congested) and compact bitrate/queue/uptime formatting. Unit-tested (health boundaries + formatting). - Publishers: statsSnapshot() on the Publisher protocol, implemented by RTMPPublisher + SessionPublisher from the ABR's healthSnapshot() + a new currentFrameRate() (effective fps folding in the congestion + thermal caps). Returns nil unless actively publishing, so the HUD clears to "—" during connect/reconnect instead of freezing on stale telemetry. - ScreenCaptureController: @observable liveStats + broadcastStartedAt, fed by a ~1s poll that starts on go-live and tears down on every path (all funnel through stopCapture). Writes snapshots through — including the reconnect nil — with an equality guard and a post-await cancel check. - Settings: a live stats/uptime card atop the launcher while broadcasting (fixed per-tick height so the content-sized drawer never springs), showing uptime, bitrate (target), effective fps, uplink health, and the thermal notice; per-metric VoiceOver labels. - ContentView: a persistent, non-interactive LIVE pill + elapsed timer overlay while live. fps/bitrate are the encoder's applied ABR targets, not measured throughput — measured fps/dropped-frame telemetry depends on M8 (not yet built). Built via an understand/design + adversarial-review multi-agent workflow; the review caught and this fixes a reconnect-staleness bug where the HUD would freeze on last-good values while the stream was actually down. StreamCore: 69 tests pass. Full app builds against the iOS 27 SDK. fixes #18 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Surfaces the live broadcast telemetry that was computed internally but never exposed past
isLive/errorMessage.What's new
LiveStats(StreamCore, unit-tested): telemetry value type with an uplink-health classification (Good/Fair/Congested) + compact bitrate/queue/uptime formatting.statsSnapshot()on thePublisherprotocol + both actors, built from the ABR'shealthSnapshot()and a newcurrentFrameRate()(effective fps after congestion/thermal caps). Returnsnilwhile not publishing so the HUD clears to—during connect/reconnect.ScreenCaptureController:@Observable liveStats+broadcastStartedAt, fed by a ~1s poll started on go-live and torn down on every path (all funnel throughstopCapture).fps/bitrate are the encoder's applied ABR targets, not measured throughput — measured fps/dropped-frame telemetry depends on M8 (not yet built).
Process
Built with an understand/design multi-agent workflow, then an adversarial review workflow that caught a reconnect-staleness bug (the HUD froze on last-good values while the stream was down) — fixed here by writing the reconnect
nilthrough.Verification
LiveStatshealth + formatting suites)fixes #18
🤖 Generated with Claude Code