# Playback Pipeline Audit — 2026-05-28

## Bugs Found & Fixed (PlayerManager.kt)

### BUG 1 (CRITICAL): Headers from PlaybackPlan silently dropped
`PlayerViewModel.playStream()` called `playerManager.play(url, seekToMs)` — never passed
`Plan.headers` (debrid proxy headers). Debrid streams requiring auth headers got 403s.
**Fix:** `play()` now accepts `headers: Map<String, String> = emptyMap()` parameter.

### BUG 2: Missing cross-protocol redirects on no-headers path
`rebuildAndPlay()` had `setAllowCrossProtocolRedirects(true)` only in the else branch.
No-headers path used `player.setMediaItem()` which relied on the factory from `createPlayer()`.
**Fix:** Both paths now create their own `DefaultHttpDataSource.Factory()` with
`.setAllowCrossProtocolRedirects(true)`.

### BUG 3: No AudioAttributes configured
ExoPlayer built without `AudioAttributes`. On Android TV, this means no proper audio routing
(surround, passthrough), no audio focus, potentially silent playback on some devices.
**Fix:** Added in `createPlayer()`:
```kotlin
val audioAttributes = AudioAttributes.Builder()
    .setUsage(C.USAGE_MEDIA)
    .setContentType(C.AUDIO_CONTENT_TYPE_MOVIE)
    .build()
setAudioAttributes(audioAttributes, true)
```

### BUG 4: No buffer/LoadControl tuning
Used ExoPlayer defaults (~12.5 MB / 30s max buffer). Debrid CDNs need more.
**Fix:** Added in `createPlayer()`:
```kotlin
val loadControl = DefaultLoadControl.Builder()
    .setTargetBufferBytes(100 * 1024 * 1024) // 100 MB
    .setBufferDurationsMs(DEFAULT_MIN, 70_000, DEFAULT_PLAYBACK, 5_000)
    .build()
```

## Remaining Work (separate sessions)

1. Switch from `DefaultHttpDataSource` to `OkHttpDataSource.Factory` — requires
   `media3-datasource-okhttp` dependency. NuvioTV uses this with `IPv4FirstDns`,
   header re-injection on cross-host redirects, trust-all SSL.

2. Configure preferred audio languages on `DefaultTrackSelector` from user prefs.

3. Frame rate matching (AFR) — `FrameRateUtils.matchFrameRateAndWait()` from NuvioTV
   probes display modes and matches video FPS to display refresh rate.

4. NuvioTV's `PlayerRuntimeController` has engine failover (ExoPlayer ↔ MPV),
   MIME-type pre-playback probing, and per-stream track preference memory.

## Fixed Files
- `PlayerManager.kt` — `createPlayer()`: AudioAttributes, LoadControl, cross-protocol redirects.
  `play()`: accepts headers parameter. `rebuildAndPlay()`: both paths use allowRedirects.
