iptv-app
v0.1.0
Published
A dark cinematic IPTV web app built with React + Vite. Supports M3U/M3U8 playlists (URL or file upload) and Xtream Codes API providers, with HLS.js playback for live streams.
Readme
NOVA · IPTV
A dark cinematic IPTV web app built with React + Vite. Supports M3U/M3U8 playlists (URL or file upload) and Xtream Codes API providers, with HLS.js playback for live streams.
Getting Started
npm install
npm run devOpen http://localhost:5173.
Features
- M3U / M3U8 playlists — load from a URL or upload a file
- Xtream Codes API — connect with server + username + password
- HLS.js playback for live streams, with native Safari fallback
- Category sidebar auto-generated from
group-title/ Xtream categories - Search across channel names and groups
- Persisted state via
zustand/persist(localStorage) - Dark cinematic UI with Bebas Neue display type, subtle noise, red accent glow
- Samsung Smart TV build — packages to a
.wgtTizen app (see below)
Scripts
| Command | Description |
|---|---|
| npm run dev | Start Vite dev server on port 5173 |
| npm run build | Production web build → dist/ |
| npm run preview | Preview the production web build locally |
| npm run build:tv | Samsung TV build → dist-tv/ + nova-iptv.wgt |
CORS Proxy
Many IPTV providers don't send CORS headers, so fetching an M3U URL directly from the browser fails. The app routes all playlist fetches through a local proxy middleware registered in vite.config.js:
GET /api/cors-proxy?url=<encoded-playlist-url>The middleware (corsProxyPlugin in vite.config.js) runs inside the Vite dev and preview servers — it fetches the target URL server-side, strips hop-by-hop headers, adds Access-Control-Allow-Origin: *, and streams the body back. No external service is needed.
In the TV build this proxy is bypassed entirely — Tizen packaged apps with <access origin="*"/> in config.xml can make cross-origin requests directly from the device.
Samsung Smart TV Build (Tizen)
Overview
Samsung Smart TVs run Tizen OS and install web apps packaged as .wgt files (a ZIP archive containing index.html, config.xml, and all assets at the archive root).
The TV build differs from the standard web build in three ways:
| Concern | Web build | TV build |
|---|---|---|
| Asset paths | Absolute (/assets/...) | Relative (./assets/...) — required by .wgt |
| CORS proxy | Local Vite middleware | Skipped — Tizen handles it via <access origin="*"/> |
| Viewport | width=device-width | width=1920 fixed canvas |
| Cursor | Default browser cursor | cursor:none (TV remotes have no pointer) |
How to Build
npm run build:tvThis runs two steps automatically:
vite build --config vite.config.tv.js— compiles intodist-tv/node scripts/package-tizen.js— copiestizen/config.xmlandtizen/icon.pngintodist-tv/, then zips everything intonova-iptv.wgt
Requires
zipon PATH (standard on macOS and Linux; use WSL on Windows).
Output
nova-iptv.wgt ← deploy this to the TV
dist-tv/ ← raw build output (intermediate)Deploying to a TV
Option 1 — Tizen CLI (requires Tizen Studio installed):
# List connected devices
tizen list-devices
# Install
tizen install --name nova-iptv.wgt -- <device-serial>Option 2 — Tizen Studio GUI:
Tools › Device Manager → right-click device → Install App → select nova-iptv.wgt
Option 3 — Developer Mode on the TV (no PC tools needed):
- On the TV:
Settings › General › System Manager › Developer Mode→ enable, enter your PC's IP - On your PC: open
http://<tv-ip>:8001/api/v2/applicationsin a browser to confirm connection - Use the Tizen CLI or a REST sideload call to push the
.wgt
App Icon
Place a 512×512 PNG at tizen/icon.png before building. The packaging script copies it automatically. Without it the app still installs but shows a default placeholder icon (a warning is printed during packaging).
Key Files
| File | Purpose |
|---|---|
| tizen/config.xml | Tizen app manifest — ID, version, privileges, access policy |
| tizen/icon.png | App icon (512×512 PNG, add manually) |
| vite.config.tv.js | TV-specific Vite config |
| scripts/package-tizen.js | Post-build packaging script |
tizen/config.xml Notes
- Package ID:
NovaIPTV00(10 alphanumeric chars, required by Tizen) - App ID:
NovaIPTV00.NovaIPTV - Privilege:
http://tizen.org/privilege/internet— grants network access <access origin="*"/>— allows the app to fetch any IPTV host without CORS blockinghw-key-event="true"— enables raw remote-control key events (arrow keys, back button)
To publish on the Samsung Apps TV seller portal you'll need to replace the package ID with one issued by Samsung and sign the .wgt with a distributor certificate.
Project Structure
iptv-app/
├── index.html # HTML entry point
├── vite.config.js # Web build + CORS proxy middleware
├── vite.config.tv.js # Samsung TV (Tizen) build
├── tailwind.config.js # Dark cinematic theme
├── postcss.config.js
├── package.json
├── tizen/
│ ├── config.xml # Tizen app manifest
│ └── icon.png # App icon — add manually (512×512 PNG)
├── scripts/
│ └── package-tizen.js # Packages dist-tv/ → nova-iptv.wgt
└── src/
├── App.jsx # Layout shell
├── main.jsx # React DOM mount
├── index.css # Tailwind + global styles
├── components/
│ ├── Header.jsx # Logo, search, add button
│ ├── Sidebar.jsx # Categories + playlist management
│ ├── ChannelGrid.jsx # Channel card grid with filtering
│ ├── VideoPlayer.jsx # HLS.js player with overlay controls
│ └── AddPlaylistModal.jsx # M3U URL / file upload / Xtream tabs
├── lib/
│ ├── m3uParser.js # #EXTINF parser
│ ├── xtreamClient.js # Xtream Codes API client
│ └── fetchProxy.js # Fetch wrapper (proxy on web, direct on Tizen)
└── store/
└── channelStore.js # Zustand store with localStorage persistenceHow the CORS Proxy Works (detail)
src/lib/fetchProxy.js exports a single function proxiedFetch(url, init). It checks the VITE_PLATFORM build constant:
'web'(default) — rewrites the URL to/api/cors-proxy?url=<encoded>and lets the Vite middleware handle it server-side'tizen'— callsfetch(url, init)directly; the Tizen runtime allows cross-origin requests for packaged apps
VITE_PLATFORM is injected at compile time via define in the respective Vite config, so the unused branch is tree-shaken out of the final bundle.
Next Steps
- EPG (electronic program guide) support
- Favorites / recently watched
- VOD & Series tabs for Xtream
- D-pad spatial navigation for the TV build
- Picture-in-picture and mini player
- Samsung TV seller portal certificate signing
