Private
Public Access
Two causes, both fixed: - Plex keeps one file stream per device and cuts the one in progress when another starts, so the read-ahead and the player cut each other off. Whole-file fetches (read-ahead, downloads, download-first) now ask for the file as a download (?download=1), which Plex leaves out of that rule; the plain address follows for servers that refuse downloads. - Http.abort closed the socket of a response already read to the end, whose connection was back in the pool and could be carrying the read-ahead. abort now leaves finished responses alone (test/PoolAbortTest.java). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.7 KiB
4.7 KiB
Plexamp Lite (Android) — spec
The short contract for working on this app. README.md is the user guide; this file says what the app is
for, what limits it lives within, and what must not break.
Goal
A Plexamp-style Plex music player for the Samsung Galaxy Mini that keeps playing reliably at home, away and over a Bluetooth speaker.
Target and hard limits
- Samsung Galaxy Mini GT-S5570: Android 2.2/2.3 (API 8), 240×320 ldpi, 600 MHz ARMv6, 384 MB RAM; any 2.2+ phone. A second build for Android 4.1+ (API 16: Xperia J, Galaxy S II), one per Android level, never per phone.
- Native Java (this app uses XML layouts), no libraries beyond the bundled Bouncy Castle TLS; the Android 4.1 build adds ExoPlayer 2.18.7 (+ Guava), shrunk by R8.
- Galician by default, English in Settings. All text in
tools/strings.py, which generatesres/values*/strings.xml. The connection log stays in English. - Plays MP3/AAC/Vorbis directly; FLAC, ALAC and the rest are transcoded to MP3 by the server.
Current scope (1.14)
- Sign in with a plex.tv/link PIN (or a manual address + token). Owned and shared servers and libraries.
- Connection picking: last good one first, then LAN HTTP, LAN HTTPS (
plex.direct), remote HTTPS, Relay (capped at 192 kbps). Secure addresses tried one at a time; re-checked on network changes. - Bundled TLS 1.2/1.3 with session resumption; a loopback
StreamProxyfeeds the media player. - Quality per network (home, away, Bluetooth cap), read-ahead of the next two tracks, stall and failure recovery (re-pick, then download first), resume after short Bluetooth drop-outs.
- Home radios and shelves, Artists/Albums/Playlists, Search, artist/album/playlist pages, Now Playing, Up Next queue (survives restarts), sleep timer, love, downloads to SD card with offline play reporting.
- Headset and Bluetooth buttons; pauses for calls and unplugging. Plays reported to Plex (not while
PlexampLite-noreportis on the SD card: for tests against a real server). - Lyrics in Now Playing (as in the Mac app): a lasting on/off; timed lyrics follow and seek; plain text scrolls.
- Home-screen widget (both builds).
- Android 4.1 build: ExoPlayer with gapless hand-over to read-ahead/downloaded files, notification and lock screen with art and buttons, resizable widget, Holo, ⋮ without a Menu key, metered networks.
Out of scope
- On the Android 2.x build: gapless playback and notification playback buttons (Android 2.x can't).
- Video, photos.
Must not break
- Package
com.minampandsigning/minamp.keystore(passwordminamp123): updates install over Minamp. - Signing:
tools/signapk.py(classic SignApk v1); neverjarsigner. src/com/minamp/net/is the origin oftlskit; keep the two in step (change../tlskit, reinstall).- This repo's
tools/setup_toolchain.sh,make_roots.pyandsignapk.pyprepare the toolchain all the Galaxy Mini apps use: changes there affect every app. - Installs to internal storage (SD-card installs get killed during USB sharing).
- Whole-file fetches of a part (read-ahead, downloads) use
Library.downloadUrls(?download=1first): Plex cuts a device's file stream when the same device starts another, except for downloads. platform/api8andplatform/api16keep the samePlatformmethods; shared code calls no API the API 8 jar lacks (the api8 compile and Dalvik check catch it). Each build'sversionCodeis the manifest's × 100 + level, same key; both APKs are listed in../tenda-lite/repo/apps.json.- The Android 4.1 build targets API 16: no
clipPathin drawing (the GPU can't before 4.3), and network on the main thread is allowed inPlatform.init(the shared code closes connections there).
Code map
PlayerService (playback, recovery, gapless) · Engine (MediaPlayerEngine; ExoEngine in platform/api16) ·
Platform (per level) · PlayerWidget + PlayerViews · Lyrics + LyricsView + util/Lrc · · PlayQueue · Downloads · plex/ (Plex, Server, Library,
Item) · net/ (Http, CertVerifier, StreamProxy, Threads, DiagLog) · activities Home, Browse,
NowPlaying, Queue, Search, Setup, Downloads.
Build, test, release
tools/setup_toolchain.shandtools/fetch_exoplayer.shonce, then./build.sh→build/PlexampLite.apkandbuild/PlexampLite-api16.apk.- Tests on the desktop JVM:
PlexTestwithtest/mock_plex.py,QueueTest,LyricsTest,PreferHomeTestwithtest/identity_server.py,NetTest,HandshakeProfile. - Release: raise
versionCode/versionName, build, addchangesin../tenda-lite/repo/apps.json, commit and push,../tenda-lite/repo/publish.sh. - Siblings for iPod, Mac and Linux (
plexamp-lite-ios,-mac,-linux) share behaviour; fixes are often backported between them.