---
name: unspooled-tv-development
description: Develop the Unspooled Android TV app (Debrid streaming client) — build, focus infrastructure, Debrid integration, UI components.
version: 1.15.0
metadata:
  hermes:
    requires_toolsets: [terminal, file]
    tags: [android, kotlin, compose-for-tv, debrid, unspooled]
    related_skills: [android-project-build, tv-app-build]
---
# Unspooled Tv Development
unspooled-tv-development
## Sections
- Overview
- Build & Verify
- V5 Focus Graph Rules (NON-NEGOTIABLE)
- Key Architecture Files
- Catalog Architecture (HYBRID — Native TMDB + Manifest-Driven Addons)
- Debrid Connection Flow
- ExoPlayer / Media3 HTTP Auth (Debrid Token Injection)
- TMDB API Key Resolution Chain
- BuildConfig Secrets & Hardcoded Values
- Backend/Scraper Wiring Audit
- APK-Native Torrent Scraper Migration
- QR Code & Addon Config Worker
- Debrid-Specific Components Created
- UI Library Stack
- Theme & Color System
- Spacing & Layout Audit (updated 2026-06-03)
- Dependencies
- Focus Audit Methodology
- Pitfalls
- Stremio Addon Serialization Quirks
## APK-Native Embed Source Provider

Free embed sources (MultiEmbed, VidSrc, 2Embed, EmbedSu, VidBinge) are generated locally via `EmbeddedEmbedSourceProvider` — always available, no debrid needed. Dual-track `ProviderRegistry`: embed sources always returned, debrid scrapers gated by connection.

### Critical Rules

1. **Dual-track ProviderRegistry.** `alwaysAvailable` (embed sources) runs regardless of debrid state. `debridRequired` (torrent scrapers) only when debrid is connected. Both merge in `enabledProviders()`.
2. **NO external API dependencies for embed URLs.** The embed provider parses IDs inline (`tt...` → IMDB, `tmdb:N`/`numeric` → TMDB). DO NOT use `ScrapeContextResolver` or TMDB — embed URLs only need raw IDs. TMDB dependency causes silent zero-source failures.
3. **`url = null` for embed sources.** Embed page URLs (multiembed.mov, vidsrc.to, etc.) are web pages, not video streams. Setting them as `Stream.url` causes `UnrecognizedInputFormatException` in ExoPlayer. Store the embed URL in `description` with `embed://` prefix.
4. **Playback requires server proxy.** The embed URL is resolved to a direct video stream via `NEXSTREAM_SCRAPER_URL/api/embed/proxy?url=EMBED_URL`. Without the server, embed sources are informational only.
5. **Auto-play MUST skip embed sources.** `ResolvePlaybackSourceUseCase` picks the best playable stream. Embed sources have `url = null` so `bestStream.url ?: bestStream.debridUrl` returns null → playback fails. Filter to `infoHash != null || url != null || debridUrl != null` before selecting.
6. **`notWebReady` is defined but UNCHECKED.** `StreamBehaviorHints.notWebReady` exists on the model but no code in the app reads it. Any new UI code for embed source selection should check this flag before attempting playback. It's a gap, not a feature.
7. **Port pitfall: Docker vs standalone.** The old Docker nexstream-scraper used `HTTPS_PORT=3443` and `https://`. The standalone ultimate-scraper uses `PORT=3091` and `http://`. `NEXSTREAM_SCRAPER_URL` in `local.properties` must match the active server — `http://192.168.1.50:3091`.

### Files

- `data/provider/embed/EmbeddedEmbedSourceProvider.kt` — embed source generation
- `data/provider/ProviderRegistry.kt` — dual-track registration
- `domain/usecase/ResolvePlaybackSourceUseCase.kt` — auto-play skips embed sources
- See `references/apk-native-embed-source-provider.md` for full details.

## Build & Verify

## References (40)
Detail has been moved to reference files in `references/`.
Load a specific reference file for detailed guidance.

Key recent references:
- `references/apk-native-torrent-scraper-migration.md` — APK-native torrent scraper architecture: embedded provider contract, TPB/BitSearch/Nyaa/1337x split, DebridRouter wiring, verification, and pitfalls.
- `references/apk-native-embed-source-provider.md` — APK-native free embed source provider: architecture, embed sources, ProviderRegistry dual-track, UI integration, and pitfalls.

## Triggers
- Load this skill when working on relevant architecture/project tasks.
- For specific subtasks, load only the relevant `references/<file>.md`.
