95 lines
3.4 KiB
Java
95 lines
3.4 KiB
Java
package com.streamplayer;
|
|
|
|
import java.io.IOException;
|
|
import java.net.InetAddress;
|
|
import java.net.UnknownHostException;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import okhttp3.HttpUrl;
|
|
import okhttp3.OkHttpClient;
|
|
import okhttp3.Request;
|
|
import okhttp3.Response;
|
|
import okhttp3.dnsoverhttps.DnsOverHttps;
|
|
|
|
/**
|
|
* Resuelve la URL real del stream extrayendo playbackURL de la página.
|
|
* Utiliza DNS de Google para evitar bloqueos.
|
|
*/
|
|
public final class StreamUrlResolver {
|
|
|
|
// Patrón para extraer la URL del stream directamente
|
|
private static final Pattern PLAYBACK_URL_PATTERN =
|
|
Pattern.compile("var\\s+playbackURL\\s*=\\s*[\"']([^\"']+)[\"']");
|
|
|
|
private static final String USER_AGENT = "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36";
|
|
|
|
private static final OkHttpClient CLIENT;
|
|
|
|
static {
|
|
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
|
.connectTimeout(15, TimeUnit.SECONDS)
|
|
.readTimeout(15, TimeUnit.SECONDS)
|
|
.followRedirects(true);
|
|
|
|
try {
|
|
// DNS de Google (8.8.8.8)
|
|
OkHttpClient bootstrap = new OkHttpClient.Builder().build();
|
|
DnsOverHttps dns = new DnsOverHttps.Builder()
|
|
.client(bootstrap)
|
|
.url(HttpUrl.get("https://dns.google/dns-query"))
|
|
.bootstrapDnsHosts(
|
|
InetAddress.getByName("8.8.8.8"),
|
|
InetAddress.getByName("8.8.4.4"))
|
|
.build();
|
|
builder.dns(dns);
|
|
} catch (UnknownHostException e) {
|
|
// Fallback a DNS del sistema
|
|
}
|
|
|
|
CLIENT = builder.build();
|
|
}
|
|
|
|
private StreamUrlResolver() {
|
|
}
|
|
|
|
public static String resolve(String pageUrl) throws IOException {
|
|
String html = downloadPage(pageUrl);
|
|
|
|
// Buscar playbackURL directamente en el HTML
|
|
Matcher matcher = PLAYBACK_URL_PATTERN.matcher(html);
|
|
if (matcher.find()) {
|
|
String url = matcher.group(1);
|
|
if (url != null && !url.isEmpty() && url.startsWith("http")) {
|
|
return url;
|
|
}
|
|
}
|
|
|
|
// Si no encontramos la URL, mostrar un fragmento del HTML para debug
|
|
String preview = html.length() > 500 ? html.substring(0, 500) : html;
|
|
throw new IOException("No se encontró la URL del stream en la página. Vista previa: " + preview);
|
|
}
|
|
|
|
private static String downloadPage(String pageUrl) throws IOException {
|
|
Request request = new Request.Builder()
|
|
.url(pageUrl)
|
|
.header("User-Agent", USER_AGENT)
|
|
.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
|
|
.header("Accept-Language", "es-ES,es;q=0.9,en;q=0.8")
|
|
.header("Referer", "http://streamtp10.com/")
|
|
.build();
|
|
|
|
try (Response response = CLIENT.newCall(request).execute()) {
|
|
if (!response.isSuccessful()) {
|
|
throw new IOException("Error HTTP " + response.code() + " al cargar la página del stream");
|
|
}
|
|
if (response.body() == null) {
|
|
throw new IOException("Respuesta vacía del servidor");
|
|
}
|
|
|
|
return response.body().string();
|
|
}
|
|
}
|
|
}
|