diff --git a/app/build.gradle b/app/build.gradle index d7568284ce..c8ce4dc9db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,7 +60,7 @@ android { dependencies { api fileTree(dir: "libs", include: ["*.jar"]) - + implementation 'org.conscrypt:conscrypt-android:2.5.2' implementation 'org.nanohttpd:nanohttpd:2.3.1' implementation 'com.google.zxing:core:3.4.1' @@ -73,11 +73,11 @@ dependencies { annotationProcessor 'androidx.room:room-compiler:2.3.0' implementation 'androidx.room:room-runtime:2.3.0' implementation 'androidx.multidex:multidex:2.0.1' - implementation 'com.squareup.okhttp3:okhttp:3.12.1' - implementation 'com.squareup.okio:okio:2.6.0' + implementation 'com.squareup.okhttp3:okhttp:3.12.13' + implementation 'com.squareup.okio:okio:3.2.0' implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.45-androidx' implementation 'com.kingja.loadsir:loadsir:1.3.8' - implementation 'com.google.code.gson:gson:2.8.7' + implementation 'com.google.code.gson:gson:2.9.1' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'me.jessyan:autosize:1.2.1' implementation('com.thoughtworks.xstream:xstream:1.4.15') { diff --git a/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java b/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java index 7f8573ed09..4a4998c916 100644 --- a/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java +++ b/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java @@ -19,6 +19,7 @@ import com.github.tvbox.osc.util.HawkConfig; import com.github.tvbox.osc.util.MD5; import com.github.tvbox.osc.util.VideoParseRuler; +import com.github.tvbox.osc.util.LOG; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -31,6 +32,8 @@ import org.json.JSONObject; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.StringReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -41,6 +44,7 @@ import java.util.List; import java.util.Map; + /** * @author pj567 * @date :2020/12/18 @@ -545,4 +549,93 @@ String fixContentPath(String url, String content) { } return content; } + + public void parseLiveTxt(LinkedHashMap>> linkedHashMap, String str) { + ArrayList arrayList; + try { + BufferedReader bufferedReader = new BufferedReader(new StringReader(str)); + String readLine = bufferedReader.readLine(); + LinkedHashMap> linkedHashMap2 = new LinkedHashMap<>(); + LinkedHashMap> linkedHashMap3 = linkedHashMap2; + while (readLine != null) { + if (readLine.trim().isEmpty()) { + readLine = bufferedReader.readLine(); + } else { + String[] split = readLine.split(","); + if (split.length < 2) { + readLine = bufferedReader.readLine(); + } else { + if (readLine.contains("#genre#")) { + String trim = split[0].trim(); + if (!linkedHashMap.containsKey(trim)) { + linkedHashMap3 = new LinkedHashMap<>(); + linkedHashMap.put(trim, linkedHashMap3); + } else { + linkedHashMap3 = linkedHashMap.get(trim); + } + } else { + String trim2 = split[0].trim(); + for (String str2 : split[1].trim().split("#")) { + String trim3 = str2.trim(); + if (!trim3.isEmpty() && (trim3.startsWith("http") || trim3.startsWith("rtsp") || trim3.startsWith("rtmp"))) { + if (!linkedHashMap3.containsKey(trim2)) { + arrayList = new ArrayList<>(); + linkedHashMap3.put(trim2, arrayList); + } else { + arrayList = linkedHashMap3.get(trim2); + } + if (!arrayList.contains(trim3)) { + arrayList.add(trim3); + } + } + } + } + readLine = bufferedReader.readLine(); + } + } + } + bufferedReader.close(); + if (linkedHashMap2.isEmpty()) { + return; + } + linkedHashMap.put("未分组", linkedHashMap2); + } catch (Throwable unused) { + } + } + + public JsonArray jsonifyLiveMap(LinkedHashMap>> linkedHashMap) { + JsonArray jsonarr = new JsonArray(); + for (String str : linkedHashMap.keySet()) { + JsonArray jsonarr2 = new JsonArray(); + LinkedHashMap> linkedHashMap2 = linkedHashMap.get(str); + if (!linkedHashMap2.isEmpty()) { + for (String str2 : linkedHashMap2.keySet()) { + ArrayList arrayList = linkedHashMap2.get(str2); + if (!arrayList.isEmpty()) { + JsonArray jsonarr3 = new JsonArray(); + for (int i = 0; i < arrayList.size(); i++) { + jsonarr3.add(arrayList.get(i)); + } + JsonObject jsonobj = new JsonObject(); + try { + jsonobj.addProperty("name", str2); + jsonobj.add("urls", jsonarr3); + } catch (Throwable e) { + } + jsonarr2.add(jsonobj); + } + } + JsonObject jsonobj2 = new JsonObject(); + try { + jsonobj2.addProperty("group", str); + jsonobj2.add("channels", jsonarr2); + } catch (Throwable e) { + } + jsonarr.add(jsonobj2); + } + } + return jsonarr; + } + + } diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java index c09b119e20..f8765c0ee2 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java @@ -17,6 +17,8 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import android.net.Uri; +import android.util.Base64; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; @@ -47,6 +49,7 @@ import com.github.tvbox.osc.util.HawkConfig; import com.github.tvbox.osc.util.urlhttp.CallBackUtil; import com.github.tvbox.osc.util.urlhttp.UrlHttpUtil; +import com.github.tvbox.osc.util.LOG; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -59,10 +62,6 @@ import com.owen.tvrecyclerview.widget.TvRecyclerView; import com.owen.tvrecyclerview.widget.V7LinearLayoutManager; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - import java.io.File; import java.io.FileOutputStream; import java.net.URLEncoder; @@ -71,8 +70,10 @@ import java.util.Arrays; import java.util.Date; import java.util.Hashtable; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; +import java.lang.Boolean; import xyz.doikki.videoplayer.player.VideoView; @@ -141,10 +142,6 @@ public class LivePlayActivity extends BaseActivity { private ObjectAnimator objectAnimator; public String epgStringAddress =""; - - - - @Override protected int getLayoutResID() { return R.layout.activity_live_play; @@ -1058,7 +1055,18 @@ private void initLiveChannelList() { } public void loadProxyLives(String url) { - OkGo.get(url).execute(new AbsCallback() { + Uri parsedUrl = Uri.parse(url); + String extUrl = url; + try { + extUrl = new String(Base64.decode(parsedUrl.getQueryParameter("ext"), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8"); + } catch (Throwable th) { + th.printStackTrace(); + } + String type = parsedUrl.getQueryParameter("type"); + boolean useProxy = extUrl.startsWith("http"); + LOG.i("url: " + url + " extUrl: " + extUrl + " proxy: " + Boolean.toString(useProxy)); + + OkGo.get(useProxy ? extUrl : url).execute(new AbsCallback() { @Override public String convertResponse(okhttp3.Response response) throws Throwable { @@ -1067,7 +1075,14 @@ public String convertResponse(okhttp3.Response response) throws Throwable { @Override public void onSuccess(Response response) { - JsonArray livesArray = new Gson().fromJson(response.body(), JsonArray.class); + JsonArray livesArray = null; + if (type.equals("txt") && useProxy) { + LinkedHashMap map = new LinkedHashMap(); + ApiConfig.get().parseLiveTxt(map, response.body()); + livesArray = ApiConfig.get().jsonifyLiveMap(map); + } else { + livesArray = new Gson().fromJson(response.body(), JsonArray.class); + } ApiConfig.get().loadLives(livesArray); List list = ApiConfig.get().getChannelGroupList(); if (list.isEmpty()) { diff --git a/app/src/main/java/com/github/tvbox/osc/util/OkGoHelper.java b/app/src/main/java/com/github/tvbox/osc/util/OkGoHelper.java index 76bfed5553..ffb471c697 100644 --- a/app/src/main/java/com/github/tvbox/osc/util/OkGoHelper.java +++ b/app/src/main/java/com/github/tvbox/osc/util/OkGoHelper.java @@ -1,7 +1,7 @@ package com.github.tvbox.osc.util; import com.github.tvbox.osc.base.App; -import com.github.tvbox.osc.util.SSL.SSLSocketFactoryCompat; +import com.github.tvbox.osc.util.TLSSocketFactory; import com.lzy.okgo.OkGo; import com.lzy.okgo.https.HttpsUtils; import com.lzy.okgo.interceptor.HttpLoggingInterceptor; @@ -11,23 +11,36 @@ import com.squareup.picasso.Picasso; import java.io.File; +import java.security.Security; +import java.security.Provider; import java.security.cert.CertificateException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import javax.net.ssl.SSLContext; + +import org.conscrypt.Conscrypt; import okhttp3.Cache; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.dnsoverhttps.DnsOverHttps; import okhttp3.internal.Version; +import okhttp3.ConnectionSpec; import xyz.doikki.videoplayer.exo.ExoMediaSourceHelper; public class OkGoHelper { public static final long DEFAULT_MILLISECONDS = 10000; //默认的超时时间 + public static final Provider conscrypt = Conscrypt.newProvider(); + static { + Security.insertProviderAt(conscrypt, 1); + } static void initExoOkHttpClient() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); @@ -117,8 +130,8 @@ public static OkHttpClient getNoRedirectClient() { public static void init() { initDnsOverHttps(); - - OkHttpClient.Builder builder = new OkHttpClient.Builder(); + List connectionSpecs = Arrays.asList(ConnectionSpec.RESTRICTED_TLS, ConnectionSpec.CLEARTEXT); + OkHttpClient.Builder builder = new OkHttpClient.Builder().connectionSpecs(connectionSpecs); HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo"); if (Hawk.get(HawkConfig.DEBUG_OPEN, false)) { @@ -183,7 +196,10 @@ public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } }; - final SSLSocketFactory sslSocketFactory = new SSLSocketFactoryCompat(trustAllCert); + final SSLContext sslContext = SSLContext.getInstance("TLS", conscrypt); + sslContext.init(null, new TrustManager[] { trustAllCert }, null); + + final SSLSocketFactory sslSocketFactory = new TLSSocketFactory(sslContext.getSocketFactory()); builder.sslSocketFactory(sslSocketFactory, trustAllCert); builder.hostnameVerifier(HttpsUtils.UnSafeHostnameVerifier); } catch (Exception e) { diff --git a/app/src/main/java/com/github/tvbox/osc/util/TLSSocketFactory.java b/app/src/main/java/com/github/tvbox/osc/util/TLSSocketFactory.java index 1ffe41c882..ed9fd7731d 100644 --- a/app/src/main/java/com/github/tvbox/osc/util/TLSSocketFactory.java +++ b/app/src/main/java/com/github/tvbox/osc/util/TLSSocketFactory.java @@ -9,7 +9,7 @@ import javax.net.ssl.SSLSocketFactory; public class TLSSocketFactory extends SSLSocketFactory { - private static final String[] TLS_SUPPORT_VERSION = {"TLSv1.1", "TLSv1.2"}; + private static final String[] TLS_SUPPORT_VERSION = {"TLSv1.2", "TLSv1.3"}; final SSLSocketFactory delegate; diff --git a/build.gradle b/build.gradle index 8e31c8589a..c0233e8813 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,13 @@ allprojects { // maven { url 'http://9xi4o.tk/maven2' } maven { url 'http://home.jundie.top:81/xwalk/maven2' } } + configurations.all { + resolutionStrategy { + force 'com.squareup.okhttp3:okhttp:3.12.13' + force 'com.squareup.okio:okio:3.2.0' + // force 'org.conscrypt:conscrypt-android:2.5.2' + } + } } task clean(type: Delete) {