Files
claude-code 7620fd3838 Rebrand as Reverie: logo, frames, typography, previous-slide history
- Name, mark, banner, adaptive icon and BRANDING.md generated with Codex
  (branding/), wired into the launcher icon and TV banner.
- Overlay typography: Playfair Display for date and clock, Manrope for the
  location line, plus a soft bottom scrim.
- Picture frames setting: gallery mat, polaroid (tilted), rounded card.
- LEFT walks back through a 50-slide history; RIGHT moves forward again.
- Any string/boolean setting can be preset from adb extras.
- docs/reverie-ios-watchos-prompt.md: build prompt for the iOS + watchOS app.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012BvT3RjNpBmMUsyPqHq7fm
2026-09-12 06:26:33 +00:00

4.1 KiB
Raw Permalink Blame History

Reverie — Immich screensaver for Android TV

Reverie

Ambient photo screensaver for Android TV / Google TV that plays photos and videos from your Immich server, in the spirit of the Google Photos ambient mode:

  • Full-screen slideshow with slow pan & zoom (Ken Burns), crossfade / slide / zoom transitions.
  • Portrait photos are shown two at a time, side by side.
  • Videos play inline (muted by default, capped length), lone portrait items sit on a blurred backdrop.
  • Date and location overlay, clock.
  • Works as the system screensaver (Settings → Screen saver) and as a normal app (start the slideshow manually).
  • Filter by albums, favorites, photos / videos.
  • Set up from your phone: the TV shows a QR code, the phone opens a form served by the TV on the LAN and sends the credentials; no typing with the remote.
  • Picture frames: gallery mat, polaroid (with a slight tilt) or rounded card, over a blurred backdrop.
  • LEFT on the remote goes back to the previous slide (50-slide history), RIGHT skips ahead.
  • Sign in with email + password once: the app creates a scoped API key (asset.read, asset.view, album.read, user.read) and never stores the password.

Tested against Immich 3.1. Requires Android 8.0+ (API 26).

Install

Grab app-release.apk from the releases page (or build it) and sideload it:

adb connect <tv-ip>
adb install -r app-release.apk

Optional: pre-configure the server without typing on the TV remote:

adb shell am start -n cloud.alexandrevazquez.immichtv/.ui.MainActivity \
  --es server https://immich.example.com --es api_key "$(pass show services/immich-api-key)"

Then on the TV: open ReverieSet as system screensaver (or Settings → System → Screen saver) and pick it. Start slideshow now previews it; RIGHT / OK skips, BACK exits.

Chromecast with Google TV has no menu to choose a third-party screensaver (only Google's ambient mode). Select it over adb instead, the same way Aerial Views and similar apps do:

adb shell settings put secure screensaver_enabled 1
adb shell settings put secure screensaver_components cloud.alexandrevazquez.immichtv/.dream.ImmichDreamService
adb shell settings put secure screensaver_default_component cloud.alexandrevazquez.immichtv/.dream.ImmichDreamService

Pairing adb with a Google TV device (Android 11+): Developer options → Wireless debugging → Pair device with pairing code, then adb pair <ip>:<pairing-port> <code> and adb connect <ip>:<connect-port> (adb mdns services lists the connect port).

Build

export ANDROID_HOME=~/android-sdk
./gradlew assembleDebug            # app/build/outputs/apk/debug/app-debug.apk
./scripts/build-release.sh         # signed release, keystore password taken from pass

scripts/build-release.sh expects the keystore at ~/.android/immichtv-release.jks and its password in pass show android/immichtv-keystore-password.

Immich API used

Call Purpose
POST /api/search/random random batch of assets (albums / type / favorites filters, visibility: timeline)
GET /api/albums album picker
`GET /api/assets/{id}/thumbnail?size=preview fullsize
GET /api/assets/{id}/video/playback transcoded video stream
POST /api/auth/login + POST /api/api-keys one-time sign-in that mints the device key

Branding

Name, mark, banner and palette live in branding/ (BRANDING.md). Fonts: Playfair Display (dates, clock) and Manrope (labels), both OFL, bundled in app/src/main/res/font.

Layout

  • data/ImmichApi.kt REST client (OkHttp + org.json).
  • data/SlideSource.kt endless shuffled stream of slides, portrait pairing, dedupe of recent assets.
  • ui/SlideshowView.kt rendering engine: layers, transitions, Ken Burns, ExoPlayer for video, overlays.
  • dream/ImmichDreamService.kt system screensaver entry point.
  • ui/SlideshowActivity.kt manual full-screen mode.
  • ui/MainActivity.kt + ui/SettingsFragment.kt Leanback settings UI.