Fredolx/open-tv
Ultra-fast, simple and powerful cross-platform IPTV app
Mixed signals — read the receipts
weakest axiscopyleft license (GPL-2.0) — review compatibility; no tests detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓4 active contributors
- ✓GPL-2.0 licensed
Show all 8 evidence items →Show less
- ✓CI configured
- ⚠Small team — 4 contributors active in recent commits
- ⚠Concentrated ownership — top contributor handles 78% of recent commits
- ⚠GPL-2.0 is copyleft — check downstream compatibility
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/fredolx/open-tv)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/fredolx/open-tv on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: Fredolx/open-tv
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Fredolx/open-tv shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Mixed signals — read the receipts
- Last commit 2w ago
- 4 active contributors
- GPL-2.0 licensed
- CI configured
- ⚠ Small team — 4 contributors active in recent commits
- ⚠ Concentrated ownership — top contributor handles 78% of recent commits
- ⚠ GPL-2.0 is copyleft — check downstream compatibility
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live Fredolx/open-tv
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/Fredolx/open-tv.
What it runs against: a local clone of Fredolx/open-tv — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in Fredolx/open-tv | Confirms the artifact applies here, not a fork |
| 2 | License is still GPL-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 47 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Fredolx/open-tv. If you don't
# have one yet, run these first:
#
# git clone https://github.com/Fredolx/open-tv.git
# cd open-tv
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of Fredolx/open-tv and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Fredolx/open-tv(\\.git)?\\b" \\
&& ok "origin remote is Fredolx/open-tv" \\
|| miss "origin remote is not Fredolx/open-tv (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"GPL-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is GPL-2.0" \\
|| miss "license drift — was GPL-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src-tauri/src/main.rs" \\
&& ok "src-tauri/src/main.rs" \\
|| miss "missing critical file: src-tauri/src/main.rs"
test -f "src-tauri/src/mpv.rs" \\
&& ok "src-tauri/src/mpv.rs" \\
|| miss "missing critical file: src-tauri/src/mpv.rs"
test -f "src-tauri/src/m3u.rs" \\
&& ok "src-tauri/src/m3u.rs" \\
|| miss "missing critical file: src-tauri/src/m3u.rs"
test -f "src-tauri/Cargo.toml" \\
&& ok "src-tauri/Cargo.toml" \\
|| miss "missing critical file: src-tauri/Cargo.toml"
test -f "package.json" \\
&& ok "package.json" \\
|| miss "missing critical file: package.json"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 47 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~17d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Fredolx/open-tv"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Fred TV (formerly Open TV) is a cross-platform IPTV streaming application built with Tauri (Rust backend) and Angular (TypeScript frontend) that enables users to import channels from M3U files, M3U links, or Xtream sources, and stream them with exceptionally low resource usage. It provides features like live recording, multi-source management, custom channels, and re-streaming capabilities, optimized for speed and minimal RAM footprint across Windows, macOS, Linux, iOS, and Android. Monorepo structure: Angular frontend in src/ using Material Design components and RxJS for state management; Rust backend in src-tauri/Cargo.toml handles core IPTV logic, streaming, and OS integration via Tauri 2.9+; desktop packaging via Tauri build system, mobile builds configured separately; static assets and configuration in src-tauri/capabilities/default.json.
👥Who it's for
Cord-cutting enthusiasts and IPTV users who want a lightweight, open-source, cross-platform streaming client that respects privacy; also appeals to developers maintaining IPTV infrastructure who need a performant playback application with re-streaming and recording capabilities.
🌱Maturity & risk
The project is actively developed and production-ready, with v1.9.1 released and distributed on multiple app stores (Microsoft Store, Flathub, AUR, Apple App Store, Google Play), indicating established stability. However, it appears to be maintained by a single developer (Fredolx) who explicitly requests financial support, which raises long-term sustainability concerns despite the mature feature set and multi-platform deployment.
Single-maintainer risk is acute—the developer explicitly states they maintain this alone and are 'in dire need of support'; dependency chain is moderate (~20 runtime deps in package.json) with Angular Material and Tauri as critical paths. No visible test suite in the file structure (karma config present but no test files listed), and reliance on external binaries (mpv, ffmpeg, yt-dlp) creates platform-specific fragility, particularly on macOS and older Linux distributions.
Active areas of work
Recent development includes rewrite for performance optimization (mentioned in README), multi-platform app store releases (Windows, Flathub, AUR, Apple, Google Play), and active CI/CD pipelines in .github/workflows/ for automated builds and Docker deployments. The project actively solicits financial support and GitHub sponsorships, indicating push toward sustainability.
🚀Get running
Clone and install:
git clone https://github.com/Fredolx/open-tv.git
cd open-tv
pnpm install
Then run locally:
pnpm start
For Tauri backend development, cd src-tauri && cargo build. Prerequisites: Node.js (pnpm 10.10.0+), Rust toolchain, mpv, ffmpeg, yt-dlp (brew on macOS, dnf on Fedora, pacman on Arch, apt on Debian).
Daily commands:
Development: pnpm start runs Angular dev server on localhost:4200. Full app with Tauri backend: pnpm build compiles and packages for target platform. For specific platforms: pnpm buildMac with environment variable APPLE_SIGNING_IDENTITY=J5GA8GVZ43 for universal macOS binary. Watch mode: pnpm watch for Angular changes.
🗺️Map of the codebase
src-tauri/src/main.rs— Tauri application entry point; initializes the desktop app, event handlers, and bridges Rust backend to Angular frontendsrc-tauri/src/mpv.rs— Core media player integration for MPV; handles video streaming and playback control across all platformssrc-tauri/src/m3u.rs— M3U playlist parser and processor; critical for loading and managing IPTV channel sourcessrc-tauri/Cargo.toml— Rust dependencies and Tauri configuration; defines all native capabilities and versioningpackage.json— Node.js and Angular build configuration; orchestrates frontend build and Tauri bridgeangular.json— Angular CLI configuration; defines compilation, asset handling, and build outputsrc-tauri/src/sql.rs— Database layer for persisting user data, playlists, and settings; critical for state management
🛠️How to make changes
Add a New IPTV Source Parser
- Create a new enum variant in
source_type.rs(e.g.,MyProvider) (src-tauri/src/source_type.rs) - Implement a parser module analogous to
m3u.rsorstalker.rsthat exports aparse_url()function returning aVec<Channel>(src-tauri/src/[new_parser].rs) - Register the new parser in
main.rsas a Tauri command:#[tauri::command] async fn parse_[provider](...) -> Result<...>(src-tauri/src/main.rs) - Insert parsed channels into the database via
sql.rsusinginsert_channels()or similar methods (src-tauri/src/sql.rs)
Add a New User Setting (Preference)
- Add a new field to the relevant struct in
settings.rsand implement serialization/deserialization (src-tauri/src/settings.rs) - Expose a Tauri command in
main.rslike#[tauri::command] fn get_settings() -> Settingsand#[tauri::command] fn set_setting(key: String, value: String)(src-tauri/src/main.rs) - Update the database schema in
sql.rsto persist the new setting in the settings table (src-tauri/src/sql.rs) - Call the Tauri command from your Angular component to read/write the setting (
src/app/[component]/[component].component.ts)
Modify MPV Player Behavior
- Adjust MPV property bindings or event handlers in the
Mpvstruct implementation (src-tauri/src/mpv.rs) - Expose new player control as a Tauri command in
main.rs(e.g.,#[tauri::command] async fn set_playback_speed(speed: f32)) (src-tauri/src/main.rs) - Emit state events via
emit_to_frontend()or app.emit() so the Angular UI stays synchronized (src-tauri/src/main.rs) - Subscribe to player events in Angular components via Tauri event listener (
src/app/[component]/[component].component.ts)
Add a New UI Tab or Page
- Generate a new Angular component using
ng generate component tabs/[new-tab](src/app/tabs/[new-tab]/[new-tab].component.ts) - Add the component to your main routing module and navigation menu (
src/app/app.routes.ts) - Create Tauri commands in
main.rsto fetch data specific to this tab (if needed) (src-tauri/src/main.rs) - Use the Angular Material components (buttons, lists, etc.) for consistent UI design (
src/app/tabs/[new-tab]/[new-tab].component.html)
🔧Why these technologies
- Tauri (Rust + WebView) — Provides lightweight, native cross-platform desktop app with smaller bundle than Electron; Rust backend ensures memory safety and performance for media handling
- Angular 17 + Material Design — Modern, componentized UI framework with rich Material component library for consistent, responsive interface across desktop and mobile web
- SQLite — Embedded database requires no external server; fast local query performance for channel data, history, and user preferences
- MPV Player — Lightweight, widely-compatible media player supporting HLS, DASH, HTTP streams, and many codecs; integrates easily via CLI/library
- M3U/XMLTV Parsing — Industry-standard playlist and EPG formats for IPTV; simple text-based protocols enable broad provider compatibility
⚖️Trade-offs already made
- Rust backend + Angular frontend over monolithic framework
- Why: Rust provides memory safety and speed for media operations; Angular offers rapid UI iteration and rich components
- Consequence:
🪤Traps & gotchas
Platform-specific binary dependencies: mpv, ffmpeg, yt-dlp must be installed separately on macOS (brew), Fedora (dnf + rpmfusion), and older Linux distros (backport yt-dlp recommended); Windows .msi bundles mpv but this can cause version conflicts. macOS signing: buildMac script requires APPLE_SIGNING_IDENTITY env var (J5GA8GVZ43 hardcoded in package.json); builds will fail without proper certificate setup. Package manager: project requires pnpm 10.10.0+ (not npm/yarn); installing with npm will fail. Tauri version mismatch: src-tauri/Cargo.lock locks specific Tauri versions; upgrading @tauri-apps packages in package.json without updating Cargo.lock causes IPC breakage. Single-developer maintenance: active CI/CD but no visible automated tests (karma/jasmine config present but test files not listed in top 60); code review and breaking-change detection minimal.
🏗️Architecture
💡Concepts to learn
- Tauri IPC (Inter-Process Communication) — Fred TV bridges TypeScript frontend and Rust backend via Tauri's IPC protocol; understanding command invocation, serialization, and capability-based security model (src-tauri/capabilities/default.json) is essential for any backend feature addition.
- M3U (M3EXTINF) Playlist Format — Core data format for IPTV channel imports; parsing M3U files and extracting metadata (channel name, logo URL, group) is fundamental to the app's data pipeline.
- Xtream Codes API — Alternative IPTV source format supported by the app; understanding username/password authentication, get_live_categories, and get_live_streams endpoints is required for source-parsing features.
- RxJS Reactive Programming — Angular frontend uses RxJS 7.8 for state management and async UI updates (no Redux); understanding Observables, Subjects, and operators is mandatory for component development.
- Cross-platform binary bundling (Tauri) — Fred TV depends on external binaries (mpv, ffmpeg, yt-dlp) and must locate them at runtime across Windows, macOS, Linux; understanding Tauri's plugin system and shell invocation is critical for reliability.
- Capability-Based Security (Tauri model) — src-tauri/capabilities/default.json controls which Rust backend functions are exposed to the Angular frontend; this prevents unauthorized OS access and is essential for auditing security.
- HLS (HTTP Live Streaming) & MPEG-TS — Underlying stream protocols that mpv/ffmpeg decode; understanding playlist structures, segment handling, and codec negotiation helps debug playback and recording failures.
🔗Related repos
xbmc/kodi— Industry-standard open-source media center for IPTV and streaming; architectural peer with similar multi-platform desktop/TV focus and custom channel support.iptv-org/iptv— Community-maintained IPTV channel database and M3U playlists; this app's primary data source and distribution partner for channel imports.tauri-apps/tauri— Core framework underlying Fred TV's desktop/mobile architecture; understanding Tauri's IPC model and security model essential for backend modifications.angular/angular— Frontend framework (v17.3); source for Material Design components and Angular CLI tooling used throughout src/.rclone/rclone— Similar single-developer, cross-platform Rust CLI tool; demonstrates sustainable patterns for maintaining multi-OS Rust applications at scale.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add Cargo-based Rust unit tests for src-tauri backend with CI workflow
The repository has a Tauri backend (src-tauri/Cargo.toml) but no visible test files or Rust testing in the CI workflows. Only buildAndUpload.yml and buildDocker.yml exist, neither running Rust tests. This is critical for a cross-platform app where backend reliability affects all distributions (Windows, macOS, Linux, Android, iOS).
- [ ] Create src-tauri/tests/ directory with integration tests for core Tauri commands
- [ ] Add unit tests within src-tauri/src/ modules using #[cfg(test)] blocks
- [ ] Create .github/workflows/rustTests.yml to run 'cargo test' on PR and push events
- [ ] Ensure workflow runs on ubuntu-latest, macos-latest, and windows-latest for platform-specific behavior
- [ ] Document testing in contributing guide or README
Add end-to-end tests for Angular UI using Cypress or Playwright with CI integration
The project has Angular 17 frontend with Material UI and keyboard shortcuts (ng-keyboard-shortcuts), but no E2E tests in package.json or .github/workflows. With Tauri-based desktop/mobile distribution, UI regression testing across platforms is essential. Current CI only runs builds, not functional validation.
- [ ] Install and configure Cypress (or Playwright) as devDependency
- [ ] Create cypress/e2e/ directory with tests for: navigation, channel loading, playback controls, keyboard shortcuts (from ng-keyboard-shortcuts)
- [ ] Create .github/workflows/e2eTests.yml to run Cypress against 'ng serve' with 'npm run tauri dev'
- [ ] Add 'test:e2e' script to package.json
- [ ] Test in headless mode for CI, ensure tests cover main user flows (add channel, play channel, search)
Add TypeScript strict mode compliance and linting workflow
Angular 17 project uses TypeScript 5.4.2 but no tsconfig strict mode enforcement or ESLint setup visible in package.json. With multi-platform code (Tauri + Angular) and cross-platform distribution, type safety and code consistency prevent bugs across Windows, macOS, Linux, and mobile builds. No linting workflow in .github/workflows.
- [ ] Update tsconfig.json to enable strict mode: 'strict': true, 'noImplicitAny': true, 'strictNullChecks': true
- [ ] Install ESLint + @angular-eslint as devDependencies (or use existing Angular linter)
- [ ] Create .eslintrc.json with rules for Angular/TypeScript style consistency
- [ ] Add 'lint' script to package.json ('ng lint' or 'eslint src/')
- [ ] Create .github/workflows/lint.yml to run linting on all PRs
- [ ] Fix existing violations and document in CONTRIBUTING.md
🌿Good first issues
- Add unit tests for IPTV source parsing: The top-level file list lacks test files (.spec.ts) for Angular components and no visible Rust tests in src-tauri/. Create tests in src/**/*.spec.ts for M3U parsing, channel filtering, and Xtream API integration to improve reliability and onboard contributors to the codebase.
- Document Tauri IPC command reference: src-tauri/capabilities/default.json defines available backend commands but no corresponding documentation exists (no docs/ directory visible). Create markdown file listing all IPC commands, their parameters, and examples so frontend developers understand the bridge protocol.
- Implement keyboard shortcut help overlay: ng-keyboard-shortcuts 13 is included but no visual help screen exists for TV remote users. Add a keybindings help component (modal with .component.ts/.html in src/) that displays available shortcuts; wire it to the keyboard shortcut library and document in README.
⭐Top contributors
Click to expand
Top contributors
- @Fredolx — 78 commits
- @schizo99 — 18 commits
- @guihkx — 3 commits
- @jeffsmith82 — 1 commits
📝Recent commits
Click to expand
Recent commits
1bfa78a— Merge pull request #422 from Fredolx/expiry (Fredolx)8663d77— remove seconds, minutes (Fredolx)0f34ea8— expiry (Fredolx)9a40cc5— Merge pull request #416 from Fredolx/add-copy-url (Fredolx)a9b69aa— add copyurl (Fredolx)c56f90a— fix <=1.9.0 favs not restoring (Fredolx)e62e580— Merge pull request #371 from Fredolx/fix-params (Fredolx)12fb390— fix mpv params (Fredolx)d98bb96— Merge pull request #361 from Fredolx/potential-linux-improvement (Fredolx)8b967b6— add unsafe block (Fredolx)
🔒Security observations
- High · Hardcoded Apple Signing Identity —
package.json - buildMac script. The buildMac script contains a hardcoded Apple signing identity (J5GA8GVZ43) in the package.json file. This exposes sensitive build configuration and could potentially be used to forge signed applications. Fix: Move the APPLE_SIGNING_IDENTITY to environment variables or a secure secrets management system. Use CI/CD platform secrets instead of committing to the repository. - High · Insecure Docker Build - npm install without lockfile verification —
Dockerfile - RUN npm install. The Dockerfile uses 'npm install' without explicitly verifying package integrity against the lock file. With both package-lock.json and pnpm-lock.yaml present, there's potential for dependency confusion attacks or unverified package installation. Fix: Use 'npm ci' instead of 'npm install' to enforce strict dependency versions from the lock file. Explicitly specify which lock file to use and verify package integrity. - High · Unverified Script Execution in Docker Build —
Dockerfile - curl commands for Node.js and Rustup. The Dockerfile downloads and executes installation scripts via curl without verification: Node.js setup script and Rust installer. These could be intercepted or compromised. Fix: Verify checksums of downloaded scripts before execution. Use official Docker images or base images that include pre-installed tools. Add hash verification: curl ... | sha256sum -c - && bash - Medium · Overly Permissive Dependency Versions —
package.json - all dependencies. Dependencies use caret (^) versioning which allows minor and patch version updates automatically. This increases the risk of pulling in vulnerable transitive dependencies without control. Fix: Use tilde (~) versioning or exact versions for critical security packages. Implement automated dependency scanning with tools like npm audit, Snyk, or dependabot to monitor for vulnerabilities. - Medium · Missing HTTPS Verification in Curl Commands —
Dockerfile - nodejs setup script curl. While curl commands use --proto and --tlsv1.2 flags, the Node.js setup script uses a pipe without verification. If the source is compromised, arbitrary code could execute with root privileges in the container. Fix: Add --fail flag to curl and verify GPG signatures or checksums of downloaded scripts. Consider using official package repositories instead of curl piping. - Medium · Build Artifacts Exposed in Runtime Container —
Dockerfile - COPY and installation of mesa/gpu packages. The Dockerfile copies compiled .deb files but doesn't verify their integrity. The runtime container has elevated capabilities with mesa-utils, libgl1, and direct GPU access which could be leveraged if the application is compromised. Fix: Implement signature verification for the .deb package. Minimize runtime dependencies and consider running the application with restricted capabilities/seccomp profiles. - Medium · Missing Security Headers Configuration —
src-tauri/capabilities/default.json (not reviewed in detail). No evidence of Content Security Policy (CSP), X-Frame-Options, or other security headers in the Tauri application configuration. This could increase XSS vulnerability impact. Fix: Implement strict CSP headers in Tauri's tauri.conf.json. Restrict allowed origins, scripts, and styles to prevent XSS attacks. - Low · Debian Package Manager Uses HTTP Fallback —
Dockerfile - RUN apt update. The Dockerfile relies on apt which may use HTTP mirrors in some configurations. Network traffic could be intercepted during package installation. Fix: Configure apt to only use HTTPS mirrors. Add 'Apt::Protocols::https "true";' and similar directives in apt configuration. - Low · No Security Updates in Base Image —
Dockerfile - FROM debian:trixie-slim. Uses 'debian:trixie-slim' without a specific pinned version or timestamp. The image might be rebuilt with outdated packages if not frequently refreshed. Fix: Use image digests for reproducible builds: FROM debian:trixie-slim@sha256:... or implement image scanning as part of CI/CD pipeline. - undefined · undefined —
undefined. undefined Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.