再次优化EXO的dns解析;解决频繁切换导致播放失败的问题

pull/137/head
于俊 10 months ago
parent 3fa48217e8
commit 9bcda08ab3
  1. 2
      app/src/main/java/com/github/tvbox/osc/player/IjkMediaPlayer.java
  2. 62
      app/src/main/java/com/github/tvbox/osc/util/OkGoHelper.java

@ -68,7 +68,7 @@ public class IjkMediaPlayer extends IjkPlayer {
// mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer"); // 减少协议层缓冲 // mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer"); // 减少协议层缓冲
}else{ }else{
LOG.i("type-点播"); LOG.i("type-点播");
mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 100); // mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 100);
mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_FORMAT, "infbuf", 0); mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_FORMAT, "infbuf", 0);
mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 5); mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 5);
} }

@ -20,11 +20,10 @@ import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
@ -39,6 +38,7 @@ import okhttp3.dnsoverhttps.DnsOverHttps;
import okhttp3.internal.Version; import okhttp3.internal.Version;
import xyz.doikki.videoplayer.exo.ExoMediaSourceHelper; import xyz.doikki.videoplayer.exo.ExoMediaSourceHelper;
public class OkGoHelper { public class OkGoHelper {
public static final long DEFAULT_MILLISECONDS = 8000; //默认的超时时间 public static final long DEFAULT_MILLISECONDS = 8000; //默认的超时时间
@ -66,6 +66,7 @@ public class OkGoHelper {
th.printStackTrace(); th.printStackTrace();
} }
// builder.dns(dnsOverHttps);
builder.dns(new CustomDns()); builder.dns(new CustomDns());
ExoMediaSourceHelper.getInstance(App.getInstance()).setOkClient(builder.build()); ExoMediaSourceHelper.getInstance(App.getInstance()).setOkClient(builder.build());
@ -76,7 +77,7 @@ public class OkGoHelper {
public static ArrayList<String> dnsHttpsList = new ArrayList<>(); public static ArrayList<String> dnsHttpsList = new ArrayList<>();
public static boolean is_doh = false; public static boolean is_doh = false;
public static Map<String,String> myHosts = null; public static Map<String, String> myHosts = null;
public static String getDohUrl(int type) { public static String getDohUrl(int type) {
@ -125,35 +126,52 @@ public class OkGoHelper {
builder.cache(new Cache(new File(App.getInstance().getCacheDir().getAbsolutePath(), "dohcache"), 100 * 1024 * 1024)); builder.cache(new Cache(new File(App.getInstance().getCacheDir().getAbsolutePath(), "dohcache"), 100 * 1024 * 1024));
OkHttpClient dohClient = builder.build(); OkHttpClient dohClient = builder.build();
String dohUrl = getDohUrl(Hawk.get(HawkConfig.DOH_URL, 0)); String dohUrl = getDohUrl(Hawk.get(HawkConfig.DOH_URL, 0));
if(!dohUrl.isEmpty())is_doh=true; if (!dohUrl.isEmpty()) is_doh = true;
dnsOverHttps = new DnsOverHttps.Builder() dnsOverHttps = new DnsOverHttps.Builder()
.client(dohClient) .client(dohClient)
.url(dohUrl.isEmpty()?null:HttpUrl.get(dohUrl)) .url(dohUrl.isEmpty() ? null : HttpUrl.get(dohUrl))
.build(); .build();
} }
// 自定义 DNS 解析器,优先使用 DoH,失败时降级到系统 DNS // 自定义 DNS 解析器
static class CustomDns implements Dns { static class CustomDns implements Dns {
@NonNull @NonNull
@Override @Override
public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException { public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
if(myHosts==null){ if (myHosts == null)myHosts = ApiConfig.get().getMyHost(); //确保只获取一次减少消耗
LOG.i("echo-exo-setHOSTS"); // 判断输入是否为 IP 地址
myHosts= ApiConfig.get().getMyHost(); if (isValidIpAddress(hostname)) {
return Collections.singletonList(InetAddress.getByName(hostname));
} else {
if(!myHosts.isEmpty() && myHosts.containsKey(hostname))hostname=myHosts.get(hostname);
assert hostname != null;
// return (is_doh?dnsOverHttps:Dns.SYSTEM).lookup(hostname);
return (dnsOverHttps).lookup(hostname);
} }
if (is_doh && !hostname.equals("127.0.0.1")) { }
if (!myHosts.isEmpty() && myHosts.containsKey(hostname)) {
return dnsOverHttps.lookup(Objects.requireNonNull(myHosts.get(hostname))); //简单判断减少开销
}else { private boolean isValidIpAddress(String str) {
return dnsOverHttps.lookup(hostname); // 处理 IPv4 地址的判断
} if (str.indexOf('.') > 0)return isValidIPv4(str);
}else { // 处理 IPv6 地址的判断
if (!myHosts.isEmpty() && myHosts.containsKey(hostname)) { if (str.indexOf(':') > 0)return true;
return Dns.SYSTEM.lookup(Objects.requireNonNull(myHosts.get(hostname))); return false;
}else { }
return Dns.SYSTEM.lookup(hostname);
private boolean isValidIPv4(String str) {
String[] parts = str.split("\\.");
// IPv4 地址必须有 4 个部分
if (parts.length != 4)return false;
// 检查每一部分是否是 0-255 的数字
for (String part : parts) {
try {
Integer.parseInt(part);
} catch (NumberFormatException e) {
return false;
} }
} }
return true;
} }
} }
@ -190,7 +208,7 @@ public class OkGoHelper {
builder.writeTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS); builder.writeTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
builder.connectTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS); builder.connectTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
if(dnsOverHttps!=null)builder.dns(dnsOverHttps); builder.dns(dnsOverHttps);
try { try {
setOkHttpSsl(builder); setOkHttpSsl(builder);
} catch (Throwable th) { } catch (Throwable th) {

Loading…
Cancel
Save