Private
Public Access
Minamp 1.5: Galician interface
- Interface in Galician by default regardless of the phone's language, with English selectable under Axustes -> Idioma; switching rebuilds the screens - All text in tools/strings.py (key -> English, Galician), generating res/values/strings.xml (gl) and res/values-en/strings.xml; layouts now use string resources - util/Tr.java: translations for the network and Plex layers, which can't read Android resources (falls back to English in desktop tests) - net/RefusedException: distinguish "server answered but refused" from connection failures - The connection log stays in English for troubleshooting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6fd17bc9c5
commit
fa67e95fde
29 files changed
+1029
-206
No files matched your search
@@ -146,6 +146,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
App.applyLanguage(this);
|
||||
instance = this;
|
||||
audio = (AudioManager) getSystemService(AUDIO_SERVICE);
|
||||
audio.registerMediaButtonEventReceiver(new ComponentName(this, MediaButtonReceiver.class));
|
||||
@@ -261,7 +262,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
offsetMs = 0;
|
||||
lastPos = posMs;
|
||||
playWhenReady = play;
|
||||
setState(BUFFERING, "Connecting…");
|
||||
setState(BUFFERING, getString(R.string.connecting));
|
||||
goForeground();
|
||||
if (play) requestFocus();
|
||||
final boolean download = forceDownload || app.downloadFirst();
|
||||
@@ -297,8 +298,13 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
} catch (final Throwable e) {
|
||||
if (!(e instanceof Exception)) App.logError("player", e);
|
||||
final String m = com.minamp.net.Threads.describe(e);
|
||||
final int code = e instanceof com.minamp.net.RefusedException ? ((com.minamp.net.RefusedException) e).code : 0;
|
||||
post(new Runnable() {
|
||||
public void run() { if (g == gen) trackFailed(m); }
|
||||
public void run() {
|
||||
if (g != gen) return;
|
||||
if (code > 0) { refusal = m; refusalCode = code; }
|
||||
trackFailed(m);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -319,6 +325,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
File f = new File(base, "play-" + (g % 2) + ".tmp");
|
||||
Http.Response r = null;
|
||||
String why = null;
|
||||
int lastCode = 0;
|
||||
for (int i = 0; i < urls.size(); i++) {
|
||||
r = Http.get(urls.get(i), App.get().server != null ? App.get().server.mediaHeaders() : Plex.headers(null), 30000);
|
||||
if (r.code == 200) {
|
||||
@@ -328,12 +335,13 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
}
|
||||
break;
|
||||
}
|
||||
why = "Server refused the stream (" + r.code + ")";
|
||||
why = com.minamp.util.Tr.t("refused", "Server refused the stream (%1$d)", r.code);
|
||||
String body = new String(r.readAll(), "UTF-8");
|
||||
if (body.trim().length() > 0) why += ": " + Plex.snippet(body);
|
||||
lastCode = r.code;
|
||||
r = null;
|
||||
}
|
||||
if (r == null) throw new IOException(why);
|
||||
if (r == null) throw new com.minamp.net.RefusedException(lastCode, why);
|
||||
InputStream in = r.body;
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
try {
|
||||
@@ -349,7 +357,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
lastUi = got;
|
||||
final int pct = (int) Math.min(99, got * 100 / total);
|
||||
final int fg = g;
|
||||
post(new Runnable() { public void run() { if (fg == gen) setState(BUFFERING, "Downloading " + pct + "%"); } });
|
||||
post(new Runnable() { public void run() { if (fg == gen) setState(BUFFERING, getString(R.string.downloading_pct, pct)); } });
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -400,7 +408,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
mp.setDataSource(proxy.register(routeId, urls, ext, transcoding,
|
||||
App.get().server != null ? App.get().server.mediaHeaders() : null));
|
||||
}
|
||||
setState(BUFFERING, "Buffering…");
|
||||
setState(BUFFERING, getString(R.string.buffering));
|
||||
mp.prepareAsync();
|
||||
} catch (Exception e) {
|
||||
trackFailed(message(e));
|
||||
@@ -433,7 +441,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
Item it = track;
|
||||
// A stream that ends well before the track does means the network dropped.
|
||||
if (it != null && it.duration > 0 && pos > 0 && pos < it.duration - 15000 && !fromFile) {
|
||||
trackFailed("Stream interrupted");
|
||||
trackFailed(getString(R.string.stream_interrupted));
|
||||
return;
|
||||
}
|
||||
if (it != null) {
|
||||
@@ -443,7 +451,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
if (sleepEndOfTrack) {
|
||||
sleepEndOfTrack = false;
|
||||
PlayQueue.get().advance(false);
|
||||
stopAll("Sleep timer");
|
||||
stopAll(getString(R.string.sleep_timer));
|
||||
return;
|
||||
}
|
||||
if (PlayQueue.get().advance(false)) {
|
||||
@@ -457,15 +465,14 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
|
||||
public boolean onError(MediaPlayer p, int what, int extra) {
|
||||
if (p != mp) return true;
|
||||
trackFailed("Playback error (" + what + "/" + extra + ")");
|
||||
trackFailed(getString(R.string.playback_error, what, extra));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void trackFailed(String msg) {
|
||||
long pos = Math.max(currentPosition(), lastPos);
|
||||
if (refusal != null) msg = refusal; // the server's own reason beats "Playback error (1/-1004)"
|
||||
boolean permanent = refusalCode >= 400 && refusalCode < 500 && refusalCode != 408 && refusalCode != 429
|
||||
|| (msg != null && msg.startsWith("Server refused the stream (4"));
|
||||
boolean permanent = refusalCode >= 400 && refusalCode < 500 && refusalCode != 408 && refusalCode != 429;
|
||||
refusal = null;
|
||||
refusalCode = 0;
|
||||
retries = permanent ? 99 : retries + 1;
|
||||
@@ -593,7 +600,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
if (sleepAt > 0 && now >= sleepAt) {
|
||||
sleepAt = 0;
|
||||
pause();
|
||||
toast("Sleep timer: paused");
|
||||
toast(getString(R.string.sleep_paused));
|
||||
}
|
||||
if (state == PLAYING && track != null) {
|
||||
long pos = currentPosition();
|
||||
@@ -700,7 +707,7 @@ public class PlayerService extends Service implements MediaPlayer.OnPreparedList
|
||||
n.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
|
||||
Intent open = new Intent(this, NowPlayingActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent pi = PendingIntent.getActivity(this, 0, open, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
String line = (state == PAUSED ? "Paused · " : "") + it.artist;
|
||||
String line = (state == PAUSED ? getString(R.string.paused_dot) : "") + it.artist;
|
||||
n.setLatestEventInfo(this, it.title, line, pi);
|
||||
if (state == PAUSED || state == IDLE) {
|
||||
// let Android reclaim us while paused, but keep the notification as a shortcut back
|
||||
|
||||
Reference in new issue
Block a user