Minamp 1.2

- Transcoding: send client identities Plex has a profile for (unknown ones get
  400 "unable to find a matching profile"), with a fresh session id per variant
- Stream proxy: fetch transcodes once into a temp file and serve every player
  request from it, so reconnects no longer restart the transcode (503s, tracks
  cut short); original files still pass Range requests through
- Sign-in: remember the pending link code so it survives Minamp being closed
  while the code is entered elsewhere; add "I've entered it - check now"
- Diagnostics: in-app connection log (DiagLog) with a streaming test and save
  to SD card; tokens are never logged

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xockoandClaude Opus 5.5 committed 2026-10-14 20:38:17 +02:00
1 parent 0a2ac901bd
commit a4b875ef34
12 files changed
+701 -196

No files matched your search

+16 -5
View File
@@ -125,6 +125,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
private String routeId;
private int retries;
private int[] variantOrder; // transcode variant behind each URL of the current route
private int acceptedVariant = -1;
private String refusal; // what the server said when it refused the current stream
private int refusalCode;
private int failuresInRow;
@@ -166,6 +167,11 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
});
}
};
File cache = null;
try {
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) cache = getExternalCacheDir();
} catch (Exception ignored) {}
proxy.cacheDir = cache != null ? cache : getCacheDir();
try { proxy.start(); } catch (IOException e) { /* reported when playback starts */ }
try {
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
@@ -360,6 +366,8 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
private void rememberVariantOf(int[] order, int index) {
if (order == null || index < 0 || index >= order.length) return;
int v = order[index];
if (order == variantOrder) acceptedVariant = v;
com.minamp.net.DiagLog.log("server accepted transcode variant " + v + " (" + Library.VARIANT_NAMES[v] + ")");
if (v != Library.preferredVariant) {
Library.preferredVariant = v;
App.get().prefs.edit().putInt("tcVariant", v).commit();
@@ -387,7 +395,9 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
routeId = proxy.newId();
refusal = null;
refusalCode = 0;
mp.setDataSource(proxy.register(routeId, urls, ext));
acceptedVariant = -1;
// transcodes are fetched once and buffered, so player reconnects can't restart them
mp.setDataSource(proxy.register(routeId, urls, ext, transcoding));
}
setState(BUFFERING, "Buffering…");
mp.prepareAsync();
@@ -520,7 +530,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
if (track == null) return;
if (ms < 0) ms = 0;
if (track.duration > 0 && ms > track.duration - 1000) ms = Math.max(0, track.duration - 1000);
if (mp != null && prepared && (!transcoding || fromFile)) {
if (mp != null && prepared && (!transcoding || fromFile || proxy.isComplete(routeId))) {
try { mp.seekTo((int) ms); } catch (Exception ignored) {}
lastPos = ms;
notifyListeners();
@@ -551,12 +561,13 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
private void releasePlayer() {
if (routeId != null) { proxy.unregister(routeId); routeId = null; }
if (session != null) {
final String s = session;
if (session != null && acceptedVariant >= 0) {
final String s = Library.variantSession(session, acceptedVariant);
final App app = App.get();
reporter.execute(new Runnable() { public void run() { if (app.library != null) app.library.stopTranscode(s); } });
session = null;
}
session = null;
acceptedVariant = -1;
if (mp != null) {
try { mp.reset(); } catch (Exception ignored) {}
try { mp.release(); } catch (Exception ignored) {}