A fast, private, open-source IPTV player for Android and Android TV. M3U, M3U8 and native Xtream, with EPG, catch-up, downloads and a player that gets out of the way.
Note
This project is vibecoded. It was built end to end with an AI coding assistant. Review the code before you rely on it.
Important
OpenTV is a player only. It does not provide any channels, streams or subscriptions, and none are included. You bring your own M3U playlist or Xtream login from a provider you already use.
OpenTV is distributed as an APK that you install yourself. It is not on the Play Store. There are two channels:
- Latest release: the most recent tagged, stable version. Download
- Dev channel: rebuilt from the latest commit on
main. Download
Both published builds are signed with the same key, so updates install in place. Catalog schema changes deliberately recreate the catalog database and can remove playlists, connected servers, favorites, resume points, and download records; read the update guide first. Full instructions and documentation are on the OpenTV docs site.
OpenTV also ships as a self-hosted web app with the same experience: the
Android app and the web server share the same core modules (parsing,
classification, Xtream, EPG, catch-up, metadata, and catalog storage
contracts); only the UI differs. Server users, grants, activity, sessions, and
downloads are isolated in the JVM-only :server-data database and are never
bundled into Android. Playlists are stored server-side in SQLite.
docker run -d -p 127.0.0.1:8080:8080 -v opentv-data:/data \
-e OPENTV_AUTH_ENCRYPTION_KEY='PASTE_32_BYTE_KEY' \
ghcr.io/buco7854/opentv-web:latestThe server has local password authentication with MFA, OIDC SSO, revocable
bearer sessions, users, roles, and playlist assignments. The web client keeps
its bearer in localStorage; Android stores it encrypted under Android
Keystore. Generate the required secret with openssl rand -base64 32 or
openssl rand -hex 32; use HTTPS and set OPENTV_PUBLIC_URL when deploying
beyond localhost. See the
authentication guide.
The Now watching page (in the playlists panel) shows who is watching what,
with remote pause/resume, a message channel, and live stream diagnostics
(direct / proxied / remux, and why ffmpeg is copying or transcoding). Viewers
are identified by their account and lease; set OPENTV_TRUSTED_PROXIES to a comma-separated list of
proxy IPs/CIDRs (e.g. 127.0.0.1,10.0.0.0/8) so the real client IP is read from
X-Forwarded-For when the request comes through your reverse proxy.
Most M3U players either hammer your provider until you get blacklisted, guess content types badly, or bury features behind a clumsy UI. OpenTV is built around three ideas: be gentle on the provider, classify content intelligently, and look genuinely good while doing it.
- Sources: native Xtream login (server-side Live, Movies and Series with no
classification guessing, the full series catalog, and auto-wired EPG and
catch-up) plus M3U/M3U8 by URL or file. Flat playlists get smart, unit-tested
VOD detection, and a
get.phpURL is offered an automatic upgrade to Xtream. An optional OpenTV server source adds granted playlists, synced favorites and progress, watch together, and pipelined downloads stored on the device. - Browsing: list or poster-grid views with 4K/FHD/HDR badges, a filter bar, global search, favorites keyed by stable identity, and rich movie, series and episode pages with cast photos (keyless via TVMaze, iTunes and Wikidata/Wikimedia Commons).
- Watching: Media3/ExoPlayer (HLS, TS, MP4, MKV) with embedded audio and subtitle track selection and styling, skip and scale gestures, Picture-in-Picture (including auto-PiP), continuous resume, EPG now/next with a full guide, and catch-up/timeshift replay.
- Downloads: offline movies and episodes with pause and resume, progress notifications and a manager; connection-aware so they never trip your provider's limit.
- Account and ops: a connection and expiry monitor, an in-app error log with credentials redacted, and full Android TV support (leanback, D-pad focus).
Full walkthroughs are on the docs site.
Getting blacklisted is the number one IPTV annoyance, so OpenTV minimizes requests by design: conditional GETs (a 304 for an unchanged playlist or EPG), refresh throttling (playlist at least 6h, EPG at least 12h) with single-flight collapsing, on-demand-only deep guide fetches, one pooled HTTP client with a 32 MB disk cache, and streaming M3U/XMLTV parsers batched into Room. A full Xtream refresh is six requests.
Kotlin, Jetpack Compose (Material 3), Media3 and ExoPlayer, Room, WorkManager, DataStore, OkHttp and Coil. The Android app, server, shared core/data, server-contract and hub-client are separate Gradle modules, with CI on every push.
./gradlew :app:testDebugUnitTest # unit tests
./gradlew :app:assembleRelease # release APK (signed with your key if provided, else debug-signed)
./gradlew :app:assembleDebug # debug APKRequires JDK 17 or newer and the Android SDK (platform 37). The CI workflow runs
the unit tests and builds a release APK on every push. It refreshes the rolling
dev release on main, and publishes a tagged GitHub Release when you push a
vX.Y.Z tag.
The docs site lives in docs/ and is built with Docusaurus, themed to match
the web client. To work on it:
cd docs
npm ci
npm run docs:dev # local preview
npm run docs:build # production buildRequires Node.js 24.18 or newer. It deploys to GitHub Pages automatically when
docs/ changes on main.
The OpenTV project runs no hosted service and includes no analytics or ads. Standalone Android sources talk only to your provider and optional keyless metadata APIs. If you connect a self-hosted OpenTV server, its account, playback, favorites, progress, and download requests go to that server, which also records your viewing activity for its administrator. Full policy: PRIVACY.md.
Issues and PRs are welcome. Please keep changes covered by the existing build and
test setup (./gradlew testDebugUnitTest) and match the surrounding style.
Released under the GNU GPL v3.0. You may use, study, modify and redistribute it, provided the source stays open under the same license. See LICENSE.
Copyright 2026 Buco7854.