Private
Public Access
Minamp 1.1
- Run network/TLS work on 256 KB-stack threads (net/Threads.java): Android 2.x's ~16 KB default stack overflowed during the bundled TLS handshake - Close pooled TLS connections off the caller thread - Try several Plex music-transcoder URL variants until the server accepts one, and remember the one that worked - Accept pasted server URLs with paths; default to 443 for https - Catch fatal errors and save a crash report (shown on next launch and written to Minamp-error.txt on the SD card) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
948d1198ad
commit
0a2ac901bd
16 files changed
+417
-80
No files matched your search
@@ -36,7 +36,7 @@ public final class Library {
|
||||
}
|
||||
|
||||
public String recentlyPlayedPath(int size) {
|
||||
return "/library/sections/" + section + "/all?type=9&sort=lastViewedAt:desc&viewCount>>=0" + page(0, size);
|
||||
return "/library/sections/" + section + "/all?type=9&sort=lastViewedAt:desc&viewCount%3E%3E=0" + page(0, size);
|
||||
}
|
||||
|
||||
public String playlistsPath() {
|
||||
@@ -84,7 +84,7 @@ public final class Library {
|
||||
|
||||
/** Tracks rated four stars or better (and loved tracks), shuffled. */
|
||||
public List<Item> topRatedRadio() throws IOException {
|
||||
return server.items("/library/sections/" + section + "/all?type=10&userRating>>=7&sort=random" + page(0, 100));
|
||||
return server.items("/library/sections/" + section + "/all?type=10&userRating%3E%3E=7&sort=random" + page(0, 100));
|
||||
}
|
||||
|
||||
/** Tracks from albums released in a random decade that the library actually has. */
|
||||
@@ -172,15 +172,56 @@ public final class Library {
|
||||
return server.url(t.partKey);
|
||||
}
|
||||
|
||||
/** MP3 transcode over plain progressive HTTP, starting at offsetMs. */
|
||||
public String transcodeUrl(Item t, int kbps, long offsetMs, String session) throws IOException {
|
||||
/**
|
||||
* Plex servers differ in which form of the music transcoder request they accept (some answer
|
||||
* 400 to one and stream fine with another), so there are several known variants. The proxy
|
||||
* tries them in order; the one that worked is remembered and tried first next time.
|
||||
*/
|
||||
public static final int VARIANTS = 4;
|
||||
public static volatile int preferredVariant = 0;
|
||||
|
||||
public static int[] variantOrder() {
|
||||
int[] order = new int[VARIANTS];
|
||||
order[0] = preferredVariant;
|
||||
for (int i = 0, k = 1; i < VARIANTS; i++) if (i != preferredVariant) order[k++] = i;
|
||||
return order;
|
||||
}
|
||||
|
||||
/** MP3 transcode URLs over plain progressive HTTP starting at offsetMs, in {@link #variantOrder()} order. */
|
||||
public java.util.List<String> transcodeUrls(Item t, int kbps, long offsetMs, String session) throws IOException {
|
||||
int[] order = variantOrder();
|
||||
java.util.List<String> out = new ArrayList<String>();
|
||||
for (int i = 0; i < order.length; i++) out.add(transcodeUrl(t, kbps, offsetMs, session, order[i]));
|
||||
return out;
|
||||
}
|
||||
|
||||
String transcodeUrl(Item t, int kbps, long offsetMs, String session, int variant) throws IOException {
|
||||
if (kbps <= 0) kbps = 320;
|
||||
String profile = "add-transcode-target(type=musicProfile&context=streaming&protocol=http&container=mp3&audioCodec=mp3)"
|
||||
+ "+add-limitation(scope=musicCodec&scopeName=mp3&type=upperBound&name=audio.bitrate&value=" + kbps + ")"
|
||||
+ "+add-limitation(scope=musicCodec&scopeName=mp3&type=upperBound&name=audio.channels&value=2)";
|
||||
String path = "/music/:/transcode/universal/start.mp3"
|
||||
String target = "add-transcode-target(type=musicProfile&context=streaming&protocol=http&container=mp3&audioCodec=mp3)";
|
||||
String profile;
|
||||
String platform;
|
||||
String base = "/music/:/transcode/universal/start.mp3";
|
||||
switch (variant) {
|
||||
case 0: // what Plex's own web player identifies as, with an explicit MP3 target
|
||||
platform = "Chrome";
|
||||
profile = target + "+add-limitation(scope=musicCodec&scopeName=*&type=upperBound&name=audio.bitrate&value=" + kbps + ")";
|
||||
break;
|
||||
case 1: // generic client profile
|
||||
platform = "Generic";
|
||||
profile = target + "+add-limitation(scope=musicCodec&scopeName=mp3&type=upperBound&name=audio.bitrate&value=" + kbps + ")";
|
||||
break;
|
||||
case 2: // older servers' audio endpoint
|
||||
platform = "Chrome";
|
||||
profile = target;
|
||||
base = "/audio/:/transcode/universal/start.mp3";
|
||||
break;
|
||||
default: // no profile tweaks at all; bitrate from musicBitrate only
|
||||
platform = "Chrome";
|
||||
profile = null;
|
||||
}
|
||||
String path = base
|
||||
+ "?path=" + Plex.enc("/library/metadata/" + t.ratingKey)
|
||||
+ "&mediaIndex=0&partIndex=0&protocol=http&hasMDE=1&fastSeek=1"
|
||||
+ "&mediaIndex=0&partIndex=0&protocol=http&hasMDE=1&fastSeek=1©ts=1"
|
||||
+ "&directPlay=0&directStream=0&directStreamAudio=0"
|
||||
+ "&musicBitrate=" + kbps + "&maxAudioBitrate=" + kbps
|
||||
+ "&offset=" + (offsetMs / 1000)
|
||||
@@ -190,9 +231,9 @@ public final class Library {
|
||||
+ "&X-Plex-Client-Identifier=" + Plex.enc(Plex.clientId)
|
||||
+ "&X-Plex-Product=" + Plex.enc(Plex.product)
|
||||
+ "&X-Plex-Version=" + Plex.enc(Plex.version)
|
||||
+ "&X-Plex-Platform=Generic"
|
||||
+ "&X-Plex-Platform=" + platform
|
||||
+ "&X-Plex-Device=" + Plex.enc(Plex.device)
|
||||
+ "&X-Plex-Client-Profile-Extra=" + Plex.enc(profile);
|
||||
+ (profile != null ? "&X-Plex-Client-Profile-Extra=" + Plex.enc(profile) : "");
|
||||
return server.url(path);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user