Replace the placeholder-content screenshots with a demo instance that serves real CC-licensed open movies (Blender Foundation, framatube), so the app looks like what it is: a video player with real thumbnails, real durations and real playback.
105 lines
No EOL
3.8 KiB
Markdown
105 lines
No EOL
3.8 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>
|
|
|
|
JTube TV is an Android TV app for [PeerTube](https://joinpeertube.org/). It puts
|
|
a PeerTube instance on the big screen the way SmartTube puts YouTube there:
|
|
browse from the couch, play with the remote, nothing else in the way.
|
|
|
|
It talks to any PeerTube instance over the
|
|
[REST API](https://docs.joinpeertube.org/api-rest-reference.html). The default
|
|
is [tube.jeena.net](https://tube.jeena.net), my own instance, where most videos
|
|
are private family uploads. Signing in matters because "My videos" shows them
|
|
all, privacy levels included.
|
|
|
|
## What it looks like
|
|
|
|
Screenshots come from a demo instance serving 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.
|
|
|
|
The home screen. Continue watching picks up at the position the server saved,
|
|
new videos first, page after page.
|
|
|
|
<p align="center">
|
|
<img src="docs/screenshots/home.png" width="800" alt="Home screen with Continue watching and New videos rows" />
|
|
</p>
|
|
|
|
A slide-in drawer opens with the left D-pad button. My videos shows your own
|
|
uploads, every privacy level included, with a badge on anything not public.
|
|
|
|
<p align="center">
|
|
<img src="docs/screenshots/drawer.png" width="800" alt="Menu drawer with the destinations" />
|
|
</p>
|
|
|
|
<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 and play counts on every card.
|
|
|
|
<p align="center">
|
|
<img src="docs/screenshots/channels.png" width="800" alt="Channels screen with channel cards" />
|
|
</p>
|
|
|
|
The player speaks remote: play and pause, seek back and forward, a seek bar
|
|
with position and duration. Watching is reported to the server every 20
|
|
seconds, so where you left off survives 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 in v0.1
|
|
|
|
- Sign in once. The app exchanges your username and password for OAuth tokens
|
|
and stores only those, encrypted with the Android Keystore. The password
|
|
itself is never kept.
|
|
- Home with Continue watching and New videos.
|
|
- Browse the instance's public videos, and search them 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.
|
|
- Player: HLS, with a progressive MP4 fallback, resume from the saved
|
|
position, and watching reports.
|
|
|
|
What it deliberately does not do (yet, or ever): uploading, editing,
|
|
deleting, managing subscriptions. That's tracked in
|
|
[BACKLOG.md](BACKLOG.md).
|
|
|
|
## 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). |