EXStreamTV creates custom live TV channels from online sources (YouTube, Archive.org) and local media (Plex, Jellyfin, Emby, local folders). Plex DVR treats it as an HDHomeRun tuner — discover, add, and tune your channels like a physical device.
- Streams YouTube and Archive.org without downloading
- Pulls content from Plex, Jellyfin, Emby, and local folders
- Schedules channels with block scheduling, templates, and filler
- Emulates HDHomeRun so Plex DVR can discover and tune channels
- Provides M3U/EPG for IPTV players and a web interface
Plex discovers EXStreamTV as an HDHomeRun device on your network. After adding the DVR, you see your custom channels in the lineup. Tuning a channel starts live streaming; multiple clients can share the same stream.
See Platform Guide for how discovery, lineup, and tuning work.
- GitHub Wiki — full guides (Mermaid, screenshots). Source tree:
EXStreamTV.wiki/in this repo; refresh withpython scripts/sync_docs_to_wiki.py --wiki-dir EXStreamTV.wikiand push the wiki remote (seedocs/WIKI_UPLOAD.md,scripts/push_wiki.sh). - Platform Guide and docs/README.md for repo-local navigation.
Clients (Plex, IPTV, Web) → REST / M3U / HDHomeRun API → SessionManager → ChannelManager
→ ProcessPoolManager (FFmpeg) → StreamThrottler → Live MPEG-TS
Restarts are bounded by a global throttle (10 per 60s), per-channel cooldown (30s), and a per-channel circuit breaker. The ProcessPoolManager is the sole gatekeeper for FFmpeg process spawning.
See Platform Guide for full architecture and diagrams.
- HDHomeRun Emulation — Plex, Emby, Jellyfin DVR support
- Hardware Transcoding — NVENC, QSV, VAAPI, VideoToolbox, AMF
- Advanced Scheduling — Time slots, balance scheduling, filler
- AI Agent — Bounded diagnostic and remediation loop (optional)
- macOS Menu Bar App — Native app with onboarding wizard
- Session Management & Throttling — Tunarr/dizqueTV-style delivery
| Area | Key Flags | Default |
|---|---|---|
| AI Agent | ai_agent.bounded_agent_enabled |
false |
| Metadata Self-Resolution | ai_agent.metadata_self_resolution_enabled |
false |
| HDHomeRun | hdhomerun.enabled |
true |
| Stream Throttler | stream_throttler.enabled |
true |
See Feature Flags for full reference.
- Bounded restarts — Throttle, cooldown, and circuit breaker prevent restart storms
- Containment mode — AI agent stops when restart velocity or pool pressure is high
- Confidence gating — Metadata tools require minimum confidence before running
- No unbounded loops — Agent loop capped at 3 steps; no tool-from-tool
- Automatic shutdown — Stops after 3 consecutive metadata tool failures
See Platform Guide for details.
cd EXStreamTV
./scripts/install_macos.sh
./start.shcd EXStreamTVApp
swift build -c release
cp -r .build/release/EXStreamTVApp.app /Applications/Launch the app and follow the onboarding wizard.
cd containers/docker
docker-compose up -dGet a free Groq API key at console.groq.com for AI-assisted channel creation.
Access the web interface at http://localhost:8411
- Python: 3.10 or higher
- FFmpeg: With hardware acceleration support
- Network: Internet for online streaming sources
| Document | Description |
|---|---|
| Platform Guide | Full architecture, streaming, HDHomeRun, AI, observability |
| Installation | Installation steps |
| Quick Start | First channel in 10 minutes |
| AI Setup | AI configuration and bounded agent |
| Streaming Stability | Session management, throttling, error screens |
| API Reference | REST and IPTV endpoints |
| Observability | Prometheus metrics and alerting |
| Operational Guide | Diagnosis and verification |
| Symptom | Check |
|---|---|
| Plex "Could not Tune Channel" | DeviceID must be 8 hex chars. See config.yaml → hdhomerun.device_id. Re-add DVR in Plex after fixing. |
| Restarts blocked | Circuit breaker or storm throttle. Check /metrics for exstreamtv_circuit_breaker_state and restart rate. |
| No stream output | Channel health: last output > 180s. Check logs for ProcessPoolManager or FFmpeg errors. |
| High memory / FDs | Pool pressure. Reduce channels or increase ffmpeg.max_processes if system allows. |
| AI not acting | bounded_agent_enabled and metadata_self_resolution_enabled default to false. Check containment mode. |
See Operational Guide for detailed diagnosis.
EXStreamTV/
├── exstreamtv/ # Python backend
│ ├── api/ # REST, IPTV, HDHomeRun
│ ├── ai_agent/ # Bounded agent, tools, metadata resolution
│ ├── streaming/ # ChannelManager, ProcessPoolManager, CircuitBreaker
│ ├── scheduling/ # Playout engine
│ ├── ffmpeg/ # Transcoding pipeline
│ └── monitoring/ # Metrics, Prometheus
├── EXStreamTVApp/ # macOS menu bar app
├── frontend/ # Track B — Vite, React, Tailwind (dev proxy → API :8411)
├── containers/ # Docker
├── tests/ # pytest suite (`tests/unit` run in CI)
└── docs/ # Documentation
On push/PR to main, GitHub Actions runs scoped Ruff, pytest tests/unit, and npm run build in frontend/. Full tests/ may include integration cases that expect a running stack; run locally as needed.
python scripts/migrate_from_streamtv.py --source /path/to/streamtvpython scripts/migrate_from_ersatztv.py --source /path/to/ersatztvContributions are welcome. See CONTRIBUTING.md for guidelines.
MIT License — see LICENSE.
- StreamTV — Original Python streaming platform
- ErsatzTV — Scheduling and transcoding
- pseudotv-plex — Original inspiration
- dizquetv — Community fork inspiration