A minimal, self-hosted web interface for IPTV streams.
We built neTV because we couldn't find a clean, lightweight interface for Xtream IPTV services. Existing solutions were either bloated media centers or clunky apps that didn't work well across devices.
neTV is intentionally minimal. It does one thing: play your IPTV streams with a clean UI that works on desktop, tablet, mobile, and Chromecast.
We also prioritize keyboard navigation throughout (though still rough around the edges). The entire app is theoretically usable with just arrow keys, Enter, and Escape -- perfect for media PCs, HTPCs, or anyone who prefers keeping hands on the keyboard (like me).
This is a player only -- it does not provide any content. You must have your own IPTV subscription that provides Xtream Codes API access or M3U playlists. Users are responsible for ensuring they have legal rights to access any content through their IPTV providers.
- Live TV with EPG grid guide
- Movies & Series with metadata, seasons, episodes
- Chromecast support (HTTPS required)
- Closed captions with style customization
- Search across all content (supports regex)
- Favorites with drag-and-drop ordering
- Resume playback for VOD content
- Responsive - works on desktop, tablet, mobile
- Keyboard navigation - 10-foot UI friendly
Extensively optimized for minimal latency and CPU usage:
- Smart passthrough - h264+aac streams remux without re-encoding (zero CPU)
- Full GPU pipeline - NVDEC decode → NVENC/VAAPI encode, CPU stays idle
- Probe caching - Streams probed once, series episodes share probe data
- Interlace detection - Auto-deinterlaces OTA/cable, skips progressive
- Smart seeking - Reuses segments for backward seeks, only transcodes gaps
- Session recovery - VOD sessions survive restarts, resume where you left off
- HTTPS passthrough - Auto-proxies HTTP streams when behind HTTPS
Hardware transcoding is auto-detected. Check Settings to see available encoders.
- Intel/AMD (VAAPI): Works automatically if
/dev/driexists. - NVIDIA: Requires nvidia-container-toolkit:
docker compose --profile nvidia up -d - No GPU / VPS: If
/dev/dridoesn't exist, comment out thedevicessection indocker-compose.ymlor compose will fail to start
If you want a full-featured media center, you might be happier with:
- Jellyfin - Free, open-source media system
- Emby - Media server with IPTV support
- Plex - Popular media platform with live TV
These are excellent, mature projects with large communities. neTV exists for users who find them overkill and just want a simple IPTV player.
| neTV | nodecast-tv | Jellyfin | Emby | Plex | |
|---|---|---|---|---|---|
| Focus | IPTV | IPTV | General media | General media | General media |
| Xtream Codes | ✅ | ✅ | ❌ | ❌ | ❌ |
| M3U playlists | ✅ | ✅ | ✅ | ✅ | |
| XMLTV EPG | ✅ | ✅ | ✅ | ✅ | |
| Local media | ❌ | ❌ | ✅ | ✅ | ✅ |
| Live TV | ✅ | ✅ | ✅ | ✅ | ✅ |
| VOD (movies/series) | ✅ | ✅ | ✅ | ✅ | ✅ |
| DVR recording | ❌ | ❌ | ✅ | ✅ | |
| Catchup/timeshift | ❌ | ❌ | ❌ | ||
| Live rewind buffer | ✅ | ❌ | |||
| Resume playback | ✅ | ❌ | ✅ | ✅ | ✅ |
| Multi-user | ✅ | ✅ | ✅ | ✅ | ✅ |
| User roles | ✅ Granular | ✅ Granular | ✅ Granular | ||
| Stream limits | ✅ Per-user, per-source | ❌ | |||
| Library permissions | N/A | N/A | ✅ Per-library | ✅ Per-library | ✅ Per-library |
| Favorites | ✅ Drag-and-drop | ✅ | ✅ | ✅ | ✅ |
| Search | ✅ Regex | ✅ Basic | ✅ Basic | ✅ Basic | ✅ Basic |
| Video transcoding | ✅ | ❌ | ✅ | ✅ | ✅ |
| Audio transcoding | ✅ | ✅ | ✅ | ✅ | ✅ |
| Transcode only if needed | ✅ Auto mode | ❌ | |||
| NVENC | ✅ | ❌ | ✅ | ✅ | |
| VAAPI | ✅ | ❌ | ✅ | ✅ | |
| QSV | ✅ | ❌ | ✅ | ✅ | |
| Software fallback | ✅ | ❌ Browser | ✅ | ✅ | ✅ |
| Legacy GPU | ✅ Any | ❌ No (browser) | ✅ Any | ✅ Any | |
| ffprobe caching | ✅ Dynamic | ❌ None | |||
| Episode probe reuse | ✅ MRU | ❌ No | |||
| Session recovery | ✅ Yes | ❌ No | |||
| Auto deinterlace | ✅ Yes | ❌ No | |||
| Subtitles | ❌ No | ✅ Full | ✅ Full | ✅ Full | |
| Chromecast | ✅ Yes | ❌ No | ✅ Yes | ✅ Yes | ✅ Yes |
| Keyboard/remote | ✅ 10-foot UI | ✅ 10-foot UI | ✅ 10-foot UI | ✅ 10-foot UI | |
| Mobile apps | ✅ Native | ✅ Native | ✅ Native | ||
| Subscription | ✅ Free | ✅ Free | ✅ Free | ||
| Setup complexity | ✅ Minimal | ✅ Minimal | |||
| License | Apache 2.0 | GPL v3 | GPL v2 | GPL v2 | Proprietary |
| Stack | Python, FFmpeg | Node.js | .NET, FFmpeg | .NET, FFmpeg | Proprietary |
Corrections welcome — open an issue.
Create a docker-compose.yml:
services:
netv:
image: ghcr.io/jvdillon/netv:latest
ports:
- "8000:8000"
volumes:
- ./cache:/app/cache
- /etc/localtime:/etc/localtime:ro
devices:
- /dev/dri:/dev/dri # for hardware transcoding (remove if no GPU)
restart: unless-stoppedThen run:
docker compose up -dOpen http://localhost:8000. To update: docker compose pull && docker compose up -d
For customization or development:
git clone https://github.com/jvdillon/netv.git
cd netv
docker compose build # optimized FFmpeg (default)
# FFMPEG_IMAGE=ubuntu:24.04 docker compose build # or stock FFmpeg
docker compose up -dTo update: git pull && docker compose build && docker compose up -d
| Optimized (default) | Ubuntu Stock | |
|---|---|---|
| FFmpeg source | Pre-built with all codecs | apt (Ubuntu repos) |
| NVENC (NVIDIA) | ✅ | ❌ |
| VAAPI (Intel/AMD) | ✅ | ✅ |
| QSV (Intel QuickSync) | ✅ | ❌ |
| libfdk-aac | ✅ | ❌ |
| SVT-AV1 | ✅ | ❌ |
NETV_PORT=9000 docker compose up -d # custom port
NETV_HTTPS=1 docker compose up -d # enable HTTPS (mount certs first)For peak FFMPEG performance, Chromecast (requires HTTPS), and auto-start:
# 1. Install prerequisites (uv, Python)
./tools/install-prereqs.sh
# 2. (Optional) Get HTTPS certificates (required for Chromecast)
./tools/install-letsencrypt.sh yourdomain.com
# 3. (Optional) Build FFmpeg (required for optimal NVidia encoding efficiency)
./tools/install-ffmpeg.sh
# 4. Install systemd service
sudo ./tools/install-netv.sh # default port=8000 or --port 9000 Manage with:
sudo systemctl status netv # Check status
sudo systemctl restart netv # Restart after updates
journalctl -u netv -f # View logs
sudo systemctl edit netv --full # Change port or other settings
sudo ./tools/uninstall-netv.sh # UninstallThere's also some gems in tools/:
zap2xml.py: Scrape guide data into XML (Icrontabthis at 5am daily).alignm3u.py: Useful for reworking your HDHomeRun m3u to align with guide.xtream2m3u.py: Dump xtream to m3u, useful for making Emby work with IPTV.
Requires Python 3.11+ and uv:
git clone https://github.com/jvdillon/netv.git
cd netv
uv run ./main.py --port 8000 # --httpsOr with pip:
pip install .
./main.py --port 8000Open http://localhost:8000, create an admin account, and add your IPTV source.
Enable verbose logs to diagnose EPG, M3U parsing, or other issues.
Docker:
In docker-compose.yml, change LOG_LEVEL=INFO to LOG_LEVEL=DEBUG, then restart:
docker compose down && docker compose up -d
docker compose logs -fSystemd:
sudo systemctl edit netvAdd:
[Service]
Environment="LOG_LEVEL=DEBUG"Then restart and view logs:
sudo systemctl restart netv
journalctl -u netv -fManual / Development:
LOG_LEVEL=DEBUG ./main.py
# or
./main.py --debugCheck out iptv-org/iptv -- a community-maintained collection of publicly available IPTV channels from around the world.
The free choice is iptv-org/epg, but this has never worked reliably for me.
For a more robust solution, consider Schedules Direct -- your membership helps fund Open Source projects.
Alternatively you can use tools/zap2xml.py. I've used this for over a year
and found it to be very reliable -- it scrapes guide data from zap2it/gracenote.
HDHomeRun devices provide an M3U playlist, but it lacks EPG channel IDs. Use the
tools/ to fetch guide data and align it:
# 1. Get your HDHomeRun lineup (replace IP with your device's IP)
wget http://192.168.1.87/lineup.m3u -O tools/lineup.m3u
# 2. Fetch TV guide data for your area
./tools/zap2xml.py --zip 90210
# 3. Align the M3U with the guide (adds tvg-id for EPG matching)
./tools/alignm3u.py --input tools/lineup.m3u --xmltv tools/xmltv.xml --output tools/ota.m3uThen add tools/ota.m3u as an M3U source in neTV settings.
And set up a cron job to refresh the guide daily (e.g.,
0 5 * * * /usr/bin/python3 /path/to/netv/tools/zap2xml.py --zip 90210 && cp /path/to/netv/tools/xmltv.xml /var/www/html/).
| Key | Action |
|---|---|
Space / k |
Play/pause |
f |
Fullscreen |
m |
Mute |
c |
Toggle captions |
i |
Toggle info overlay |
← / → |
Seek ±10s |
↑ / ↓ |
Volume |
j |
Jump to time |
Esc |
Back / close |
Yes.
We leave pronunciation and meaning as an exercise for your idiom:
- N-E-T-V -- "Any TV", say it out loud
- ≠TV -- "Not Equals TV", because we're
!=traditional cable - Net-V -- "Net Vision", because it streams video over your network
- Ni!-TV -- For the Knights who say Ni
We will also accept a shrubbery. One that looks nice. And not too expensive.
If you find neTV useful, consider buying me a coffee:
Apache License 2.0




