An open API service indexing awesome lists of open source software.

https://github.com/gabrielmaialva33/streamix-tv

📺 Smart TV streaming app built with Lightning 3 + SolidJS for Tizen, webOS, Android TV and Fire TV. Personalized rails, semantic search and native IME.
https://github.com/gabrielmaialva33/streamix-tv

android-tv fire-tv iptv lightningjs samsung-tv smart-tv solidjs streaming ten-foot-ui tizen typescript vite webgl webos

Last synced: about 1 month ago
JSON representation

📺 Smart TV streaming app built with Lightning 3 + SolidJS for Tizen, webOS, Android TV and Fire TV. Personalized rails, semantic search and native IME.

Awesome Lists containing this project

README

          




Streamix TV


Streamix TV



A cinematic 10-foot streaming client built with LightningJS + SolidJS, targeting Samsung Tizen, LG webOS, Android TV, and Fire TV. The TV companion to the Streamix platform.


LightningJS
SolidJS
TypeScript
Vite
Tizen
webOS
Android TV
Fire TV
hls.js
License


Streamix TV — Home screen on a Samsung smart TV


Highlights   |   
Architecture   |   
Runtime Surfaces   |   
Stack   |   
Quick Start   |   
Project Notes


> [!NOTE]
> This repository contains only the Smart TV client. The Phoenix + LiveView backend, APIs, and web surface live in the
> [Streamix](https://github.com/gabrielmaialva33/streamix) repository.

## :sparkles: Highlights

### Native-feel TV Experience

- **10-foot UI** optimized for D-pad and remote navigation
- **WebGL rendering** via LightningJS for 60fps animations on low-power TV SoCs
- **Hero carousel, row-based browsing**, and cinematic focus transitions
- **Fast channel switching** with pre-buffered HLS streams
- **Exit dialog, skeleton loaders**, and scroll indicators tuned for TV ergonomics
- **MSDF fonts** (NotoSans with full PT-BR diacritics coverage) for crisp type on any screen

### Streamix-Connected

- **Auth** with session persistence in TV-local storage
- **Live TV, movies, and series** browsing with remote catalog paging
- **Favorites and watch history** synced with the backend, optimistic UI with rollback
- **Continue watching row** with server-side progress tracking
- **EPG now / next** for live channels
- **Semantic search** when the backend has Qdrant + Gemini configured
- **Playback telemetry** for bitrate, position, and error tracking

### Cross-Device Builds

- **Samsung Tizen** (`.wgt` packaging with certificate signing + `sdb` deploy)
- **LG webOS** (`.ipk` packaging through the webOS TV CLI)
- **Android TV and Fire TV** through a Capacitor Android shell fed by the Fire TV Vite target
- **Device config plugin** that swaps polyfills and feature flags per target
- **Log server** over WebSocket for live debugging on TV hardware

## :fire: Why Streamix TV Feels Different

Streamix TV is not a wrapped web app running in a TV browser. It renders through WebGL with LightningJS, which means the
UI is a scene graph of textures rather than a DOM tree. Focus traversal, animations, and list virtualization are all
built for the constraints of TV hardware (limited GPU, slow CPU, remote latency).

The app is opinionated about what makes a good TV experience: no hover, no scroll, no hidden menus. Everything is
focus-driven, everything has a visible selection state, and every screen answers the "what can I press next" question
without guessing.

## :art: Architecture

### High-Level View

```mermaid
graph TD
R[Remote Control]

subgraph TVApp["Streamix TV (LightningJS + SolidJS)"]
AS[AppShell]
ML[MainLayout + Sidebar]
RT[Router]
FM[Focus Manager]
PL[Player + hls.js]
API[API Client]
STG[Storage / Session]
end

subgraph Pages["Pages"]
HM[Home / Hero]
MV[Movies]
SR[Series]
CH[Channels]
GD[Guide / EPG]
FV[Favorites]
SC[Search]
DT[Movie / Series Detail]
end

subgraph Platform["Platform Layer"]
TZ[Tizen Device Config]
LG[webOS Device Config]
WEB[Web / Dev]
end

subgraph Backend["Streamix Backend"]
AUTH[Auth API]
CAT[Catalog API]
HST[History + Favorites]
EPG[EPG API]
TEL[Telemetry API]
STR[Signed Stream URLs]
end

R --> FM
FM --> AS
AS --> ML
ML --> RT
RT --> Pages
Pages --> API
Pages --> PL
API --> AUTH
API --> CAT
API --> HST
API --> EPG
API --> TEL
PL --> STR
STG --> API
AS --> Platform
```

### Playback Flow

```mermaid
sequenceDiagram
participant User as User + Remote
participant UI as Page / Detail
participant API as API Client
participant Token as Backend StreamToken
participant HLS as hls.js / Native
participant TV as TV Video Pipeline

User->>UI: Press OK on title
UI->>API: Request signed stream URL
API->>Token: POST /catalog/.../stream
Token-->>API: Signed HLS URL
API-->>UI: Playable URL
UI->>HLS: Attach source
HLS->>TV: Feed segments
TV-->>User: Picture
UI->>API: Post playback telemetry (progress, bitrate)
```

Core modules worth knowing

| Area | Main modules |
| ---------------- | ------------------------------------------------------------------ |
| App shell | `src/app/AppShell.tsx`, `src/app/bootstrap.tsx`, `routes.tsx` |
| Layout + nav | `src/app/MainLayout.tsx`, `src/components/Sidebar.tsx` |
| Pages | `src/pages/Home.tsx`, `Movies.tsx`, `Series.tsx`, `Guide.tsx`, ... |
| UI primitives | `src/components/Card.tsx`, `Hero.tsx`, `Row.tsx`, `ExitDialog.tsx` |
| Player | `src/features/player/` (hls.js integration, telemetry) |
| Auth | `src/features/auth/LoginPage.tsx`, `RequireAuth.tsx` |
| API client | `src/lib/api.ts`, `src/lib/storage.ts` |
| Device targeting | `devices/tizen/`, `devices/lg/`, `devices/common/` |
| Fonts | `src/fonts.ts` (NotoSans MSDF) |

## :tv: Runtime Surfaces

### Pages

- `/` home with hero + continue watching + curated rows
- `/login` session + register
- `/movies`, `/series`, `/channels`
- `/movies/:id`, `/series/:id` detail with cast, seasons, episodes
- `/guide` EPG now / next for live channels
- `/favorites`
- `/search` with semantic + fulltext
- `/player/:type/:id` full-screen playback

### Focus Model

- Sidebar is the root focus column; pages mount a `MainLayout` that forwards focus to their first row
- Rows implement horizontal D-pad traversal; columns implement vertical
- `ExitDialog` captures the back key on the home screen instead of closing the app blindly

## :computer: Stack

### Runtime

| Technology | Version | Role |
| ---------------------- | --------- | ------------------------------------------------- |
| LightningJS Renderer | `^3.0.1` | WebGL scene graph and rendering |
| @lightningtv/solid | `^3.1.18` | SolidJS bindings for Lightning |
| SolidJS | `^1.9.12` | Reactive UI primitives |
| @solidjs/router | `^0.16.1` | Client-side routing |
| hls.js | `^1.6.16` | Adaptive streaming in browsers without native HLS |
| @solid-primitives/i18n | `^2.2.1` | Internationalization |

### Tooling

| Technology | Role |
| ----------------- | -------------------------------------------- |
| Vite 8 | Dev server, build, legacy target for old TVs |
| TypeScript 6 | Types across app, components, API |
| ESLint + Prettier | Lint + format |
| Vitest | Unit + browser tests via Playwright |
| Storybook | Isolated component development |

### Target Platforms

| Platform | Status | Notes |
| ------------- | --------- | --------------------------------------------------------- |
| Samsung Tizen | supported | `.wgt` packaging, `sdb` install, certificate `StreamixTV` |
| LG webOS | supported | `TARGET_DEVICE=lg` build, `appinfo.json`, `.ipk` package |
| Android TV | supported | Capacitor Android shell, Chromium WebView |
| Fire TV | supported | Fire TV Vite target copied into the Android shell |
| Browser | dev only | Used for iteration via `pnpm start` |

## :package: Quick Start

### Prerequisites

- Node.js 20+
- pnpm 9+
- A running Streamix backend (see [Streamix repo](https://github.com/gabrielmaialva33/streamix))
- For Tizen: Tizen Studio CLI + certificate profile `StreamixTV`
- For webOS: webOS TV CLI (`ares-package`, `ares-install`) when packaging or deploying
- For Fire TV / Android TV: Android SDK, Java 21, Capacitor CLI, and `adb`

### 1. Install

```bash
pnpm install
```

### 2. Configure environment

Create an `.env` based on `environments/` defaults. Typical values:

```dotenv
VITE_API_URL=https://your-streamix-host/api/v1
VITE_API_KEY=your-streamix-api-key
```

### 3. Run in the browser

```bash
pnpm start
```

Opens on [http://localhost:5173](http://localhost:5173) with hot reload. Arrow keys + Enter behave like a remote.

### 4. Build and package targets

```bash
pnpm build:tizen # dist/tizen/ + Tizen config.xml
pnpm build:webos # dist/lg/ + webOS appinfo.json
pnpm build:firetv # dist/firetv/ for Capacitor Android

pnpm tizen:package # creates a .wgt from dist/tizen/
pnpm webos:package # creates an .ipk from dist/lg/
pnpm firetv:apk # syncs dist/firetv/ into android/ and builds debug APK
```

Target orchestration lives in `scripts/platform.mjs`. Platform manifests live under `platforms/` and are copied into the
matching `dist/` folder after Vite builds, so Tizen/webOS metadata does not leak into generic web or Android packages.
For Tizen, packaging follows the Samsung TV CLI flow: Vite build -> copy `config.xml` -> `tizen build-web` ->
`tizen package` from `.buildResult`.

### 5. Deploy to Tizen (TV or emulator)

```bash
# Physical TV. Override TIZEN_DEVICE_IP or TIZEN_TARGET when needed.
pnpm tizen:deploy

# Samsung emulator
pnpm tizen:deploy:emu
```

That pipeline runs `build:tizen` -> `tizen:package` -> `tizen:install` -> `tizen:run`.

### 6. Live device logs

```bash
# Tizen device logs. Set TIZEN_DEVICE_IP or TIZEN_TARGET when needed.
pnpm tizen:logs

# Restart the app in Tizen Web Inspector mode and open DevTools.
pnpm tizen:debug

# WebSocket log relay from the TV into your terminal
pnpm logs
```

Useful Tizen debug variables:

```bash
TIZEN_DEVICE_IP=192.168.1.6 pnpm tizen:debug
TIZEN_TARGET=emulator-26101 pnpm tizen:logs
TIZEN_APP_ID=EI8qhrd7xh.streamix pnpm tizen:inspect:restart
```

Device build matrix

| Command | Target | Output | Package source |
| ------------------- | -------------------- | -------------- | ---------------------------------- |
| `pnpm build` | generic web | `dist/` | none |
| `pnpm build:tizen` | Samsung Tizen | `dist/tizen/` | `platforms/tizen/config.xml` |
| `pnpm build:webos` | LG webOS | `dist/lg/` | `platforms/webos/appinfo.json` |
| `pnpm build:firetv` | Fire TV / Android TV | `dist/firetv/` | `capacitor.config.ts` + `android/` |

## :wrench: Developer Commands

```bash
pnpm start # dev server, browser
pnpm start:tizen # dev server with Tizen polyfills
pnpm platform -- build tizen
pnpm platform -- build webos
pnpm platform -- build firetv
pnpm test # vitest
pnpm tsc # type-check only
pnpm lint # eslint
pnpm lint-fix # eslint --fix
pnpm format # prettier --write
pnpm storybook # component workbench
pnpm build:analyze # bundle visualizer

pnpm tizen:install # install last .wgt
pnpm tizen:run # launch app on TV
pnpm tizen:debug # restart app in Web Inspector mode
pnpm tizen:logs # stream Tizen dlog filters
pnpm tizen:kill # kill app on TV
pnpm tizen:uninstall # remove app from TV
pnpm webos:package # package dist/lg/ with ares-package
pnpm firetv:apk # build Android debug APK from dist/firetv/
```

## :memo: Project Notes

- The app is pinned to `@lightningtv/solid@3.1.18` because 3.2.x calls `animateProp`, which the pinned renderer `3.0.x`
does not expose. Do not bump solid bindings without also bumping the renderer.
- MSDF fonts are required; the Tizen 4 Chromium (M56) cannot `fetch` `file://` URLs, so the font config uses relative
URLs and registers NotoSans with explicit style/stretch descriptors.
- All code and comments are English-only; pt-BR is reserved for chat and commit messages.
- The signed stream URL returned by the backend requires `X-API-Key` on the final request; the player must inject it.
- Focus flow follows the `solid-demo-app` pattern: `App` → `MainLayout` → pages with a `forwardFocus` callback.

## :handshake: Contributing, License

- [AGENTS.md](AGENTS.md)
- [LICENSE](LICENSE)
- [NOTICE](NOTICE)



Gabriel Maia


Crafted by Gabriel Maia

gabrielmaialva33@gmail.com ·
GitHub