Your own IPTV player for Android TV
Fast ยท modern ยท remote-first โ bring your own M3U or Xtream sources
OwnTV is a native Android TV IPTV player built with Kotlin, Jetpack Compose for TV, and libmpv (FFmpeg). It's a player only โ you bring your own M3U or Xtream sources, and OwnTV gives you a fast, modern, remote-first way to browse and watch them.
โ ๏ธ OwnTV does not provide any channels, playlists, subscriptions, streams, or media content. You are responsible for adding your own legally accessible sources.
This is an open-source project โ the code is original (not derived from any other app) and was built with the help of AI. Contributions are welcome: clone, build, and test it freely. It targets Android TV only (leanback launcher, D-pad-first UI).
Questions, ideas, bug reports โ or just want to follow along? Join the OwnTV Telegram group:
๐ t.me/owntvplayer
Scan to join from your phone:
- Plays virtually any codec/container, and exposes every audio and subtitle track (not just the ones the device can decode).
- TV-optimized rendering โ the decoder writes frames directly to the display (the zero-copy pipeline streaming apps use): smooth 4K HDR with the panel's native HDR handling and fast channel starts, with subtitles drawn by the app. Software decoding is used automatically as a fallback for streams the hardware decoder can't handle.
- Custom TV HUD: scrubbable seek bar, prev/next, audio/subtitle/speed pickers, zoom & aspect modes, volume, and auto-hide controls.
- Channel zapping โ while watching fullscreen with the controls hidden, D-pad Up/Down (plus CH+/CHโ and the media โฎ/โญ keys) switch channels and wrap around at the ends, so remotes without dedicated channel buttons (e.g. Fire TV) can zap too.
- Large demuxer cache for smooth 4K/8K streams; HDR passthrough when the video and TV support it.
- Mini-player / PiP โ dock a movie, episode or live channel to a corner and keep browsing (it keeps streaming across the whole app); selecting another channel updates the docked window, and you can expand or close it.
- Resume, your way โ movies & episodes remember where you stopped; replaying shows a small "Resume at 23:45?" prompt, with a setting for Always / Ask / Never resume.
- ๐บ Complete player design & feature reference โ โ an interactive Material 3 mockup documenting the full player HUD, PiP, popup menus, and remote-key mappings.
- Live TV, Movies, Series, Downloads, and a full EPG Guide. The Live preview pane
shows the channel's video, now/next/later, and the real stream resolution (e.g.
1080p/4K) โ so a channel named "โฆ4K" that's actually 1080p can't fool you. - Folder rail with section-specific Favorites and History โ it expands on focus to show full category names, with a category search box at the top to filter hundreds of groups by name. Inline per-folder search and a cross-section global search too โ all TV-style: search bars take focus like any control and only open the keyboard on OK.
- Sort toggle per section: your playlist's own order or AโZ (Live TV defaults to playlist order).
- Customize everything (per profile): hide, rename & reorder categories; hide & rename channels โ and it all survives re-syncs.
- Built for scale โ tested with ~50k channels / ~168k movies via streaming import and Paging 3.
- A full time ร channel guide grid (XMLTV), plus per-channel now / next / later in the Live preview.
- Catch-up TV (archive) โ for providers that support it (Xtream
tv_archive/ M3Ucatchup), watch programmes that already aired: the guide extends back in time, and Watch from start replays a programme from the archive (seekable). A Catch-up time setting (device timezone or a manual UTC offset) handles panels that index their archive in local time. - Smart EPG matching โ an Auto-match EPG button links channels to the guide by name when their tvg-id is missing or wrong (ignoring HD/country tags); confident matches apply automatically, the rest go to a quick review list. Or long-press a channel to auto-match or pick its guide entry manually. All matches are per profile and survive re-syncs.
- Two-stage guide navigation โ press Right on a channel to select its whole programme row, then OK to browse programmes with Left/Right (Up/Down jumps channels at the same time), plus a sort button (AโZ / Provider / Live TV / Catch-up).
- Multiple EPG sources โ add any number of XMLTV feeds in Settings โ EPG Sources (edit /
delete / re-sync); they merge into the guide. Adding a playlist auto-syncs its EPG (Xtream
xmltv.php/ M3Uurl-tvg). - Clear status: the Guide shows "Guide loaded: N channels ยท M programmes ยท K with catch-up", and each EPG source shows its own sync state.
- Multiple profiles with their own favorites/history/resume, optional PIN locks (salted hash) and a kids flag, and a "Who's watching?" launch gate. Sources can be shared between profiles.
- Offline downloads for movies & episodes (never Live TV), with pause/resume and a user-chosen download folder.
- Material 3 theme (AMOLED dark / light / system), any accent color โ presets, a palette, or an exact hex code (the whole theme is generated from it) โ UI zoom, per-profile avatars.
- Video Player settings: hardware decoding, default zoom, subtitle size & language, audio sync.
- Complete Backup & Restore โ one file covers profiles, sources, customizations, favorites, watch history, and resume positions โ and you choose what to include on export and what to apply on restore; per-source User-Agent, refresh-on-startup, default source.
- In-app updates โ OwnTV checks GitHub Releases (automatically on startup with a small corner status card โ toggleable โ or manually), shows the full changelog, and installs the new APK right on the TV. No browser, no storage permission.
- Sized for real TVs โ the player's memory budget scales to the device (lean stream buffers on low-RAM panels), a decode watchdog blocks 4K/8K software-decode death spirals with a clear error, backgrounding releases the stream immediately, and the app sheds caches under memory pressure.
- All player commands run off the UI thread โ a stalling stream can never freeze the remote (no ANRs), and fast preview-scrolling coalesces loads so only the channel you land on is opened.
- Connection-friendly: preview โ fullscreen reuses the same stream (no reconnect โ kind to strict 1-connection providers), and a dropped live stream auto-reconnects before showing an error + Retry.
- Offline detection with a banner, and friendly, offline-aware error messages on import/sync/guide.
![]() Main view |
![]() Live TV โ preview playing |
![]() Movies |
![]() "Who's watching?" profile gate |
![]() Downloads |
![]() Settings |
![]() TV Guide (EPG) |
![]() Personalization |
More in extras/screenshots/ โ Live TV (preview off), playlist management, profiles & sources settings.
| Area | Choice |
|---|---|
| Language | Kotlin 2.3.10 (AGP 9 built-in Kotlin, no kotlin-android plugin) |
| Build | AGP 9.2.1 / Gradle 9.4.1, KSP2 2.3.9 |
| UI | Jetpack Compose for TV (androidx.tv:tv-material 1.1.0), Compose BOM 2026.05.00 |
| Media | libmpv (FFmpeg) โ dev.jdtech.mpv:libmpv |
| Database | Room 2.8.4 + Paging 3.5.0 + FTS4 (WAL) |
| DI | Koin 4.1.1 |
| Networking | OkHttp |
| Images | Coil 3.3.0 |
| Preferences | DataStore |
minSdk 26, targetSdk 36, applicationId tv.own.owntv.
Build note: Kotlin comes from AGP 9's built-in Kotlin (no
kotlin-androidplugin). KSP 2.3.6+ supports built-in Kotlin, so Room codegen works alongside it; the Compose compiler and KSP track Kotlin 2.3.x.
- Parsing & sync โ M3U playlists are line-streamed and Xtream
player_apiJSON is read withandroid.util.JsonReader, so huge provider payloads are never fully buffered.SyncManagerdoes a clear-then-insert refresh in ~500-row chunked transactions with Flow progress and cancellation. - Storage โ a 19-entity Room schema: profiles & sources (
ProfileSourceCrossReffor sharing), content (categories/channels/movies/series/seasons/episodes), per-profile favorites/history/progress/ downloads, EPG channels/programmes, and FTS4 search tables. Totals come from indexedCOUNTqueries. - Lists โ Paging 3 with a bounded
maxSizekeeps memory flat across 50k+ item lists. - EPG โ bulk XMLTV is stream-parsed (gzip-aware) into a rolling nowโ+48h window and pruned.
- Player โ a single hoisted
libmpvsurface drives preview, fullscreen, and the mini-player, with state published asStateFlows for the Compose HUD. - DI โ Koin modules (
appModule,databaseModule,dataModule,playerModule).
tv.own.owntv/
โโโ core/ database (Room), network, parser (M3U/Xtream/XMLTV), repository, sync, util
โโโ player/ libmpv player + Compose surface + HUD + mini-player
โโโ ui/ theme + reusable components (focus surface, cards, state views, avatars)
โโโ features/ setup, shell, live, movies, series, search, downloads, epg, profiles, settings
โโโ di/ Koin modules
- ๐ Complete Product Brief & Build Plan โ the full as-built design brief, architecture, data model, and all 14 build phases.
- ๐บ Player design reference โ an interactive Material 3 mockup of the player UI.
- ๐ผ๏ธ
extras/logo.pngโ the OwnTV logo.
Grab the signed APK from the latest release and sideload it. A fixed link always points at the newest signed build:
https://github.com/ahXN00/OwnTV/releases/latest/download/OwnTV.apk
- Fire TV โ install the Downloader app (by AFTVnews) from the Amazon Appstore, then enter the
Downloader code
4308278(oraftv.news/4308278, which always points at the latest signedOwnTV.apk). Enable Apps from Unknown Sources if prompted. - Android TV / Google TV โ the Downloader app is also on Google Play, so the same code
4308278works here too. (If Downloader doesn't show in search, open the Play Store on the TV โ you can reach it via Settings โ Apps โ See all apps โ Show system apps โ Google Play Store โ and install it from there.) Or just sideload the APK with your tool of choice (Send files to TV, a USB drive, oradb install OwnTV.apk).
Only install the APK from this repository's official Releases (or the
โฆ/releases/latest/download/OwnTV.apklink above). It's the build signed by this project's CI โ third-party re-hosts aren't endorsed.
- Open the project in Android Studio (a version matching AGP 9.x) and let Gradle sync.
- Run the
appconfiguration on an Android TV emulator or device. The app declaresLEANBACK_LAUNCHERand requires the leanback feature, so it appears in the TV launcher, not the phone launcher. - Or from the command line:
./gradlew assembleDebugOn first launch you'll go through onboarding: accept the disclaimer, create a profile, then add a source (M3U or Xtream) โ or import a backup. After it imports, browse from the sidebar and open the Guide for the EPG. Everything is managed under Settings.
Tested on: a real TCL Google TV, and the Android Studio emulator (both the Android TV and Google TV system images).
GitHub Actions (.github/workflows/android.yml) builds the app in the
cloud โ no local build needed:
- Every push / PR โ builds a debug APK and uploads it as a workflow artifact named
OwnTV-v<version>-<sha>.apk(download it from the run's Summary โ Artifacts). - Push a
v*tag (e.g.git tag v1.1.0 && git push origin v1.1.0) โ builds a signed APK and publishes a GitHub Release withOwnTV-v1.1.0.apkattached. The release notes are taken from the newest section ofCHANGELOG.md(which the in-app updater shows as "What's new"), plus GitHub's auto-generated commit list.
Versioning is automatic: versionName/versionCode are derived from the tag (e.g. v1.1.0 โ
1.1.0 / 10100) โ no need to touch build.gradle.kts.
Signed release builds (optional, recommended for distribution). Tag builds are debug-signed until you add a release keystore. Create one and add four repo Secrets to get properly signed releases:
keytool -genkey -v -keystore owntv.keystore -alias owntv -keyalg RSA -keysize 2048 -validity 10000
base64 -w0 owntv.keystore # copy the output into the KEYSTORE_BASE64 secretThen add repo Secrets (Settings โ Secrets and variables โ Actions): KEYSTORE_BASE64,
KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD. Keep the keystore file private โ it's never committed.
Contributions, bug reports, and ideas are welcome โ open an issue or a pull request. Please keep the project's player-only, bring-your-own-source positioning, and match the existing code style.
OwnTV is a media player only. It ships with no channels, playlists, subscriptions, or content, and does not endorse or facilitate access to unauthorized streams. Users are solely responsible for the sources they add and for complying with the laws and rights that apply to them.
Released under the MIT License โ see LICENSE.
OwnTV is an open-source, player-only project, built with the help of AI.









