
# Memby
**An independent Android TV client for Emby.**
A personalised television launcher, a full media player, a system screensaver and an
optional self-hosted gateway that shapes the experience for every viewer in the house.
[](LICENSE)
[](#build--install)
[](#build--install)
[](#tech-stack)
[](server/README.md)
Source: [g.sublogue.com/admin/memby](https://g.sublogue.com/admin/memby)
---
## Contents
- [How it works](#how-it-works)
- [Features](#features)
- [Browse and discover](#browse-and-discover)
- [Playback](#playback)
- [Profiles, televisions and administration](#profiles-televisions-and-administration)
- [Screensaver and updates](#screensaver-and-updates)
- [Tech stack](#tech-stack)
- [Build & install](#build--install)
- [Server address](#server-address)
- [First run](#first-run)
- [Running the gateway](#running-the-gateway)
- [Project layout](#project-layout)
- [Distributing builds](#distributing-builds)
- [One-time: a signing key](#one-time-a-signing-key)
- [NAS deployment release (recommended)](#nas-deployment-release-recommended)
- [Local PowerShell release (compatibility path)](#local-powershell-release-compatibility-path)
- [How TVs update themselves](#how-tvs-update-themselves)
- [Upgrading to v0.1.53](#upgrading-to-v0153)
- [Notes & limitations](#notes--limitations)
- [Licence](#licence)
---
## How it works
The client can talk to Emby directly, or through the **Memby gateway** — a Go service in
`server/` that runs in Docker alongside Postgres and Redis and owns auth, caching, search
and the shaping of TV screens. With a gateway the launcher is one request instead of four,
and the TV holds a revocable gateway token rather than a live Emby token.
```
direct: TV ──────────────────────────────► Emby
gateway: TV ──► Memby gateway ──► Emby (metadata + artwork)
TV ─────────────────────► Emby (video stream; never proxied by the gateway)
```
Which one a build uses is decided by `memby.gatewayUrl` in `gradle.properties`: set it and
the app is a thin client; leave it blank and the app talks to Emby directly. Both paths are
maintained — the direct path is the fallback when the container is down.
## Features
### Browse and discover
- Personalised, server-composed Home rows with a cached instant-start launcher.
- A cinematic featured hero that rotates through ranked films and series premieres.
- Continue Watching merged with Next Up, ordered by the viewer's recent activity.
- Favourites, latest films, recommendations, curated shelves and schedule rows.
- Dedicated Movies, TV Shows, Favourites and For You destinations.
- Instant search with an on-screen keyboard, voice input and session result caching.
- Optional, server-controlled genre browsing with paged film and series catalogues.
- A dedicated For You page combining viewing history, browsing signals, available time
and direct-play evidence; every recommendation explains why it was selected.
- More Like This, cast and technical details on film and series pages.
- Per-title IMDb, Rotten Tomatoes, Metacritic, Letterboxd and TMDb ratings where available.
- My Shows tracking, upcoming episodes, lifecycle badges and personal return alerts.
- Themes, seasonal colour schemes and optional launcher decorations.
### Playback
- Media3/ExoPlayer playback with direct play, compatible-stream remuxing and HLS fallback.
- Resume playback, progress reporting, watched state and immediate poster badge updates.
- Audio and subtitle track selection with per-viewer language preferences.
- Missing-subtitle search and download through Bazarr or OpenSubtitles when configured.
- Configurable Left/Right seeking with trickplay thumbnail previews.
- Skip-intro prompts or automatic skipping from Emby's chapter markers.
- Automatic next-episode playback with an on-screen countdown.
- Closing-credits presentation with the next episode alongside and adaptive 2× playback.
- Episode pages with season navigation, watched markers and estimated completion dates.
- In-player cast lookup, pause artwork, time-remaining reminders and service-status banners.
### Profiles, televisions and administration
- Multiple saved viewer profiles with quick switching from the navigation rail.
- Per-viewer settings synchronised through the gateway across every signed-in television.
- Device management, session revocation and stable television identity.
- Gateway-controlled feature flags, maintenance mode, forced app updates and live themes.
- Service alerts for new library items, aired episodes, deployments and Emby outages.
- A dependency-free web console for accounts, devices, settings history, features,
updates, library imports, recommendations, searches, row engagement and logs.
- Postgres catalogue import, Redis caching, full-text search and background recommendation
and ratings warming.
### Screensaver and updates
- A system `DreamService` screensaver with cross-fading library backdrops.
- Interactive screensaver controls for playback, favourites and artwork navigation.
- An in-app screensaver preview using the same rendering surface as the system Dream.
- Self-hosted signed APK updates with SHA-256, package and signing-key verification.
- Mandatory and optional update policy controlled by the gateway.
## Tech stack
| Layer | Built with |
| --- | --- |
| UI | Kotlin + Jetpack **Compose for TV** (`androidx.tv:tv-material3`) |
| Playback | **Media3 / ExoPlayer** |
| Networking | Retrofit + OkHttp + kotlinx.serialization, over one shared HTTP stack |
| Storage | DataStore for profiles, settings and cached launcher state |
| Images | Coil |
| Gateway | Go, with Postgres and Redis |
## Build & install
You need **JDK 17** and the **Android SDK** (Android Studio bundles both).
Open the folder in Android Studio (Giraffe/Koala or newer) and let it sync, **or** from a
terminal:
```powershell
# Android Studio writes local.properties automatically. If building from the CLI,
# point it at your SDK first:
"sdk.dir=C:\\Users\\