Skip to content

Repository files navigation

TagFlix Logo

TagFlix

⚠️ Under Active Development — This project is a work in progress. Expect breaking changes, incomplete features, and bugs.

An open-source, community-driven media aggregator with a Netflix-style interface. Built with Tauri v2 + React + Vite, featuring a built-in web player with full playback controls.

License: GPL v3

Features

  • Horizon-inspired UI — Top navbar with tabs and scroll auto-hide, crossfade hero carousel, catalog hub with genre/sort filters (Discover), full-width search with history suggestions, redesigned cards with hover-play
  • Built-in web player — HTML5 + hls.js playback (VixSrc) with a settings menu (quality, playback speed, audio, captions), server selection, ±10s skip, prev/next episode, and fullscreen. Optional switch to VidSrc / CineSrc embedded players.
  • Playback controls — Play/Pause, seek, volume/mute, fullscreen, quality menu, subtitle menu
  • VixSrc streaming — All video playback is resolved through VixSrc (vixsrc.to) and played in the built-in web player. No addons or debrid required.
  • Music — Search songs, albums and artists (via Piped), with full artist album lists (years, newest first) and album tracks scraped directly from YouTube Music. Playback runs through the hidden YouTube IFrame Player with prev/next, seek and a persisted volume slider.
  • Server-side TMDB proxy — Metadata (trending, popular, genres, search, details) is fetched through the Rust backend via Tauri IPC, with the API key kept out of the webview and 1-hour in-memory caching to cut API quota.
  • Customizable — 12 accent colors, 6 theme skins, persisted via localStorage
  • TV remote navigation — Spatial D-pad navigation (directional focus), visible focus rings, auto-focus and media-key support for Android TV / Firestick remotes
  • Android — Builds as a single universal APK for phones, Android TV and Firestick
  • Favourites — Save media locally with localStorage persistence

Architecture

┌───────────────────────────────────────────────┐
│               Tauri v2 Desktop App             │
│  ┌─────────────────────────────────────────┐  │
│  │   React SPA (Vite) — WebView            │  │
│  │   Port 5173 (dev) / dist/ (production)  │  │
│  │                                          │  │
│  │   ┌─── WebPlayer (hls.js) ─────────┐    │  │
│  │   │  Play/Pause · Seek · Volume     │    │  │
│  │   │  Quality · Subtitles · Fullscreen│    │  │
│  │   └──────────────────────────────────┘    │  │
│  │                        ▲                  │  │
│  │         resolve_vixsrc (Rust backend)      │  │
│  └─────────────────────────────────────────┘  │
└───────────────────────────────────────────────┘
  • Frontend SPA (src/) — Vite-powered React application with Tailwind CSS. Video plays in a <video> element via hls.js inside the WebView.
  • Web playerWebPlayer component plays the VixSrc HLS master playlist directly in the browser (VixSrc serves CORS-enabled playlists/segments), avoiding server-side CDN throttling.
  • Streamingresolve_vixsrc (Rust backend) resolves a direct HLS master playlist through VixSrc's 3-step flow; the web player then handles playback.

Tech Stack

Layer Technology
Shell Tauri v2 (WebView2 on Windows, Android WebView)
UI framework React 18 + Vite 5
Styling Tailwind CSS
Video engine HTML5 + hls.js (in-webview)
Player Custom WebPlayer React component (quality, subtitles, fullscreen)
Music search Piped API (public instances with fallback + live list refresh)
Music playback YouTube IFrame Player (hidden audio player)
Media metadata TMDB API (server-side proxy via Rust backend, in-memory cache)
Streaming VixSrc (vixsrc.to) — direct HLS resolved by the Rust backend

Getting Started

Prerequisites

  • Node.js 18+
  • Rust (latest stable)
  • npm
  • For Android builds: JDK 17 + Android SDK/NDK (see "Build for Android")

Install

git clone https://github.com/Wookiee-/tagflix.git
cd tagflix
npm install

Development

npm run tauri dev

This starts both the Vite dev server and the Tauri desktop app with hot-reload.

Build for Production

npm run tauri build

Output will be in src-tauri/target/release/.

Build for Android (phones / Android TV / Firestick)

Prerequisites: JDK 17, Android SDK (platform + build-tools + NDK), with JAVA_HOME, ANDROID_HOME and ANDROID_SDK_ROOT set.

npx tauri android init                    # once — generates src-tauri/gen/android
npx tauri android build --apk --target aarch64   # signed release APK

The signed release APK is written to src-tauri/gen/android/app/build/outputs/apk/universal/release/. Debug APKs (auto-signed, for quick sideloading) are built with --debug.

Signing: tauri android build signs with the keystore configured in src-tauri/gen/android/keystore.properties (gitignored). Keep the keystore file safe — the same key is required for future updates to install smoothly.

Music

  • Search — Songs / Albums / Artists tabs, backed by Piped's music_* search filters. The public instance list is refreshed dynamically from the Piped docs and tried in order until one responds.
  • Artists — The real album list (with years, newest first) is scraped from the artist's YouTube Music channel page — no more partial/incorrect results.
  • Albums — Track lists come from the YouTube playlist page, or the YouTube Music innertube API for album ids.
  • Playback — A hidden YouTube IFrame Player plays each track; the now-playing bar has play/pause, previous/next, seek and a volume slider (persisted).

Configuration

API Keys

Copy .env.example to .env and fill in your API keys:

cp .env.example .env

Edit .env with your API keys:

# TMDB API — SERVER-SIDE ONLY. Never prefix with VITE_ (that would bundle the
# key into the frontend and expose it to clients). Read by the Rust backend.
TMDB_API_KEY=your_tmdb_api_key
# TMDB_ACCESS_TOKEN=your_tmdb_v4_read_access_token

VITE_TRAKT_CLIENT_ID=your_trakt_client_id

All TMDB requests are proxied through the Rust backend via Tauri IPC, so your key never reaches the webview. List responses (trending, popular, genres, discover) are cached in memory for 1 hour to cut API quota usage.

If no key is configured, the app automatically falls back to a set of public shared TMDB keys (with automatic rotation on 401/403) so it works out of the box — your own key always takes priority.

Streaming

Playback uses a selectable player / source (Settings → Player):

  • Web Player (VixSrc) — the built-in hls.js player. VixSrc HLS is resolved directly through the Rust backend and played in the browser with resolution/subtitle defaults, server selection (Server1/Server2), skip buttons, and a fullscreen settings menu.
  • VidSrc (vidsrc.tw) — VidSrc's own embedded player in a full-screen iframe.
  • CineSrc (cinesrc.st) — CineSrc's own embedded player in a full-screen iframe, honoring the default resolution setting.

No addons, API keys, or debrid services are required.

Project Structure

tagflix/
  src-tauri/                Tauri v2 Rust backend
    src/
      lib.rs                Main library with IPC commands
      main.rs               Entry point
      tmdb.rs               Server-side TMDB proxy with in-memory cache
      vixsrc.rs             VixSrc stream resolver (direct HLS)
      piped.rs              Piped API client (music search, dynamic instances)
      youtube.rs            YouTube playlist / artist / album scraping
      trakt.rs              Trakt API integration
    capabilities/
      default.json          Tauri permissions (window, fullscreen)
    gen/android/            Generated Android project (gradle, AndroidManifest)
  src/                      React SPA frontend
    components/
      WebPlayer.jsx         HTML5 + hls.js player (quality, subtitles, fullscreen)
      MediaCard.jsx         Media card with hover-play overlay
      MediaGrid.jsx         Grid layout for media items
      SplashScreen.jsx      Startup splash screen
      ErrorBoundary.jsx     React error boundary
    hooks/
      useTagflix.js         Main app state hook
      useTVNavigation.jsx   Spatial D-pad navigation for TV remotes
    pages/
      Home.jsx              Landing page with hero carousel + catalog rows
      Detail.jsx            Media detail page (Play resolves VixSrc stream)
      Player.jsx            Route wrapper for WebPlayer
      Music.jsx             Music search + player (YouTube IFrame Player)
      Discover.jsx          Catalog hub (type/sort/genre filters, infinite scroll)
      Movies.jsx            Movies browse page
      TVShows.jsx           TV shows browse page
      Search.jsx            Search with history suggestions
      Favourites.jsx        Saved favourites
      Settings.jsx          App settings
    services/
      api.js                Tauri IPC bridge
      tmdbApi.js            TMDB client (via IPC proxy)
      continueWatching.js   Resume progress for the home "Continue Watching" row
  public/                   Static assets

Keyboard Shortcuts

Key Action
Space / K Play/Pause
Arrow Left Skip back 10 seconds
Arrow Right Skip forward 10 seconds
Arrow Up Volume up
Arrow Down Volume down
M Toggle mute
F Toggle fullscreen

License

This project is licensed under the GNU General Public License v3.0.

About

Netflix/Stremio-style desktop media aggregator with a native libmpv player built with Tauri + React

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages