# Embed vs Direct Playback Strategy

## Architecture Decision: Iframe-First Playback

When building a streaming web frontend that uses server-side scrapers, the playback architecture should be **iframe-first**:

```
User clicks source
       │
       ▼
┌──────────────────┐
│ LOAD IFRAME NOW  │◄── PRIMARY: Instant, browser handles Cloudflare/JS
│ (embed URL)      │
└──────┬───────────┘
       │
       ▼ (in background)
┌──────────────────┐
│ Try resolve to   │◄── SECONDARY: May fail due to Cloudflare
│ direct m3u8 URL  │
└──────┬───────────┘
       │
       ▼ if resolved
┌──────────────────┐
│ Show "Play Direct"│
│ button overlay   │
└──────────────────┘
```

## Why Iframe-First

| Aspect | Iframe embed | Direct m3u8 |
|---|---|---|
| Cloudflare bypass | ✅ Browser handles natively | ❌ Server-side blocked |
| Speed | ✅ Instant (browser loads embed) | ⏳ ~3-10s to resolve |
| Quality | ⚠️ Embed may have ads/limits | ✅ Full quality, no ads |
| Reliability | ✅ High (embed sites maintained) | ⚠️ Hosters change often |

## Frontend Implementation (hls.js)

For direct m3u8 playback, use hls.js with custom headers:

```js
const hls = new Hls({
    enableWorker: true,
    lowLatencyMode: true,
    xhrSetup: (xhr, url) => {
        if (headers.Referer) xhr.setRequestHeader('Referer', headers.Referer);
    }
});
hls.loadSource(url);
hls.attachMedia(videoElement);
```

## Edge Cases

- **IFrame blocked by X-Frame-Options**: Some embed sites block iframing. Detect with `window.postMessage` timeout, fallback to opening in new tab.
- **Mixed content**: If the site is HTTPS but embed URL is HTTP, the browser blocks it. Use the server's HLS proxy or a CORS proxy.
- **Multiple embeds**: Only one iframe/player should be active at a time. Destroy previous player before loading new one.
