优化超级解析(同时进行嗅探和并发json);

main
jun 12 months ago
parent 84f2e95a0b
commit e9ce49747e
  1. 115
      app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java
  2. 126
      app/src/main/java/com/github/tvbox/osc/ui/fragment/PlayFragment.java
  3. 32
      app/src/main/java/com/github/tvbox/osc/util/parser/JsonParallel.java
  4. 82
      app/src/main/java/com/github/tvbox/osc/util/parser/SuperParse.java
  5. 2
      gradle.properties

@ -1257,56 +1257,97 @@ public class PlayActivity extends BaseActivity {
parseThreadPool.execute(new Runnable() {
@Override
public void run() {
JSONObject rs = isSuper? SuperParse.parse(jxs,parseFlag,webUrl):ApiConfig.get().jsonExtMix(parseFlag + "111", pb.getUrl(), finalExtendName, jxs, webUrl);
if (rs == null || !rs.has("url") || rs.optString("url").isEmpty()) {
setTip("解析错误", false, true);
} else {
if (rs.has("parse") && rs.optInt("parse", 0) == 1) {
if (rs.has("ua")) {
webUserAgent = rs.optString("ua").trim();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
String mixParseUrl = DefaultConfig.checkReplaceProxy(rs.optString("url", ""));
stopParse();
setTip("正在嗅探播放地址", true, false);
mHandler.removeMessages(100);
mHandler.sendEmptyMessageDelayed(100, 20 * 1000);
loadWebView(mixParseUrl);
}
});
if(isSuper){
JSONObject rs = SuperParse.parse(jxs,parseFlag+"123",webUrl);
if (!rs.has("url") || rs.optString("url").isEmpty()) {
setTip("解析错误", false, true);
} else {
HashMap<String, String> headers = null;
if (rs.has("header")) {
try {
JSONObject hds = rs.getJSONObject("header");
Iterator<String> keys = hds.keys();
while (keys.hasNext()) {
String key = keys.next();
if (headers == null) {
headers = new HashMap<>();
}
headers.put(key, hds.getString(key));
}
} catch (Throwable th) {
if (rs.has("parse") && rs.optInt("parse", 0) == 1) {
if (rs.has("ua")) {
webUserAgent = rs.optString("ua").trim();
}
setTip("超级解析中", true, false);
runOnUiThread(new Runnable() {
@Override
public void run() {
String mixParseUrl = DefaultConfig.checkReplaceProxy(rs.optString("url", ""));
stopParse();
mHandler.removeMessages(100);
mHandler.sendEmptyMessageDelayed(100, 20 * 1000);
loadWebView(mixParseUrl);
}
});
parseThreadPool.execute(new Runnable() {
@Override
public void run() {
JSONObject res = SuperParse.doJsonJx(webUrl);
rsJsonJx(res, true);
}
});
} else {
rsJsonJx(rs,false);
}
if (rs.has("jxFrom")) {
}
}else {
JSONObject rs = ApiConfig.get().jsonExtMix(parseFlag + "111", pb.getUrl(), finalExtendName, jxs, webUrl);
if (rs == null || !rs.has("url") || rs.optString("url").isEmpty()) {
setTip("解析错误", false, true);
} else {
if (rs.has("parse") && rs.optInt("parse", 0) == 1) {
if (rs.has("ua")) {
webUserAgent = rs.optString("ua").trim();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "解析来自:" + rs.optString("jxFrom"), Toast.LENGTH_SHORT).show();
String mixParseUrl = DefaultConfig.checkReplaceProxy(rs.optString("url", ""));
stopParse();
setTip("正在嗅探播放地址", true, false);
mHandler.removeMessages(100);
mHandler.sendEmptyMessageDelayed(100, 20 * 1000);
loadWebView(mixParseUrl);
}
});
} else {
rsJsonJx(rs,false);
}
playUrl(rs.optString("url", ""), headers);
}
}
}
});
}
private void rsJsonJx(JSONObject rs,boolean isSuper)
{
if(isSuper){
if(rs==null || !rs.has("url"))return;
stopLoadWebView(false);
}
HashMap<String, String> headers = null;
if (rs.has("header")) {
try {
JSONObject hds = rs.getJSONObject("header");
Iterator<String> keys = hds.keys();
while (keys.hasNext()) {
String key = keys.next();
if (headers == null) {
headers = new HashMap<>();
}
headers.put(key, hds.getString(key));
}
} catch (Throwable th) {
}
}
if (rs.has("jxFrom")) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "解析来自:" + rs.optString("jxFrom"), Toast.LENGTH_SHORT).show();
}
});
}
playUrl(rs.optString("url", ""), headers);
}
// webview
private XWalkView mXwalkWebView;
private XWalkWebClient mX5WebClient;
@ -1625,6 +1666,7 @@ public class PlayActivity extends BaseActivity {
String cookie = CookieManager.getInstance().getCookie(url);
if(!TextUtils.isEmpty(cookie))headers.put("Cookie", " " + cookie);//携带cookie
playUrl(url, headers);
SuperParse.stopJsonJx();
stopLoadWebView(false);
}
}
@ -1808,6 +1850,7 @@ public class PlayActivity extends BaseActivity {
String cookie = CookieManager.getInstance().getCookie(url);
if(!TextUtils.isEmpty(cookie))webHeaders.put("Cookie", " " + cookie);//携带cookie
playUrl(url, webHeaders);
SuperParse.stopJsonJx();
stopLoadWebView(false);
}
}

@ -1290,6 +1290,7 @@ public class PlayFragment extends BaseLazyFragment {
setTip("正在解析播放地址", true, false);
parseThreadPool = Executors.newSingleThreadExecutor();
LinkedHashMap<String, HashMap<String, String>> jxs = new LinkedHashMap<>();
LinkedHashMap<String, String> json_jxs = new LinkedHashMap<>();
String extendName = "";
for (ParseBean p : ApiConfig.get().getParseBeanList()) {
HashMap<String, String> data = new HashMap<String, String>();
@ -1300,65 +1301,112 @@ public class PlayFragment extends BaseLazyFragment {
data.put("type", p.getType() + "");
data.put("ext", p.getExt());
jxs.put(p.getName(), data);
if (p.getType() == 1) {
json_jxs.put(p.getName(), p.mixUrl());
}
}
String finalExtendName = extendName;
parseThreadPool.execute(new Runnable() {
@Override
public void run() {
JSONObject rs = isSuper? SuperParse.parse(jxs, parseFlag, webUrl):ApiConfig.get().jsonExtMix(parseFlag + "111", pb.getUrl(), finalExtendName, jxs, webUrl);
if (rs == null || !rs.has("url") || rs.optString("url").isEmpty()) {
// errorWithRetry("解析错误", false);
setTip("解析错误", false, true);
} else {
if (rs.has("parse") && rs.optInt("parse", 0) == 1) {
if (rs.has("ua")) {
webUserAgent = rs.optString("ua").trim();
}
if(!isAdded())return;
requireActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
String mixParseUrl = DefaultConfig.checkReplaceProxy(rs.optString("url", ""));
stopParse();
setTip("正在嗅探播放地址", true, false);
mHandler.removeMessages(100);
mHandler.sendEmptyMessageDelayed(100, 20 * 1000);
loadWebView(mixParseUrl);
}
});
if(isSuper){
//并发执行 嗅探和json
JSONObject rs = SuperParse.parse(jxs, parseFlag+"123", webUrl);
if (!rs.has("url") || rs.optString("url").isEmpty()) {
setTip("解析错误", false, true);
} else {
HashMap<String, String> headers = null;
if (rs.has("header")) {
try {
JSONObject hds = rs.getJSONObject("header");
Iterator<String> keys = hds.keys();
while (keys.hasNext()) {
String key = keys.next();
if (headers == null) {
headers = new HashMap<>();
}
headers.put(key, hds.getString(key));
}
} catch (Throwable th) {
th.printStackTrace();
if (rs.has("parse") && rs.optInt("parse", 0) == 1) {
if (rs.has("ua")) {
webUserAgent = rs.optString("ua").trim();
}
setTip("超级解析中", true, false);
if(!isAdded())return;
requireActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
String mixParseUrl = DefaultConfig.checkReplaceProxy(rs.optString("url", ""));
stopParse();
mHandler.removeMessages(100);
mHandler.sendEmptyMessageDelayed(100, 20 * 1000);
loadWebView(mixParseUrl);
}
});
parseThreadPool.execute(new Runnable() {
@Override
public void run() {
JSONObject res = SuperParse.doJsonJx(webUrl);
rsJsonJX(res, true);
}
});
} else {
rsJsonJX(rs,false);
}
if (rs.has("jxFrom")) {
}
}else {
JSONObject rs = ApiConfig.get().jsonExtMix(parseFlag + "111", pb.getUrl(), finalExtendName, jxs, webUrl);
if (rs == null || !rs.has("url") || rs.optString("url").isEmpty()) {
// errorWithRetry("解析错误", false);
setTip("解析错误", false, true);
} else {
if (rs.has("parse") && rs.optInt("parse", 0) == 1) {
if (rs.has("ua")) {
webUserAgent = rs.optString("ua").trim();
}
if(!isAdded())return;
requireActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "解析来自:" + rs.optString("jxFrom"), Toast.LENGTH_SHORT).show();
String mixParseUrl = DefaultConfig.checkReplaceProxy(rs.optString("url", ""));
stopParse();
setTip("正在嗅探播放地址", true, false);
mHandler.removeMessages(100);
mHandler.sendEmptyMessageDelayed(100, 20 * 1000);
loadWebView(mixParseUrl);
}
});
} else {
rsJsonJX(rs,false);
}
playUrl(rs.optString("url", ""), headers);
}
}
}
});
}
private void rsJsonJX(JSONObject rs,boolean isSuper){
if(isSuper){
if(rs==null || !rs.has("url"))return;
stopLoadWebView(false);
}
HashMap<String, String> headers = null;
if (rs.has("header")) {
try {
JSONObject hds = rs.getJSONObject("header");
Iterator<String> keys = hds.keys();
while (keys.hasNext()) {
String key = keys.next();
if (headers == null) {
headers = new HashMap<>();
}
headers.put(key, hds.getString(key));
}
} catch (Throwable th) {
th.printStackTrace();
}
}
if (rs.has("jxFrom")) {
if(!isAdded())return;
requireActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, "解析来自:" + rs.optString("jxFrom"), Toast.LENGTH_SHORT).show();
}
});
}
playUrl(rs.optString("url", ""), headers);
}
public MyVideoView getPlayer() {
return mVideoView;
}
@ -1695,6 +1743,7 @@ public class PlayFragment extends BaseLazyFragment {
if(!TextUtils.isEmpty(cookie))headers.put("Cookie", " " + cookie);//携带cookie
playUrl(url, headers);
stopLoadWebView(false);
SuperParse.stopJsonJx();
}
}
}
@ -1881,6 +1930,7 @@ public class PlayFragment extends BaseLazyFragment {
if(!TextUtils.isEmpty(cookie))webHeaders.put("Cookie", " " + cookie);//携带cookie
playUrl(url, webHeaders);
stopLoadWebView(false);
SuperParse.stopJsonJx();
}
}
}

@ -25,14 +25,17 @@ import okhttp3.Response;
*/
public class JsonParallel {
private static OkHttpClient client;
private static ExecutorService executorService;
private static final List<Future<JSONObject>> futures = new ArrayList<>();
public static JSONObject parse(LinkedHashMap<String, String> jx, String url) {
try {
if (jx != null && jx.size() > 0) {
OkHttpClient client = new OkHttpClient();
// 使用线程池并发处理各个任务
ExecutorService executorService = Executors.newFixedThreadPool(6);
client = new OkHttpClient();
// 使用线程池并发处理任务
executorService = Executors.newFixedThreadPool(5);
CompletionService<JSONObject> completionService = new ExecutorCompletionService<>(executorService);
List<Future<JSONObject>> futures = new ArrayList<>();
futures.clear();
// 遍历所有的解析配置
for (final String jxName : jx.keySet()) {
@ -45,7 +48,6 @@ public class JsonParallel {
HashMap<String, String> reqHeaders = JsonParallel.getReqHeader(parseUrl);
String realUrl = reqHeaders.get("url");
reqHeaders.remove("url");
SpiderDebug.log(realUrl + url);
Headers headers = Headers.of(reqHeaders);
Request request = new Request.Builder()
.url(realUrl + url)
@ -59,10 +61,9 @@ public class JsonParallel {
JSONObject taskResult = Utils.jsonParse(url, json);
taskResult.put("jxFrom", jxName);
SpiderDebug.log(taskResult.toString());
return taskResult;
} catch (Throwable th) {
SpiderDebug.log(th);
// 输出日志
return null;
}
}
@ -100,6 +101,23 @@ public class JsonParallel {
return new JSONObject();
}
public static void cancelTasks() {
if (client != null) {
client.dispatcher().cancelAll();
}
if (futures != null) {
for (Future<JSONObject> future : futures) {
try {
future.cancel(true);
} catch (Throwable t) {
}
}
futures.clear();
}
if (executorService != null) {
executorService.shutdownNow();
}
}
public static HashMap<String, String> getReqHeader(String url) {
HashMap<String, String> reqHeaders = new HashMap<>();
reqHeaders.put("url", url);

@ -3,6 +3,8 @@ package com.github.tvbox.osc.util.parser;
import android.util.Base64;
import com.github.catvod.crawler.SpiderDebug;
import com.github.tvbox.osc.util.LOG;
import org.json.JSONArray;
import org.json.JSONObject;
@ -12,16 +14,12 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class SuperParse {
public static HashMap<String, ArrayList<String>> flagWebJx = new HashMap<>();
static HashMap<String, ArrayList<String>> configs = null;
static LinkedHashMap<String, String> jsonJx = null;
static ArrayList<String> webJx = null;
public static JSONObject parse(LinkedHashMap<String, HashMap<String, String>> jx, String flag, String url) {
try {
@ -62,10 +60,9 @@ public class SuperParse {
}
// 根据配置构建 jsonJx 和 webJx
LinkedHashMap<String, String> jsonJx = new LinkedHashMap<>();
ArrayList<String> webJx = new ArrayList<>();
jsonJx = new LinkedHashMap<>();
webJx = new ArrayList<>();
List<String> targetKeys = configs.get(flag);
if (targetKeys != null && !targetKeys.isEmpty()) {
for (String key : targetKeys) {
HashMap<String, String> parseBean = jx.get(key);
@ -117,61 +114,34 @@ public class SuperParse {
if (!webJx.isEmpty()) {
flagWebJx.put(flag, webJx);
}
//同时进行json和web
ExecutorService exec = Executors.newFixedThreadPool(2);
CompletionService<JSONObject> cs = new ExecutorCompletionService<>(exec);
List<Future<JSONObject>> tasks = new ArrayList<>();
tasks.add(cs.submit(new Callable<JSONObject>() {
@Override
public JSONObject call() {
return JsonParallel.parse(jsonJx, url);
}
}));
if (!webJx.isEmpty()) {
tasks.add(cs.submit(new Callable<JSONObject>() {
@Override
public JSONObject call() {
JSONObject webResult = new JSONObject();
String encodedUrl = Base64.encodeToString(url.getBytes(),
Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP);
try {
webResult.put("url", "proxy://go=SuperParse&flag=" + flag + "&url=" + encodedUrl);
webResult.put("parse", 1);
webResult.put("ua", Utils.UaWinChrome);
} catch (Exception e) {
SpiderDebug.log(e);
}
return webResult;
}
}));
}
JSONObject result = null;
for (int i = 0, n = tasks.size(); i < n; i++) {
try {
Future<JSONObject> future = cs.take();
JSONObject res = future.get();
if (res != null && res.has("url")) {
result = res;
break;
}
} catch (Exception e) {
SpiderDebug.log(e);
}
}
for (Future<JSONObject> future : tasks) {
future.cancel(true);
}
exec.shutdownNow();
if (result != null) {
return result;
JSONObject webResult = new JSONObject();
webResult.put("url", "proxy://go=SuperParse&flag=" + flag + "&url=" + Base64.encodeToString(url.getBytes(), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP));
webResult.put("parse", 1);
webResult.put("ua", Utils.UaWinChrome);
return webResult;
}
} catch (Exception e) {
SpiderDebug.log(e);
LOG.i("echo-result"+e.getMessage());
}
return new JSONObject();
}
public static JSONObject doJsonJx(LinkedHashMap<String, String>json_jxs,String url){
LOG.i("echo-jsonJx1"+json_jxs.toString());
return JsonParallel.parse(json_jxs, url);
}
public static JSONObject doJsonJx(String url){
LOG.i("echo-jsonJx2"+jsonJx.toString());
return JsonParallel.parse(jsonJx, url);
}
public static void stopJsonJx(){
JsonParallel.cancelTasks();
}
private static String mixUrl(String url, String ext) {
if (ext.trim().length() > 0) {
int idx = url.indexOf("?");

@ -18,4 +18,4 @@ android.useAndroidX=true
android.enableJetifier=true
IsDebug=true
#build on off
#org.gradle.jvmargs=-Xmx2048m --add-opens java.base/java.io=ALL-UNNAMED
org.gradle.jvmargs=-Xmx2048m --add-opens java.base/java.io=ALL-UNNAMED
Loading…
Cancel
Save