🎉 v10.1.2: Reproductor robusto con calidad adaptativa
✨ Mejoras principales: - Reproductor más robusto: reintenta automáticamente en errores 404 - Calidad adaptativa: eliminado forzamiento de 1080p - Sistema de reintentos: 3 intentos automáticos con delays - Timeouts mejorados: 20s connect, 30s read - Manejo granular de errores recuperables 📱 Cambios técnicos: - setForceHighestSupportedBitrate(false) - calidad adaptativa - Configuración de reintentos (MAX_RETRIES = 3) - Detección de errores 404, 403, timeout, network - Feedback visual durante reintentos - Timeouts incrementados para conexiones lentas 🔧 Build: - Incrementado versionCode: 100101 → 100102 - Incrementado versionName: 10.1.1 → 10.1.2 - APK compilado y subido a Gitea 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2
.env
2
.env
@@ -1,4 +1,4 @@
|
||||
GITEA_TOKEN=7921aa22187b39125d29399d26f527ba26a2fb5b
|
||||
GITEA_TOKEN=efeed2af00597883adb04da70bd6a7c2993ae92d
|
||||
GEMINI_API_KEY=AIzaSyDWOgyAJqscuPU6iSpS6gxupWBm4soNw5o
|
||||
TELEGRAM_BOT_TOKEN=8593525164:AAGCX9B_RJGN35_F7tSB72rEZhS_4Zpcszs
|
||||
TELEGRAM_CHAT_ID=692714536
|
||||
|
||||
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.streamplayer"
|
||||
minSdk 21
|
||||
targetSdk 35
|
||||
versionCode 100101
|
||||
versionName "10.1.1"
|
||||
versionCode 100102
|
||||
versionName "10.1.2"
|
||||
buildConfigField "String", "DEVICE_REGISTRY_URL", '"http://194.163.191.200:4000"'
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@ public class PlayerActivity extends AppCompatActivity {
|
||||
private String channelUrl;
|
||||
private boolean overlayVisible = true;
|
||||
private OkHttpClient okHttpClient;
|
||||
private int retryCount = 0;
|
||||
private static final int MAX_RETRIES = 3;
|
||||
private String lastStreamUrl;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -102,6 +105,7 @@ public class PlayerActivity extends AppCompatActivity {
|
||||
|
||||
private void loadChannel() {
|
||||
showLoading(true);
|
||||
retryCount = 0; // Resetear contador al cargar nuevo canal
|
||||
new Thread(() -> {
|
||||
try {
|
||||
String resolvedUrl = StreamUrlResolver.resolve(channelUrl);
|
||||
@@ -117,14 +121,17 @@ public class PlayerActivity extends AppCompatActivity {
|
||||
private void startPlayback(String streamUrl) {
|
||||
try {
|
||||
releasePlayer();
|
||||
lastStreamUrl = streamUrl; // Guardar URL para reintentos
|
||||
retryCount = 0; // Resetear contador al iniciar nueva reproducción
|
||||
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(this)
|
||||
.setEnableDecoderFallback(true)
|
||||
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON);
|
||||
|
||||
// Configurar track selector para máxima calidad
|
||||
// Configurar track selector para calidad adaptativa (no forzar máxima calidad)
|
||||
trackSelector = new DefaultTrackSelector(this);
|
||||
DefaultTrackSelector.Parameters params = trackSelector.buildUponParameters()
|
||||
.setForceHighestSupportedBitrate(true) // Forzar máximo bitrate
|
||||
.setForceHighestSupportedBitrate(false) // Permitir calidad adaptativa
|
||||
.setMaxVideoBitrate(Integer.MAX_VALUE) // Sin límite máximo de bitrate
|
||||
.build();
|
||||
trackSelector.setParameters(params);
|
||||
|
||||
@@ -140,6 +147,7 @@ public class PlayerActivity extends AppCompatActivity {
|
||||
public void onPlaybackStateChanged(int playbackState) {
|
||||
if (playbackState == Player.STATE_READY) {
|
||||
showLoading(false);
|
||||
retryCount = 0; // Resetear contador de reintentos al reproducir exitosamente
|
||||
} else if (playbackState == Player.STATE_BUFFERING) {
|
||||
showLoading(true);
|
||||
}
|
||||
@@ -147,9 +155,46 @@ public class PlayerActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onPlayerError(PlaybackException error) {
|
||||
String detail = error.getCause() != null ?
|
||||
String errorMsg = error.getMessage() != null ? error.getMessage() : "";
|
||||
String detail = error.getCause() != null ?
|
||||
error.getCause().getMessage() : "";
|
||||
showError("Error al reproducir: " + error.getMessage() + " " + detail);
|
||||
String fullError = errorMsg + " " + detail;
|
||||
|
||||
// Verificar si es un error que justifica reintento (404, conectividad, etc.)
|
||||
boolean isRetryableError =
|
||||
fullError.contains("404") ||
|
||||
fullError.contains("403") ||
|
||||
fullError.contains("timeout") ||
|
||||
fullError.contains("Unable to connect") ||
|
||||
fullError.contains("Network") ||
|
||||
fullError.contains("source error") ||
|
||||
error.errorCode == PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED ||
|
||||
error.errorCode == PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT ||
|
||||
error.errorCode == PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS;
|
||||
|
||||
if (isRetryableError && retryCount < MAX_RETRIES) {
|
||||
retryCount++;
|
||||
runOnUiThread(() -> {
|
||||
showLoading(true);
|
||||
showError("Error de conexión. Reintentando... (" + retryCount + "/" + MAX_RETRIES + ")");
|
||||
});
|
||||
|
||||
// Reintentar después de 2 segundos
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
|
||||
if (lastStreamUrl != null) {
|
||||
startPlayback(lastStreamUrl);
|
||||
} else {
|
||||
loadChannel();
|
||||
}
|
||||
}, 2000);
|
||||
} else {
|
||||
// Mostrar error final después de agotar reintentos
|
||||
String finalMessage = "Error al reproducir: " + fullError;
|
||||
if (retryCount >= MAX_RETRIES) {
|
||||
finalMessage += "\n\nSe agotaron los reintentos (" + MAX_RETRIES + ").";
|
||||
}
|
||||
showError(finalMessage);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -210,8 +255,8 @@ public class PlayerActivity extends AppCompatActivity {
|
||||
|
||||
try {
|
||||
OkHttpClient bootstrap = new OkHttpClient.Builder()
|
||||
.connectTimeout(15, TimeUnit.SECONDS)
|
||||
.readTimeout(15, TimeUnit.SECONDS)
|
||||
.connectTimeout(20, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.retryOnConnectionFailure(true)
|
||||
.build();
|
||||
|
||||
@@ -228,8 +273,8 @@ public class PlayerActivity extends AppCompatActivity {
|
||||
.build();
|
||||
} catch (UnknownHostException e) {
|
||||
okHttpClient = new OkHttpClient.Builder()
|
||||
.connectTimeout(15, TimeUnit.SECONDS)
|
||||
.readTimeout(15, TimeUnit.SECONDS)
|
||||
.connectTimeout(20, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.retryOnConnectionFailure(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user