{"id":51288715,"url":"https://github.com/khalilbenaz/ultra-tv","last_synced_at":"2026-06-30T08:32:11.990Z","repository":{"id":357240526,"uuid":"1236062278","full_name":"khalilbenaz/ultra-tv","owner":"khalilbenaz","description":"Modern IPTV player for Web, Desktop and Android TV / Google TV — Xtream, M3U, Stalker. HLS/DASH/MPEG-TS, EPG, DVR, Cast, multi-language.","archived":false,"fork":false,"pushed_at":"2026-06-03T15:38:34.000Z","size":1305,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T16:22:41.408Z","etag":null,"topics":["android-tv","capacitor","chromecast","dash","electron","epg","google-tv","hls","iptv","iptv-player","m3u","react","stalker-portal","typescript","vlc","xtream-codes"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/khalilbenaz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T23:14:02.000Z","updated_at":"2026-06-03T15:51:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/khalilbenaz/ultra-tv","commit_stats":null,"previous_names":["khalilbenaz/ultra-tv"],"tags_count":37,"template":false,"template_full_name":null,"purl":"pkg:github/khalilbenaz/ultra-tv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalilbenaz%2Fultra-tv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalilbenaz%2Fultra-tv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalilbenaz%2Fultra-tv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalilbenaz%2Fultra-tv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/khalilbenaz","download_url":"https://codeload.github.com/khalilbenaz/ultra-tv/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/khalilbenaz%2Fultra-tv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34959505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android-tv","capacitor","chromecast","dash","electron","epg","google-tv","hls","iptv","iptv-player","m3u","react","stalker-portal","typescript","vlc","xtream-codes"],"created_at":"2026-06-30T08:32:11.339Z","updated_at":"2026-06-30T08:32:11.978Z","avatar_url":"https://github.com/khalilbenaz.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ultra TV\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/redesign/logo.svg\" alt=\"Ultra TV\" width=\"160\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eNative Android TV / Google TV IPTV player.\u003c/strong\u003e\u003cbr/\u003e\n  Kotlin · Jetpack Compose · Compose-TV · Media3 · Room · Hilt\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/khalilbenaz/ultra-tv/releases/latest/download/UltraTV-debug.apk\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Download-Android%20TV%20APK-3DDC84?style=for-the-badge\u0026logo=android\u0026logoColor=white\" alt=\"Download APK\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-0284c7?style=for-the-badge\" alt=\"License\" /\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Kotlin-2.0-7F52FF?style=for-the-badge\u0026logo=kotlin\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Compose--TV-1.0-4285F4?style=for-the-badge\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Media3-1.5-FF6F00?style=for-the-badge\" /\u003e\n\u003c/p\u003e\n\n---\n\n## 🎨 New UI (2026 redesign)\n\nFull editorial redesign — AMOLED-first, accent rouge `#FF3A2F`, typo **Instrument Serif** pour les titres + **Geist** / **Geist Mono** pour le reste.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/redesign/home.png\" alt=\"Home — hero éditorial + rails Netflix-style\" width=\"900\" /\u003e\n\u003c/p\u003e\n\n| Écran | Description |\n|---|---|\n| **Home** | Hero éditorial 720 dp · serif 84 sp · eyebrow accent · colonne \"En direct maintenant\" · rails Continue Watching 16:9 + Films / Séries / Chaînes |\n| **Live TV** | Layout Tivimate 3 panes : catégories (accent pill) · chaînes (numérotation mono, logo dégradé hue) · **fenêtre preview** avec logo géant, chip `EN DIRECT`, cards now/next, CTA Regarder |\n| **Films / Séries** | Hero featured + rails Netflix par catégorie · focus Apple-TV (scale 1.08 + ring accent) |\n| **Detail** | Affiche 320×480 · serif 72 sp · meta accent · `94% match` · épisodes mono `S01E02` |\n| **Guide TV** | Timeline 12 h × N chaînes · ruler mono · ligne `NOW` accent · cards programme avec chip `EN COURS` |\n| **Recherche** | 2 panes : clavier d'écran 4×10 + récentes à gauche · chips de filtres + grille de résultats à droite |\n| **Player** | Overlays minimaux : top bar transport, bottom controls big play + ring accent, **stats card** mono, **EPG drawer** zapping |\n| **Settings** | Tabs sidebar 300 dp · section cards Surface1 + border · MAC card gradient accent · toggle, pills, color swatches |\n| **Onboarding** | Wizard 3 steps · stepper accent · option Cloud (recommandée) vs Manuel · QR code stub |\n\nMulti-View screen was removed in v1.0.0 — too few users, awkward focus on a single remote.\n\n### Logo\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/redesign/logo.svg\" alt=\"Ultra TV — logo variant C\" width=\"120\" /\u003e\n\u003c/p\u003e\n\nLogo \"variant C\" : dégradé rouge `#FF3A2F → #7A0E08`, trois ondes de diffusion qui émanent d'un point en bas à gauche, triangle play plein à droite. Installé en tant que `ic_launcher` adaptive + banner Android TV (320×180).\n\n---\n\n## What is Ultra TV?\n\nUltra TV is a **fully native** Android TV IPTV client. D-pad navigation is handled by Compose-TV's focus tree (no WebView bridges), playback uses Media3 / ExoPlayer for native codec support, and the whole catalog (channels, movies, series, EPG, history, favorites) lives in a local Room database. It speaks **Xtream Codes**, **M3U / M3U8** (URL or local file), and **Stalker Portal** out of the box.\n\nA companion **Cloudflare Worker** (in `cloudflare-config/`) provides a MAC-based remote-config dashboard so users can provision their providers from a web browser and have the TV pull them in one click.\n\n## Features\n\n### Catalog \u0026 providers\n- 🎬 **Xtream Codes** · **M3U URL** · **M3U file from local storage** · **Stalker Portal** with Live + VOD + series catalogues (MAC handshake + lazy `create_link` at play time, including movies)\n- 🔁 **Multi-provider** — add as many as you want, pick the default in Settings (★ Default badge)\n- 🚦 **De-duplication** — re-adding the same `(kind, url, username)` reuses the existing row instead of duplicating\n- 🛰️ **Cloud sync via Cloudflare Worker** — paste your device MAC into the dashboard (login + password), add providers, then the app pulls them with one tap. App reads are anonymous (the MAC, hashed from `ANDROID_ID`, is the bearer); only dashboard mutations require the per-MAC password.\n- ⏱️ **Background sync via WorkManager** (every 6 / 12 / 24 h, or every launch)\n- 📈 **Live sync progress banner** pinned to the top of every screen during sync\n\n### Live TV\n- 📺 **Tivimate-style two-pane layout**: categories on the left, channels of the selected category on the right\n- 🔢 Channel position numbers, logos, focus highlight, **now-playing + next-up programme** under each name (from cached EPG)\n- 🏷️ **Categories management** (search, bulk Hide / Show, \"Hide adult\" preset, 🔒 / 🔞 markers)\n- 🧹 Cleans decorative wrappers (`### FRANCE ###` → `FRANCE`) for display while keeping DB intact\n\n### Movies / Series\n- 🎞️ **Netflix-style rails by category** (top 25 per rail), hero banner with the featured title\n- 🟦 Focus scale animation (1.0 → 1.08, 160 ms tween)\n- 🔍 Cross-content **search** (debounced 220 ms): channels + movies + series, with **last-10 recent queries** as one-tap chips\n- ★ **Favorites** (per kind, browsable from a dedicated screen)\n- 📚 **Series episodes** loaded on demand — Xtream via `get_series_info` (per-season map), Stalker via `get_ordered_list?category=…`; played through Media3 (Stalker episodes resolve their `stalker://` URL via `create_link` at play time, exactly like channels and movies)\n\n### Player\n- ▶ **Media3 / ExoPlayer** — HLS, DASH, MPEG-TS, MP4 with hardware codec support\n- 🎮 D-pad: BACK = exit, plus **Live**: ▲/▼ zap channels in the current category; **VOD**: ◀/▶ seek\n- 🎚 **Subtitle + audio track selector** (VOD only) — reads Tracks from Media3, applies a TrackSelectionOverride\n- 📋 **EPG drawer overlay** (Live only) — press OK / center to slide in a right-side channel list with now/next; D-pad picks a channel to zap to\n- 📡 **Chromecast button** in the player toolbar — opens the system Cast picker when Google Play Services are available (silent no-op on Cast-less Android TV builds)\n- ⏸️ **Continue watching** (position recorded every 10 s + on dispose)\n- 🚀 **Auto-play last watched on launch** option\n- 🥷 **Open in external player** (VLC / MX / Just Player / Next Player) for codecs Media3 can't handle\n- ⏺ **Record VOD** — from a movie's detail page, queue an OkHttp-backed download via WorkManager; progress visible on a Recordings screen; played locally once done (no external storage permission — saved under app-private external storage)\n- 📐 **Aspect \u0026 speed** controls in the player toolbar — Fit / Fill / Zoom / 16:9 / 4:3 for picture, 0.5× / 1× / 1.25× / 1.5× / 2× for VOD playback speed\n- 💤 **Sleep timer** (15 min · 30 min · 1 h · 2 h · cancel) — pauses + exits player at the deadline\n- 📊 **Stream stats overlay** — resolution / video \u0026 audio codec / frame rate / bitrate / buffer ahead, toggled from the player overlay\n\n### Discovery / Home\n- 🏠 Dynamic Home: **Continue watching** (tap an item → Resume / Dismiss sheet), **Recently watched**, **Movies**, **Series**, **Featured channels** rails\n- 🆕 **First-time MAC card**: shows your device MAC + dashboard steps when no provider is configured\n- 🗓 **TV Guide grid** (Tivimate-style): 12 h × N channels timeline with \"now\" indicator, refreshed from the provider's full `xmltv.php` feed (streaming pull-parser handles 50 MB+ feeds)\n- ▦ **Multi-View**: up to 4 channels simultaneously in a 2×2 grid\n\n### Personalization\n- 🎨 **3 themes**: Dark · AMOLED · Blue\n- 📐 **Adaptive nav**: sidebar on tablets/TV (≥ 840 dp), top bar on medium widths (600–840 dp, also the user-selectable option in Settings), bottom bar on phones (\u003c 600 dp). Phones / tablets ship from the same APK.\n- 🌍 **Multi-language** UI: English / Français / Español / العربية + System (auto-detect). RTL layout direction flips automatically for Arabic. Translation table covers nav, home, settings and common buttons; the longer prose is still English for now.\n- 🔄 **Boot autolaunch** — open Ultra TV automatically when the box finishes booting\n- 🪟 **Picture-in-picture** — pressing Home while a stream plays shrinks the player into a corner (Android 8+)\n- 🪜 **Onboarding wizard** on first launch — 3-step flow showing the device MAC and the two provider-adding paths\n- 🔢 Show / hide channel numbers, hide adult categories beyond PIN, resume playback toggle, auto-play next episode\n\n### Backup \u0026 state\n- 💾 **Export / restore** providers + favorites + watch history as a single JSON file (Storage Access Framework picker)\n\n### Security\n- 🔐 **Parental PIN** (SHA-256, DataStore-backed) — auto-locks adult categories on each sync when a PIN is set\n- 🔒 **Per-channel lock** — Settings → Manage locked channels lets you flag individual channels; play prompts for the PIN\n- 🆔 **Stable per-device MAC** derived from `ANDROID_ID` (hashed) — never the real WiFi MAC\n\n### Performance\n- 🖼️ **Coil ImageLoader** with 25 %-heap memory + 256 MB disk cache (no re-downloads on scroll)\n- 📦 **Chunked DB inserts** (500 rows / batch) during sync — flat memory on huge catalogs\n- ⚡ **DB indices** on `(providerId, categoryId)` for fast category filtering\n- 🎯 SQL-level filtering for Live TV per category (only the visible subset materialises)\n- 🧱 **R8 / ProGuard release build** with resource shrinking — **18 MB debug → 4.9 MB release** (incl. Google Cast SDK) (latest APK shipped is the release variant)\n- 📑 **Paging Room** for Movies / Series flat-grid (pages of 60, only ~120 items in memory regardless of catalog size)\n\n### Distribution \u0026 updates\n- 🇩 **Downloader code `5248504`** — initial sideload via the [Downloader app](https://www.aftvnews.com/downloader/) on any Android TV box.\n- 🌐 GitHub Releases — latest APK at `releases/latest/download/UltraTV-debug.apk`.\n- 🔄 **In-app self-update** (v1.0.5+) — the app pings GitHub Releases on launch, compares versionCode, and pops a dialog with a progress bar that downloads + installs the new APK via PackageInstaller. First update prompts once for \"Install unknown apps\"; subsequent updates are one-tap. No Play Store, no third-party updater required.\n\n### Telemetry \u0026 crash reporting\n- 🛰️ **Cloudflare Worker ingest** — every crash + ad-hoc `RemoteLog.info/warn/error/debug(...)` event is POSTed directly to the worker. No local crash.txt; no ADB pulls.\n- 📒 **Crash dashboard** — `GET /crashes?token=…` returns an HTML page with expandable stack traces, device + version columns, 30-day rolling window.\n- 🪵 **Event dashboard** — `GET /logs?token=…` table with level colouring (debug / info / warn / error), 7-day rolling window.\n- 🔑 Token-gated via `env.CRASH_TOKEN` (fallback to `env.ADMIN_PASSWORD`). The app ships the URL + token baked in so every install reports automatically.\n\n## Quick start\n\n### Install on a TV box\n\n1. Install the **Downloader** app on your Android TV box from Google Play.\n2. Open Downloader, enter code **`5248504`**, press **Go**.\n3. Allow install from unknown sources when prompted; install the APK.\n4. On first launch, you'll see a **First-time setup** card with your device MAC.\n5. Either:\n   - Open **Settings** → tap **+ Xtream / + M3U URL / + M3U file / + Stalker portal** and fill in the form.\n   - **Or** self-host the Cloudflare Worker, provision your MAC in its dashboard, then **Sync from cloud**.\n\nFrom v1.0.5 onwards you only need Downloader for the *first* install — the app auto-updates itself from GitHub Releases.\n\n### Build from source\n\n```bash\ngit clone https://github.com/khalilbenaz/ultra-tv\ncd ultra-tv/android-native\n\n# JDK 17 is required (Android Gradle Plugin 8.7+)\nexport JAVA_HOME=$(/usr/libexec/java_home -v 17)   # macOS\n./gradlew assembleDebug\n\n# APK at app/build/outputs/apk/debug/app-debug.apk\n```\n\nFor a smaller signed release build:\n\n```bash\n./gradlew assembleRelease\n# ~8 MB APK at app/build/outputs/apk/release/app-release.apk\n```\n\n### Deploy the Cloudflare Worker (optional)\n\n```bash\ncd cloudflare-config\nnpm i -g wrangler\n\nwrangler kv:namespace create CONFIG             # paste id/preview_id into wrangler.toml\nwrangler kv:namespace create CONFIG --preview\nwrangler secret put ADMIN_PASSWORD              # strong password — dashboard login\nwrangler secret put CRASH_TOKEN                 # optional: rotate the crash-report token away from the admin one\nwrangler deploy\n```\n\nThe Worker URL printed by wrangler is what you paste in the app's Settings → **Change** next to the Worker URL field, and is also the host of the crash + event dashboards (`/crashes?token=…`, `/logs?token=…`).\n\nIf you fork the project, swap the hard-coded `WORKER_URL` + `TOKEN` constants in `android-native/.../RemoteLog.kt` and `UpdateChecker.kt` so your installs report to *your* worker, not the upstream one.\n\n## Architecture\n\n```\nandroid-native/\n├── app/src/main/kotlin/com/ultratv/tv/nativeapp/\n│   ├── MainActivity.kt         (entry point + nav host)\n│   ├── UltraTvApp.kt           (Hilt + Coil + WorkManager Configuration.Provider)\n│   ├── BootReceiver.kt         (BOOT_COMPLETED → MainActivity)\n│   ├── data/\n│   │   ├── db/                 (Room entities + DAOs)\n│   │   ├── xtream/             (Xtream Codes player_api.php client)\n│   │   ├── stalker/            (Stalker Portal handshake + create_link)\n│   │   ├── m3u/                (M3U/M3U8 parser, URL or text input)\n│   │   ├── repo/               (Provider / Catalog / History / PlaybackContext / SyncStatusBus)\n│   │   ├── sync/               (WorkManager SyncWorker + SyncScheduler)\n│   │   ├── parental/           (PIN store, SHA-256)\n│   │   ├── prefs/              (UserPreferences, HiddenCategoriesStore)\n│   │   └── config/             (DeviceMac, RemoteConfigImporter)\n│   ├── di/                     (Hilt modules: DB / Network)\n│   ├── nav/                    (Routes catalog)\n│   ├── RemoteLog.kt            (direct-to-Worker crash + event transport)\n│   ├── update/                 (UpdateChecker + UpdateDialog — GitHub Releases self-update)\n│   └── ui/\n│       ├── theme/              (DesignTokens, ultraCardColors, palettes: AMOLED / Dark / Blue)\n│       ├── components/         (SidebarNav, TopBarNav, UltraIcons — 28 stroke icons)\n│       ├── common/             (PosterCard, ContentRail, HeroBanner, ChannelLogo, ContinueWatchingTile, NowPlayingMini)\n│       ├── home/               (rails + MAC onboarding card)\n│       ├── live/               (Tivimate 3-pane: categories | channels | preview window)\n│       ├── movies/             (Rails view + Detail)\n│       ├── series/             (Rails view + Detail with episodes)\n│       ├── guide/              (12 h × N timeline grid with NOW accent line)\n│       ├── search/             (on-screen keyboard + filter chips + grid)\n│       ├── favorites/\n│       ├── categories/         (Hide / Show + bulk)\n│       ├── player/             (Media3 PlayerView wrapper)\n│       └── settings/           (editorial header + section cards + AddProviderDialogs)\n└── cloudflare-config/          (Worker: KV-backed config per MAC + crash \u0026 event dashboards)\n```\n\n## Roadmap\n\nIn active development / next iterations:\n\n- 📊 **7-day xmltv** (current grid covers 12 h; longer window is a windowing change away)\n- 🔍 **Full-text search index** (Room FTS4) — current LIKE is ok up to ~10k items\n- 🧭 **Aggregated crash grouping** on the dashboard (currently one entry per occurrence; collapsing by stack fingerprint would scale better)\n\nRecently landed:\n\n- 🔓 **Anonymous worker sync (v1.0.8)** — the app no longer needs the per-MAC password to pull its config. The dashboard `/login` still gates mutations.\n- 🎯 **Settings dialog focus (v1.0.8)** — text fields grab D-pad focus on dialog open and show an accent-tinted border so the cursor is visible.\n- 🔁 **Update dialog loop fix (v1.0.8)** — local + remote versions are now compared on the same packed-semver scale; no more \"update available\" popping after every install.\n- 🪟 **Auto-update via system installer (v1.0.6)** — switched from PackageInstaller sessions to `ACTION_VIEW` + FileProvider so the OS install activity handles the APK. Works on Fire TV, Mecool, vivo boxes that rejected the session path.\n- 🩹 **Focus visibility + sidebar flicker (v1.0.7)** — `inverseOnSurface` flipped to near-black so TV Button/Card focus reads as a white pill with dark text instead of white-on-white. Sidebar labels gate on the animated width so returning via the left D-pad doesn't reflow text.\n- 🎨 **2026 editorial redesign** of every screen — AMOLED-first, accent `#FF3A2F`, Instrument Serif + Geist typo, new variant-C launcher icon. See the *New UI* section above.\n- 🛰️ **Remote crash + event reporting** to a self-hosted Cloudflare Worker (`POST /api/crash`, `POST /api/event`); HTML dashboards at `/crashes` and `/logs`. No more `crash.txt` hunting.\n- 🔄 **In-app GitHub-Releases auto-update** with a download progress bar + PackageInstaller commit. After v1.0.5 the Downloader code is only needed for the very first install.\n- 🩹 **LiveViewModel init-order NPE fix** that was crashing any nav to Live TV on some devices (Main.immediate dispatch + property declared after init).\n- 📥 **HLS-segment recording** for Live channels (m3u8 polling + .ts append).\n- 🌐 **Deep i18n EN / FR / ES / AR** across every screen — Home, Live, Movies/Series, Settings (incl. private dialogs and SAF toasts), Preferences, Categories, Onboarding wizard, Guide list + grid, Add-provider dialogs, parental PIN flow, Recordings, Search, Player overlays plus the rail-title fallback. ~270 keys, RTL-aware.\n- 👆 **Touch UX**: vertical-drag gesture overlays for system volume (right strip, `🔊 nn%`) and screen brightness (left strip, `☀ nn%`); **pull-to-refresh** on Home, Live TV, Movies, Series and the Guide grid. Both inert under D-pad, so TV remote behaviour is unchanged.\n\n## Credits\n\nUltra TV — original work by [khalilbenaz](https://github.com/khalilbenaz). MIT-licensed.\n\nThe native Android TV codebase supersedes the earlier Capacitor WebView build (kept under `android-app/` and `web/` for historical reference — legacy, no releases produced from it, see [`android-app/README.md`](android-app/README.md)) — Compose-TV's focus tree gave reliable D-pad navigation on every box we tested, including the Mecool KM7 Plus where the WebView bridge approach struggled.\n\nIf you fork / repackage, please keep the credit visible in the About screen.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\n## Disclaimer\n\nUltra TV is an IPTV **client**, not a content provider. It does not include, host or distribute any stream. Use only playlists, EPG sources and credentials you are authorized to access in your jurisdiction.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhalilbenaz%2Fultra-tv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkhalilbenaz%2Fultra-tv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkhalilbenaz%2Fultra-tv/lists"}