10 Commits

Author SHA1 Message Date
Trey t
da033cf12c Fix NSFW sheet scroll on iOS/iPad, clean up audio pin
- WerkoutNSFWSheet: wrap content in ScrollView + ViewThatFits(in: .horizontal)
  so iPad's narrow sheet width falls back to VStack and content scrolls.
- Tighten padding on compact layouts (38→24).
- Revert AAC-preference in pinAudioSelection (stream is all AAC, no Dolby).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 19:30:25 -05:00
Trey t
08ad702f9d Add AudioDiagnostics heartbeat logging
Adds [AUDIO]-prefixed logs to both single-stream and multi-stream players:
1 Hz heartbeat with rate/timeControl/mute/volume/bitrate/route, plus
immediate events on rate, isMuted, volume, currentItem, media selection,
access-log, error-log, and system audio route/interruption changes.

Grep Xcode console for `[AUDIO]` or `[AUDIO SYSTEM]` to isolate.

Also reverts the AAC-preference in pinAudioSelection: the
ballgame.treytartt.com master playlist is already all mp4a.40.2 stereo,
so the Dolby-DRC theory doesn't fit. Pin simply selects the default
audible option now.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:28:15 -05:00
Trey t
85a19fdd71 Fix mid-stream audio loudness jumps
Root cause: the quality upgrade path called replaceCurrentItem mid-stream,
which re-loaded the HLS master manifest and re-picked an audio rendition,
producing a perceived loudness jump 10-30s into playback. .moviePlayback
mode amplified this by re-initializing cinematic audio processing on each
variant change.

- Start streams directly at user's desiredResolution; remove
  scheduleQualityUpgrade, qualityUpgradeTask, and the 504p->best swap.
- Switch AVAudioSession mode from .moviePlayback to .default in both
  MultiStreamView and SingleStreamPlayerView.
- Pin the HLS audio rendition by selecting the default audible
  MediaSelectionGroup option on every new AVPlayerItem, preventing
  ABR from swapping channel layouts mid-stream.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:04:39 -05:00
Trey t
ba24c767a0 Improve stream quality: stop capping resolution, allow AVPlayer to ramp
SingleStream: pass preserveServerResolutionWhenBest=false so "best"
always reaches the server for a full multi-variant manifest. Increase
buffer to 8s and enable automaticallyWaitsToMinimizeStalling so AVPlayer
can measure bandwidth and select higher variants. Add quality monitor
that nudges AVPlayer if observed bandwidth far exceeds indicated bitrate.

MultiStream: remove broken URL-param resolution detection that falsely
skipped upgrades, log actual indicatedBitrate instead. Extend upgrade
check windows from [2,4,7]s to [2,4,7,15,30]s for slow-to-stabilize
streams.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 12:38:38 -05:00
Trey t
bf44a7b7eb Fix memory leaks, stale game data, and audio volume fluctuation
Memory: clean observers even during PiP, nil player on tile disappear,
track/cancel Werkout monitor tasks, add highlight player cleanup.
Data: add scenePhase-triggered reload on day change, unconditional
10-minute full schedule refresh, keep fast 60s score refresh for live games.
Audio: set mute state before playback starts, use consistent .moviePlayback
mode, add audio session interruption recovery handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 12:21:21 -05:00
Trey t
88308b46f5 Add game center, per-model shuffle, audio focus fixes, README, tests
- README.md with build/architecture overview
- Game Center screen with at-bat timeline, pitch sequence, spray chart,
  and strike zone component views
- VideoShuffle service: per-model bucketed random selection with
  no-back-to-back guarantee; replaces flat shuffle-bag approach
- Refresh JWT token for authenticated NSFW feed; add josie-hamming-2
  and dani-speegle-2 to the user list
- MultiStreamView audio focus: remove redundant isMuted writes during
  startStream and playNextWerkoutClip so audio stops ducking during
  clip transitions; gate AVAudioSession.setCategory(.playback) behind
  a one-shot flag
- GamesViewModel.attachPlayer: skip mute recalculation when the same
  player is re-attached (prevents toggle flicker on item replace)
- mlbTVOSTests target wired through project.yml with
  GENERATE_INFOPLIST_FILE; VideoShuffleTests covers groupByModel,
  pickRandomFromBuckets, real-distribution no-back-to-back invariant,
  and uniform model distribution over 6000 picks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:02:46 -05:00
Trey t
58e4c36963 Fix video autoplay reliability, add shuffle playback, refresh data on appear
- Remove cache expiry on video feed (fetch once, keep for session)
- Add retry logic (3 attempts with backoff) for autoplay resolution
- Replace random video selection with shuffle-bag (no repeats until all played)
- Reload games every time DashboardView appears
- Cache standings per day to avoid redundant fetches

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:49:54 -05:00
Trey t
fda809fd2f Add iOS/iPad target with platform-adaptive UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:30:28 -05:00
Trey t
127125ae1b Add Werkout channel playback and autoplay 2026-03-26 20:53:08 -05:00
Trey t
bae265b132 Initial commit 2026-03-26 15:37:31 -05:00