Private
Public Access
Renames the app (label, texts, log files, Plex product name, User-Agent, APK). The package
name, preferences and signing key stay, so it installs over Minamp and keeps its settings.
tools/strings.py catches up with the strings added straight to the XML in 9440536.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
116 lines
6.9 KiB
Markdown
116 lines
6.9 KiB
Markdown
# Plexamp Lite
|
||
|
||
A small Plexamp-style music player for Plex, built for the Samsung Galaxy Mini (GT-S5570:
|
||
Android 2.2/2.3, 240×320 ldpi screen, 600 MHz ARMv6, 384 MB RAM). Runs on any Android 2.2+ phone.
|
||
|
||
## Language
|
||
|
||
The interface is in **Galician** by default, whatever language the phone is set to. English is
|
||
available under *Axustes → Idioma*. All text lives in `tools/strings.py` (key → English, Galician),
|
||
which generates `res/values/strings.xml` (Galician) and `res/values-en/strings.xml`; the connection
|
||
log stays in English since it's meant for troubleshooting.
|
||
|
||
## Install
|
||
|
||
1. On the phone: **Settings → Applications → Unknown sources** (tick it).
|
||
2. Copy `PlexampLite.apk` to the SD card (USB cable, or download it in the browser) and open it
|
||
with a file manager, or from a computer: `adb install PlexampLite.apk`.
|
||
3. Plexamp Lite installs to internal storage (about 1 MB): an app on the SD card is killed whenever the
|
||
phone shares its SD card over USB, which stopped the music.
|
||
|
||
## Sign in
|
||
|
||
Open Plexamp Lite → **Sign in with Plex**. It shows a 4-character code; on any other device go to
|
||
**plex.tv/link** and type it in. Plexamp Lite then lists your servers (owned and shared) and music libraries.
|
||
|
||
*Connect to a server address* is the manual fallback: an IP/hostname plus an optional X-Plex-Token.
|
||
|
||
## Streaming from anywhere
|
||
|
||
After sign-in Plexamp Lite knows every address Plex advertises for your server and picks the best
|
||
working one, re-checking whenever the phone switches network:
|
||
|
||
| Order | Connection | When it's used |
|
||
|---|---|---|
|
||
| 1 | Whatever worked last time | Tried alone first, so a normal start costs one request (if that was a remote address, the home addresses get 2 s first) |
|
||
| 2 | Home network, plain HTTP | On your Wi-Fi (fast: no encryption work for the phone) |
|
||
| 3 | Home network, HTTPS (`*.plex.direct`) | On your Wi-Fi if plain HTTP is refused, or if *Settings → Encrypt at home too* is on |
|
||
| 4 | Remote, HTTPS | Away, if Remote Access is set up on the server |
|
||
| 5 | Plex Relay | Away, when the server isn't reachable directly (bandwidth-capped; Plexamp Lite caps itself at 192 kbps) |
|
||
|
||
Secure addresses are tried one at a time: on a 600 MHz phone a TLS handshake takes seconds, and
|
||
several at once make each of them time out. Plexamp Lite uses TLS 1.2 with session resumption, so only
|
||
the first connection to each server pays the full cost; later ones resume in a fraction of it.
|
||
|
||
For the best remote experience enable **Settings → Remote Access** on your Plex Media Server.
|
||
Without it, Relay still works.
|
||
|
||
Android 2.x can't do modern TLS, so Plexamp Lite bundles its own TLS 1.2/1.3 stack (Bouncy Castle,
|
||
renamed to `com.minamp.bc` so it doesn't clash with the old copy inside Android) and verifies
|
||
certificates against Mozilla's root store (from `certifi`). A tiny loopback proxy feeds the
|
||
phone's media player, so HTTPS streams and relay work the same as local ones. If the phone's
|
||
clock has been reset to before 2024 the certificate date check is skipped rather than failing.
|
||
|
||
## Playback and quality
|
||
|
||
* MP3, AAC (M4A) and Ogg Vorbis play directly. FLAC, ALAC etc. are transcoded to MP3 by the
|
||
server (Android 2.2/2.3 can't decode FLAC).
|
||
* **Menu → Settings**: separate quality for home Wi-Fi (default *Original*) and for away/mobile
|
||
data (default *192 kbps MP3*); 320/256/192/128/96 kbps available. *Quality over Bluetooth*
|
||
(default 192 kbps) caps both while the sound goes to a Bluetooth speaker: on the Mini, Wi-Fi and
|
||
Bluetooth share one radio, and a lighter stream keeps the speaker from stuttering.
|
||
* Seeking in a transcoded track restarts the transcode at the new position.
|
||
* If a stream fails, Plexamp Lite re-picks the connection and resumes; if it fails again it downloads
|
||
the whole track first and plays from the SD card. "Download tracks before playing" forces that
|
||
mode (useful on flaky mobile data). Playback that stalls ("playing" but the time doesn't move
|
||
for 10 s) is recovered the same way.
|
||
* A Bluetooth speaker that drops its link for a moment pauses Plexamp Lite, which resumes by itself if the
|
||
speaker is back within 20 s. Why playback paused or stopped is written to the connection log.
|
||
* Plays are reported to Plex (Now Playing in the Plex dashboard, play counts, resume position).
|
||
|
||
## Features
|
||
|
||
* Home: Library radio, Loved radio (rated 4★+ / loved), Time-travel radio (pick a decade),
|
||
Random album, Recently added and Recently played shelves.
|
||
* Artists / Albums (5 sort orders) / Playlists tabs with paging and fast scroll; Search.
|
||
* Artist page with *Play all* and *Artist radio*; album and playlist pages with *Play*/*Shuffle*.
|
||
* Long-press anything: Play next, Add to queue, Go to album/artist, Love.
|
||
* Now Playing: big art on a backdrop coloured from the cover, seek bar, shuffle, repeat
|
||
(queue/track), love, sleep timer (15–90 min or end of track), where it's streaming from.
|
||
* Up Next queue: jump, play next, remove, clear; the queue and position survive restarts.
|
||
* Downloads for offline listening: long-press a track, album, artist or playlist -> *Download*;
|
||
*Menu -> Downloads* shows progress, space used and free, play/shuffle, retry and remove. Files go to
|
||
the SD card. MP3 originals are kept as they are (unless above a lower *Download quality* in
|
||
Settings); everything else is transcoded to MP3, 320 kbps by default. Downloaded tracks play from
|
||
the SD card, offline too, and plays made offline are reported to Plex later.
|
||
* *Menu -> Close Plexamp Lite* stops the music and closes every screen.
|
||
* Wired headset button: 1 click play/pause, 2 next, 3 previous; Bluetooth media keys;
|
||
pauses for calls and when headphones are unplugged.
|
||
|
||
## Building (no Android SDK needed)
|
||
|
||
```
|
||
tools/setup_toolchain.sh # once: fetches aapt2, the API 8 android.jar, builds dx, renames Bouncy Castle
|
||
./build.sh # -> build/PlexampLite.apk
|
||
```
|
||
|
||
`build.sh` runs `aapt2` (resources), `javac` (Java 8 bytecode checked against the API 8
|
||
`android.jar`), `dx` (dex 035) and `tools/signapk.py`, which writes the v1 signature in the
|
||
classic Android SignApk format and aligns the APK. (Modern `jarsigner` output does *not* install on
|
||
Android 4.2 and older: it names digests `SHA-1-Digest` and labels the PKCS#7 signer algorithm in a
|
||
way old `JarUtils` can't read, so the phone treats the APK as unsigned.) The debug key in `signing/` (password `minamp123`) is what this APK is
|
||
signed with, so rebuilt APKs install over it.
|
||
|
||
Tests (desktop JVM, no device):
|
||
|
||
* `test/PlexTest.java` + `test/mock_plex.py`: PIN sign-in, server discovery, connection
|
||
picking/fallback, TLS with a wildcard plex.direct-style certificate (ECDSA leaf, RSA root),
|
||
untrusted-root rejection, browsing, search, artwork, and the stream proxy (Range requests over
|
||
TLS, de-chunking transcodes, aborting).
|
||
* `test/QueueTest.java`: shuffle/unshuffle, repeat modes, play next, remove, move, clear.
|
||
|
||
## Limits
|
||
|
||
* No gapless playback (Android 2.2/2.3 have no API for it).
|
||
* Notification has no playback buttons (pre-Android 3 can't); tap it to open Now Playing.
|