Plexamp Lite 1.11: Minamp is now Plexamp Lite

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>
This commit is contained in:
XoséandClaude Opus 5.5 committed 2026-10-19 16:57:47 +02:00
1 parent 08590f3224
commit 7eebb0d881
15 files changed
+52 -50

No files matched your search

+2 -2
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.minamp"
android:versionCode="11"
android:versionName="1.10"
android:versionCode="12"
android:versionName="1.11"
android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10" />
+14 -14
View File
@@ -1,4 +1,4 @@
# Minamp
# 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.
@@ -13,21 +13,21 @@ log stays in English since it's meant for troubleshooting.
## Install
1. On the phone: **Settings → Applications → Unknown sources** (tick it).
2. Copy `Minamp.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 Minamp.apk`.
3. Minamp installs to internal storage (about 1 MB): an app on the SD card is killed whenever the
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 Minamp → **Sign in with Plex**. It shows a 4-character code; on any other device go to
**plex.tv/link** and type it in. Minamp then lists your servers (owned and shared) and music libraries.
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 Minamp knows every address Plex advertises for your server and picks the best
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 |
@@ -36,16 +36,16 @@ working one, re-checking whenever the phone switches network:
| 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; Minamp caps itself at 192 kbps) |
| 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. Minamp uses TLS 1.2 with session resumption, so only
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 Minamp bundles its own TLS 1.2/1.3 stack (Bouncy Castle,
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
@@ -60,11 +60,11 @@ clock has been reset to before 2024 the certificate date check is skipped rather
(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, Minamp re-picks the connection and resumes; if it fails again it downloads
* 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 Minamp, which resumes by itself if the
* 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).
@@ -83,7 +83,7 @@ clock has been reset to before 2024 the certificate date check is skipped rather
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 Minamp* stops the music and closes every screen.
* *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.
@@ -91,7 +91,7 @@ clock has been reset to before 2024 the certificate date check is skipped rather
```
tools/setup_toolchain.sh # once: fetches aapt2, the API 8 android.jar, builds dx, renames Bouncy Castle
./build.sh # -> build/Minamp.apk
./build.sh # -> build/PlexampLite.apk
```
`build.sh` runs `aapt2` (resources), `javac` (Java 8 bytecode checked against the API 8
+3 -3
View File
@@ -1,5 +1,5 @@
#!/bin/bash
# Builds Minamp.apk for Android 2.2+ without the Android SDK/Gradle:
# Builds PlexampLite.apk for Android 2.2+ without the Android SDK/Gradle:
# aapt2 (resources) -> javac (Java 8 bytecode vs android-8 API) -> dx (dex 035) -> signapk.py (v1/SHA-1 + zipalign).
set -euo pipefail
cd "$(dirname "$0")"
@@ -42,5 +42,5 @@ echo "== package"
cp $OUT/base.apk $OUT/unsigned.apk
(cd $OUT && zip -q unsigned.apk classes.dex)
# v1 signature in the classic Android SignApk format (jarsigner's modern output won't install on Android <= 4.2)
python3 tools/signapk.py ${KEYSTORE:-$T/minamp.keystore} ${KEYPASS:-minamp123} $OUT/unsigned.apk $OUT/Minamp.apk
ls -la $OUT/Minamp.apk
python3 tools/signapk.py ${KEYSTORE:-$T/minamp.keystore} ${KEYPASS:-minamp123} $OUT/unsigned.apk $OUT/PlexampLite.apk
ls -la $OUT/PlexampLite.apk
+6 -6
View File
@@ -8,7 +8,7 @@
<string name="album">Album</string>
<string name="album_link">Album ›</string>
<string name="already_downloaded">Already downloaded</string>
<string name="app_name">Minamp</string>
<string name="app_name">Plexamp Lite</string>
<string name="applies_next_track">Applies from the next track</string>
<string name="artist">Artist</string>
<string name="artist_radio">Radio</string>
@@ -57,7 +57,7 @@
<string name="downloads">Downloads</string>
<string name="end_of_track">End of track</string>
<string name="enter_address">Enter your server\'s address</string>
<string name="error_last_time">Minamp hit an error last time</string>
<string name="error_last_time">Plexamp Lite hit an error last time</string>
<string name="finding_decades">Finding decades…</string>
<string name="finding_servers">Finding your servers…</string>
<string name="go_to_album">Go to album</string>
@@ -124,11 +124,12 @@
<string name="playlist">Playlist</string>
<string name="plex_server">Plex server</string>
<string name="quality_away_title">Quality away / mobile</string>
<string name="quality_bt_title">Quality over Bluetooth</string>
<string name="quality_home_title">Quality at home</string>
<string name="quality_original">Original</string>
<string name="queue_empty">The queue is empty</string>
<string name="queued_n">%1$d tracks added to downloads</string>
<string name="quit_app">Close Minamp</string>
<string name="quit_app">Close Plexamp Lite</string>
<string name="random_album">Random album</string>
<string name="random_album_sub">Feeling lucky</string>
<string name="recently_added">Recently added</string>
@@ -141,7 +142,7 @@
<string name="repeat_queue">Repeat queue</string>
<string name="repeat_track">Repeat track</string>
<string name="save_to_sd">Save to SD card</string>
<string name="saved_log">Saved as Minamp-log.txt on the SD card</string>
<string name="saved_log">Saved as PlexampLite-log.txt on the SD card</string>
<string name="search">Search</string>
<string name="search_hint">Search music</string>
<string name="search_in">Search %1$s</string>
@@ -164,6 +165,7 @@
<string name="set_library">Library: %1$s</string>
<string name="set_log">Connection log &amp; streaming test</string>
<string name="set_quality_away">Quality away / mobile data: %1$s</string>
<string name="set_quality_bt">Quality over Bluetooth: %1$s</string>
<string name="set_quality_home">Quality at home: %1$s</string>
<string name="set_secure_home">Encrypt at home too (slower): %1$s</string>
<string name="set_server">Server: %1$s</string>
@@ -236,6 +238,4 @@
<string name="unloved">Removed from favourites</string>
<string name="up_next">Queue</string>
<string name="you">you</string>
<string name="quality_bt_title">Quality over Bluetooth</string>
<string name="set_quality_bt">Quality over Bluetooth: %1$s</string>
</resources>
+6 -6
View File
@@ -8,7 +8,7 @@
<string name="album">Álbum</string>
<string name="album_link">Álbum ›</string>
<string name="already_downloaded">Xa está descargado</string>
<string name="app_name">Minamp</string>
<string name="app_name">Plexamp Lite</string>
<string name="applies_next_track">Aplícase desde a seguinte pista</string>
<string name="artist">Artista</string>
<string name="artist_radio">Radio</string>
@@ -57,7 +57,7 @@
<string name="downloads">Descargas</string>
<string name="end_of_track">Fin da pista</string>
<string name="enter_address">Escribe o enderezo do teu servidor</string>
<string name="error_last_time">Minamp tivo un erro a última vez</string>
<string name="error_last_time">Plexamp Lite tivo un erro a última vez</string>
<string name="finding_decades">Buscando décadas…</string>
<string name="finding_servers">Buscando os teus servidores…</string>
<string name="go_to_album">Ir ao álbum</string>
@@ -124,11 +124,12 @@
<string name="playlist">Lista de reprodución</string>
<string name="plex_server">Servidor Plex</string>
<string name="quality_away_title">Calidade fóra / datos móbiles</string>
<string name="quality_bt_title">Calidade por Bluetooth</string>
<string name="quality_home_title">Calidade na casa</string>
<string name="quality_original">Orixinal</string>
<string name="queue_empty">A cola está baleira</string>
<string name="queued_n">%1$d pistas engadidas ás descargas</string>
<string name="quit_app">Pechar Minamp</string>
<string name="quit_app">Pechar Plexamp Lite</string>
<string name="random_album">Álbum ao chou</string>
<string name="random_album_sub">Proba sorte</string>
<string name="recently_added">Novidades</string>
@@ -141,7 +142,7 @@
<string name="repeat_queue">Repetir a cola</string>
<string name="repeat_track">Repetir a pista</string>
<string name="save_to_sd">Gardar na tarxeta SD</string>
<string name="saved_log">Gardado como Minamp-log.txt na tarxeta SD</string>
<string name="saved_log">Gardado como PlexampLite-log.txt na tarxeta SD</string>
<string name="search">Buscar</string>
<string name="search_hint">Buscar música</string>
<string name="search_in">Buscar en %1$s</string>
@@ -164,6 +165,7 @@
<string name="set_library">Biblioteca: %1$s</string>
<string name="set_log">Rexistro de conexión e proba de reprodución</string>
<string name="set_quality_away">Calidade fóra / datos móbiles: %1$s</string>
<string name="set_quality_bt">Calidade por Bluetooth: %1$s</string>
<string name="set_quality_home">Calidade na casa: %1$s</string>
<string name="set_secure_home">Cifrar tamén na casa (máis lento): %1$s</string>
<string name="set_server">Servidor: %1$s</string>
@@ -236,6 +238,4 @@
<string name="unloved">Quitada de favoritas</string>
<string name="up_next">Cola</string>
<string name="you">ti</string>
<string name="quality_bt_title">Calidade por Bluetooth</string>
<string name="set_quality_bt">Calidade por Bluetooth: %1$s</string>
</resources>
+2 -2
View File
@@ -176,7 +176,7 @@ public class App extends Application {
try {
java.io.StringWriter sw = new java.io.StringWriter();
java.io.PrintWriter pw = new java.io.PrintWriter(sw);
pw.println("Minamp " + Plex.version + " on " + Build.MODEL + ", Android " + Build.VERSION.RELEASE);
pw.println("Plexamp Lite " + Plex.version + " on " + Build.MODEL + ", Android " + Build.VERSION.RELEASE);
pw.println(new java.util.Date() + " - " + where);
e.printStackTrace(pw);
pw.flush();
@@ -186,7 +186,7 @@ public class App extends Application {
out.close();
try {
if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {
java.io.File f = new java.io.File(android.os.Environment.getExternalStorageDirectory(), "Minamp-error.txt");
java.io.File f = new java.io.File(android.os.Environment.getExternalStorageDirectory(), "PlexampLite-error.txt");
java.io.FileOutputStream o2 = new java.io.FileOutputStream(f);
o2.write(text);
o2.close();
+3 -3
View File
@@ -80,7 +80,7 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
super.onCreate(b);
}
/** If the last run hit an error, show it so it can be reported (also saved as Minamp-error.txt on the SD card). */
/** If the last run hit an error, show it so it can be reported (also saved as PlexampLite-error.txt on the SD card). */
protected void showCrashReportIfAny() {
final String report = app.takeCrashReport();
if (report == null) return;
@@ -530,9 +530,9 @@ public abstract class BaseActivity extends Activity implements PlayerService.Lis
toast(str(R.string.no_sd));
return;
}
java.io.File f = new java.io.File(android.os.Environment.getExternalStorageDirectory(), "Minamp-log.txt");
java.io.File f = new java.io.File(android.os.Environment.getExternalStorageDirectory(), "PlexampLite-log.txt");
java.io.FileOutputStream o = new java.io.FileOutputStream(f);
String head = "Minamp " + com.minamp.plex.Plex.version + " on " + android.os.Build.MODEL
String head = "Plexamp Lite " + com.minamp.plex.Plex.version + " on " + android.os.Build.MODEL
+ ", Android " + android.os.Build.VERSION.RELEASE + "\n";
o.write((head + com.minamp.net.DiagLog.dump()).getBytes("UTF-8"));
o.close();
+1 -1
View File
@@ -90,7 +90,7 @@ public class HomeActivity extends BaseActivity {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.getBooleanExtra("exit", false)) { finish(); return; } // "Close Minamp"
if (intent.getBooleanExtra("exit", false)) { finish(); return; } // "Close Plexamp Lite"
if (intent.getBooleanExtra("relaunch", false)) {
// language changed: rebuild from scratch so every inflated text is re-read
finish();
+2 -2
View File
@@ -109,7 +109,7 @@ public class SetupActivity extends BaseActivity {
public Plex.Pin work() throws Exception { return Plex.createPin(); }
public void done(Plex.Pin p) {
if (my != pinSeq) return;
// Remember the code: the phone may close Minamp while you type it in elsewhere.
// Remember the code: the phone may close Plexamp Lite while you type it in elsewhere.
app.prefs.edit().putLong("pinId", p.id).putString("pinCode", p.code)
.putLong("pinStart", System.currentTimeMillis()).commit();
showPin(p.id, p.code, System.currentTimeMillis());
@@ -122,7 +122,7 @@ public class SetupActivity extends BaseActivity {
});
}
/** Resume waiting for a code created earlier (Minamp was closed while the user typed it in). */
/** Resume waiting for a code created earlier (Plexamp Lite was closed while the user typed it in). */
private boolean resumePendingPin() {
long id = app.prefs.getLong("pinId", 0);
String code = app.prefs.getString("pinCode", null);
+1 -1
View File
@@ -19,7 +19,7 @@ public final class DiagLog {
private DiagLog() {}
public static void log(String msg) {
android.util.Log.i("Minamp", msg); // also in logcat: readable over USB after the fact
android.util.Log.i("PlexampLite", msg); // also in logcat: readable over USB after the fact
String line;
synchronized (fmt) { line = fmt.format(new Date()) + " " + msg; }
synchronized (lines) {
+1 -1
View File
@@ -37,7 +37,7 @@ import com.minamp.bc.tls.crypto.impl.bc.BcTlsCrypto;
*/
public final class Http {
public static final String USER_AGENT = "Minamp/1.0";
public static final String USER_AGENT = "PlexampLite/1.0";
/** Optional HTTP CONNECT proxy, only used when running the networking code on a desktop JVM. */
public static String proxyHost;
+1 -1
View File
@@ -14,7 +14,7 @@ import com.minamp.util.Json;
/** Client identity + plex.tv account calls (PIN sign-in, server discovery). */
public final class Plex {
public static String product = "Minamp";
public static String product = "Plexamp Lite";
public static String version = "1.0";
public static String clientId = "minamp-dev";
public static String platform = "Android";
+2 -2
View File
@@ -1,4 +1,4 @@
"""Mock plex.tv + Plex Media Server for exercising Minamp's networking code on a desktop JVM.
"""Mock plex.tv + Plex Media Server for exercising Plexamp Lite's networking code on a desktop JVM.
Serves:
https://plex.tv:443 pins, user, resources
@@ -26,7 +26,7 @@ NOW = datetime.datetime.now(datetime.timezone.utc)
def name(cn):
return x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Minamp Test"), x509.NameAttribute(NameOID.COMMON_NAME, cn)])
return x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Plexamp Lite Test"), x509.NameAttribute(NameOID.COMMON_NAME, cn)])
def cert(subject, issuer, pub, signer, hashalg, ca, sans=None):
+1 -1
View File
@@ -66,6 +66,6 @@ echo "== signing key"
if [ ! -f minamp.keystore ]; then
if [ -f "$PROJ/signing/minamp.keystore" ]; then cp "$PROJ/signing/minamp.keystore" .; else
keytool -genkeypair -keystore minamp.keystore -storepass minamp123 -keypass minamp123 -alias minamp \
-keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 20000 -dname "CN=Minamp, O=Minamp"; fi
-keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 20000 -dname "CN=Plexamp Lite, O=Plexamp Lite"; fi
fi
echo "Toolchain ready in $T — build with: TOOLS=$T ./build.sh"
+7 -5
View File
@@ -7,7 +7,7 @@ Run: python3 tools/strings.py
import os
S = {
"app_name": ("Minamp", "Minamp"),
"app_name": ("Plexamp Lite", "Plexamp Lite"),
# tabs / headers
"tab_home": ("Home", "Inicio"),
@@ -75,7 +75,7 @@ S = {
"cant_load_tap": ("Couldn't load: %1$s (tap to retry)", "Non se puido cargar: %1$s (toca para tentar de novo)"),
"on": ("On", "Activado"),
"off": ("Off", "Desactivado"),
"error_last_time": ("Minamp hit an error last time", "Minamp tivo un erro a última vez"),
"error_last_time": ("Plexamp Lite hit an error last time", "Plexamp Lite tivo un erro a última vez"),
"min": ("%1$d min", "%1$d min"),
"h_min": ("%1$d h %2$d min", "%1$d h %2$d min"),
@@ -153,7 +153,7 @@ S = {
"save_to_sd": ("Save to SD card", "Gardar na tarxeta SD"),
"test_streaming": ("Test streaming", "Probar reprodución"),
"no_sd": ("No SD card available", "Non hai tarxeta SD dispoñible"),
"saved_log": ("Saved as Minamp-log.txt on the SD card", "Gardado como Minamp-log.txt na tarxeta SD"),
"saved_log": ("Saved as PlexampLite-log.txt on the SD card", "Gardado como PlexampLite-log.txt na tarxeta SD"),
"cant_save": ("Couldn't save: %1$s", "Non se puido gardar: %1$s"),
"testing": ("Testing… (about 30 s)", "Probando… (uns 30 s)"),
@@ -255,8 +255,10 @@ S = {
"dl_quality_original": ("Original MP3s, others 320 kbps", "MP3 orixinais, o resto a 320 kbps"),
"set_delete_downloads": ("Delete all downloads (%1$s)", "Borrar todas as descargas (%1$s)"),
"downloaded": ("Downloaded", "Descargada"),
"quit_app": ("Close Minamp", "Pechar Minamp"),
"stalled": ("Playback is stuck. Try pausing and playing again.", "A reprodución quedou parada. Proba a pausar e reproducir de novo."),
"quit_app": ("Close Plexamp Lite", "Pechar Plexamp Lite"),
"stalled": ("Playback got stuck: the network isn't keeping up.", "A reprodución quedou parada: a rede non dá abasto."),
"quality_bt_title": ("Quality over Bluetooth", "Calidade por Bluetooth"),
"set_quality_bt": ("Quality over Bluetooth: %1$s", "Calidade por Bluetooth: %1$s"),
# pure-Java layers (looked up by name through com.minamp.util.Tr)
"tr_kind_home": ("Home network", "Rede da casa"),