jtube-tv/README.md
Jeena 46a325eed3 docs: regenerate screenshots via the mock backend, add the channel page (#30)
Recapture every screen through the branch-only mock backend
(tools/screenshot-mock) so the app runs unmodified against real CC/Blender
content: the rows no longer repeat thumbnails (Continue watching, New local
videos and My videos draw different slices), the account has an avatar, the
player sits on a frame with something happening, and the Subscribe button reads
correctly. Adds a channel-page screenshot (banner, stats, Subscribe, full video
grid) and references it in the README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-15 13:07:33 +00:00

133 lines
5.1 KiB
Markdown

# JTube TV
<p align="center">
<img src="docs/jtube-logo.svg" width="150" alt="The JTube TV logo, a little orange TV" />
</p>
<p align="center">
<em>Watch your PeerTube instance from the couch, with the remote.</em>
</p>
JTube TV is an Android TV app for
<a href="https://joinpeertube.org/"><img src="docs/peertube-logo.svg" width="16" alt="" valign="middle" />&nbsp;PeerTube</a>.
It does for a PeerTube instance what SmartTube does for YouTube: a big-screen,
D-pad-first way to browse your videos, your channels and your watch history and
play them — and nothing else in the way.
It is built for people who self-host their videos on PeerTube and want to watch
them on the TV without a phone, a cast button or a browser. Sign in once with
your PeerTube account and the whole instance is a few clicks away on the remote:
your own uploads (private ones included), the channels you follow, what you were
watching last, and the instance's public videos and search.
It works with any PeerTube instance over the
[REST API](https://docs.joinpeertube.org/api-rest-reference.html). The default
in the sign-in screen is [tube.jeena.net](https://tube.jeena.net), the author's
own instance, but you can point it at yours.
## What it looks like
The screenshots use a public demo instance with real, CC-licensed open-movie
content, courtesy of the [Blender Foundation](https://www.blender.org/) movies
and the [A propos de PeerTube](https://framatube.org) channel — all of it plays
in the app.
**Home.** Three rows: *Continue watching* picks up each video at the position
the server saved, then the newest local videos, then the newest from the
channels you follow. Scroll right and more load on their own.
<p align="center">
<img src="docs/screenshots/home.png" width="800" alt="Home screen with Continue watching, New local videos and subscriptions rows" />
</p>
**The menu.** A sidebar slides in — press the left D-pad at the edge of a row,
or just press Back from anywhere in a list. It jumps to Home, My videos,
Channels, Search, Subscriptions and History.
<p align="center">
<img src="docs/screenshots/drawer.png" width="800" alt="Menu drawer with the destinations" />
</p>
**My videos.** Everything you own, every privacy level, with a badge on
anything that isn't public.
<p align="center">
<img src="docs/screenshots/myvideos.png" width="800" alt="My videos grid with Private and Internal badges" />
</p>
**Channels.** One row per owner, with video, subscriber and play counts on
every card.
<p align="center">
<img src="docs/screenshots/channels.png" width="800" alt="Channels screen with channel cards" />
</p>
Open a channel for its banner, its stats and all its videos — with a Subscribe
button you can reach with the remote.
<p align="center">
<img src="docs/screenshots/channel.png" width="800" alt="A channel page: banner, stats, Subscribe button and the channel's videos" />
</p>
**The player** speaks remote: play and pause, seek back and forward, a seek bar
with position and duration, and the video's info, comments and playlists a
button away. Watching is reported to the server every 20 seconds, so where you
left off survives closing the app.
<p align="center">
<img src="docs/screenshots/player.png" width="800" alt="Player with controls, seek bar and title" />
</p>
## What it does
- **Sign in once.** The app trades your username and password for OAuth tokens
and keeps only those, encrypted with the Android Keystore. The password is
never stored.
- **Home** with Continue watching, new local videos and new videos from your
subscriptions.
- **Browse and search** the instance's public videos by title.
- **My videos** — every video you own, private, internal and unlisted included.
- **Channels** — local channels with their videos, plus your subscriptions and
your server-side watch history.
- **Subscribe** to and unsubscribe from channels, from the player or a channel
page.
- **Player** — HLS with a progressive MP4 fallback, resume from the saved
position, like/dislike, comments, playlists, and watching reports.
What it deliberately does not do: uploading, editing or deleting content.
## Build
Requirements: JDK 17 or newer (21 recommended) and an Android SDK with
platform 35. The Gradle wrapper is checked in, so no local Gradle install is
needed.
```bash
./gradlew :app:assembleDebug
```
Then put it on the TV:
```bash
adb connect <tv-ip>:<port>
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
## Architecture
A single-module app, deliberately small:
- `data/api` — Retrofit interface and kotlinx-serialization DTOs for the
PeerTube API.
- `data/auth` — TokenStore, the encrypted preference storage for tokens.
- `data/network` — OkHttp/Retrofit wiring: dynamic base URL, bearer token
interceptor, single-flight token refresh.
- `data/PeerTubeRepository.kt` — one suspend-call surface for the whole UI.
- `ui/` — Compose for TV screens, one for each of the destinations above.
- No DI framework, no database. The service locator is `AppGraph`.
## License
JTube TV is free software under [GPL-3.0-or-later](LICENSE). The PeerTube logo
is a trademark of [Framasoft](https://framasoft.org/), used here to refer to the
PeerTube project.