2 Commits

Author SHA1 Message Date
be-nj
e66c8a863b Overlay readability on bright video: brighter times, translucent progress track
Some checks failed
Build TV app / build (push) Failing after 2s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-26 01:32:34 +02:00
be-nj
ca401e8ca3 README for humans: German, screenshots, install guide
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-26 01:30:29 +02:00
6 changed files with 74 additions and 43 deletions

107
README.md
View File

@@ -1,49 +1,80 @@
# Castarr
Native Google TV client for a [Dispatcharr](https://github.com/be-nj/Dispatcharr)
backend: live IPTV with a full D-pad UI (Compose for TV), login via the OIDC
device flow (Authentik), per-user favorites, per-stream output profiles, and
an optional phone remote paired by QR code — served by the TV itself, no phone
app install.
**Live-TV auf dem Fernseher, eingerichtet in einer Minute — alles läuft übers Handy.**
## Features
Castarr ist eine App für Google TV / Android TV. Auf dem Fernseher muss nie
etwas getippt werden: Zum Einrichten scannt man einmal einen QR-Code mit dem
Handy, meldet sich dort an — fertig. Danach zappt man mit der normalen
TV-Fernbedienung oder steuert alles bequem vom Handy aus.
- **Live TV** channel list with Now/Next EPG and progress, zapping via
channel/D-pad keys, fullscreen playback (ExoPlayer, HLS + MPEG-TS) with a
minimal auto-hiding overlay
- **Login without typing**: the TV shows a QR code and a user code; confirm on
your phone at your identity provider (OIDC device authorization grant). The
only thing entered on the TV is the Dispatcharr URL.
- **Dispatcharr source**: channels, groups and EPG via the fork's
Bearer-authenticated API; favorites are stored per user on the backend
(long-press a channel to star it, filter chip in the list)
- **Stream profiles**: pick Standard / Passthrough / audiofix / 720p (list
comes from the backend) — applied per stream request
- **Generic source fallback**: any M3U (+ optional XMLTV) URL works without a
login — ErsatzTV, Threadfin, Tunarr, plain playlists
- **Phone remote** (optional): scan the QR under Einstellungen; play/pause,
zapping, volume, channel list with Now/Next and favorite toggling in the
browser — no app install, rate-limited pairing code as fallback
- Physical remote keys and Google Assistant keep working (Media3
MediaSession, TV app quality guidelines TV-PC/TV-PP/TV-VC)
![Senderliste](docs/screenshots/senderliste.png)
## Building
## Was die App kann
Requires JDK 17+ and the Android SDK (platform 35). A JDK toolchain is
resolved automatically (foojay) if the host only has a JRE.
- **Senderliste mit Logos und Programm** — was gerade läuft, wie lange noch,
was danach kommt. Gruppen und Favoriten links, Sender rechts.
- **Zappen wie früher** — Nummerntasten auf der Fernbedienung schalten direkt
um (mit großer Anzeige, welcher Sender gleich kommt), hoch/runter blättert
durch die Sender.
- **Aufgeräumter Player** — OK-Taste zeigt Sendung, Zeiten und Fortschritt,
dazu Pause/Stopp-Buttons und Tonspur-Wahl, wenn der Sender mehrere hat.
Blendet sich von selbst wieder aus.
- **Handy als Fernbedienung** — QR-Code in den Einstellungen scannen, schon
hat man Senderliste, Suche, Lautstärke und Favoriten im Handy-Browser.
Keine App-Installation nötig.
- **Favoriten** — OK auf einem Sender gedrückt halten, Stern gesetzt. Die
Favoriten gelten pro Person und sind auf jedem Gerät dieselben.
- **Updates aus der App heraus** — unter Einstellungen → App genügt ein
Klick, wenn eine neue Version bereitsteht.
| Player | Nummerntasten |
| --- | --- |
| ![Player](docs/screenshots/player.png) | ![Nummerntasten](docs/screenshots/nummerntasten.png) |
## Installation auf dem Fernseher
1. Auf dem Google TV die App **Downloader** installieren (oder einen anderen
Weg nutzen, eine APK-Datei zu öffnen).
2. Diese Adresse eingeben:
`git.beckm4nn.net/benjamin/castarr/raw/branch/apk/castarr.apk`
3. Installation bestätigen („Unbekannte Quellen" für Downloader erlauben,
wenn der Fernseher fragt).
4. Castarr starten und den drei Schritten auf dem Bildschirm folgen:
QR-Code scannen, auf dem Handy Server angeben und anmelden — den Rest
macht der Fernseher.
Danach hält sich die App über den eingebauten Updater selbst aktuell.
---
## Für Technikinteressierte
Native Kotlin-App (Jetpack Compose for TV, Media3/ExoPlayer für HLS und
MPEG-TS). Als Backend dient ein [Dispatcharr](https://github.com/be-nj/Dispatcharr)-Fork
mit OIDC-Unterstützung: Anmeldung per Device Authorization Grant (der
Fernseher zeigt QR + Code, bestätigt wird am Handy beim Identity Provider),
API-Zugriff per Bearer-Token, Favoriten und Ausgabeprofile pro Nutzer.
Ohne Dispatcharr funktioniert auch jede M3U-Playlist (+ optionales XMLTV)
als generische Quelle — ErsatzTV, Threadfin, Tunarr, einfache Playlists.
Die Handy-Fernbedienung serviert der Fernseher selbst (eingebetteter
HTTP/WebSocket-Server, Kopplung per QR-Token mit ratenlimitiertem
Zahlencode als Fallback). Physische Mediatasten und Google Assistant
funktionieren über eine Media3 MediaSession.
### Selbst bauen
JDK 17+ und Android SDK (Platform 35) erforderlich; eine passende
JDK-Toolchain wird automatisch aufgelöst (foojay).
```
./gradlew assembleDebug # debug APK
./gradlew assembleRelease # signed when CASTARR_STORE_* env vars are set
./gradlew assembleDebug # Debug-APK
./gradlew assembleRelease # signiert, wenn CASTARR_STORE_*-Env gesetzt ist
```
APK output: `app/build/outputs/apk/<variant>/`. Releases on the
[releases page](https://git.beckm4nn.net/benjamin/castarr/releases) are signed; install
over an existing debug build requires uninstalling first (signature change).
APK-Ausgabe: `app/build/outputs/apk/<variant>/`. Die Releases hier im Repo
sind signiert; über einem Debug-Build muss einmal deinstalliert werden
(Signaturwechsel). Updates bezieht die App über die Release-API dieses
Repos, die APK selbst liegt auf dem Branch `apk`.
## Backend
The full feature set needs the Dispatcharr fork with OIDC support
(be-nj/Dispatcharr): its `/api/accounts/oidc/status/` endpoint hands the app
the issuer and public device-flow client id. Configuration lives in
[CONTEXT.md](CONTEXT.md) and [docs/adr/](docs/adr/).
Architektur-Notizen: [CONTEXT.md](CONTEXT.md) und [docs/adr/](docs/adr/).

View File

@@ -12,8 +12,8 @@ android {
applicationId = "dev.castarr.tv"
minSdk = 26
targetSdk = 35
versionCode = 21
versionName = "0.8.5"
versionCode = 22
versionName = "0.8.6"
}
// Release signing from environment (see ~/.keys/castarr-release.env on the

View File

@@ -235,7 +235,7 @@ private fun Overlay(state: AppState) {
Spacer(Modifier.width(14.dp))
Text(
"${formatClock(now.start)} ${formatClock(now.stop)}",
color = CastarrColors.muted,
color = Color(0xFFD7DBE0),
fontFamily = AppFont,
style = OverlayText,
fontSize = 14.sp,
@@ -248,7 +248,7 @@ private fun Overlay(state: AppState) {
Spacer(Modifier.height(2.dp))
Text(
"Danach: ${next.title} (${formatClock(next.start)})",
color = CastarrColors.faint,
color = CastarrColors.muted,
fontFamily = AppFont,
style = OverlayText,
fontSize = 14.sp,
@@ -270,7 +270,7 @@ private fun Overlay(state: AppState) {
.fillMaxWidth()
.height(3.dp)
.clip(RoundedCornerShape(1.5.dp))
.background(CastarrColors.line)
.background(Color(0x59FFFFFF))
) {
Box(
Modifier

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

BIN
docs/screenshots/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB