补齐Json聚合和Json扩展

pull/1/head
SDL 4 years ago
parent 1966d2be33
commit 049f1a987c
  1. 30
      app/src/main/java/com/github/catvod/crawler/JarLoader.java
  2. 20
      app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java
  3. 22
      app/src/main/java/com/github/tvbox/osc/bean/ParseBean.java
  4. 18
      app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java
  5. 2
      app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java
  6. 23
      app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java
  7. 5
      app/src/main/java/com/github/tvbox/osc/ui/activity/SettingActivity.java
  8. 90
      app/src/main/java/com/github/tvbox/osc/ui/dialog/ParseDialog.java
  9. 37
      app/src/main/java/com/github/tvbox/osc/ui/fragment/ModelSettingFragment.java
  10. 18
      app/src/main/java/com/github/tvbox/osc/util/DefaultConfig.java
  11. 1
      app/src/main/java/com/github/tvbox/osc/util/HawkConfig.java
  12. 4
      app/src/main/java/com/github/tvbox/osc/viewmodel/SourceViewModel.java
  13. 46
      app/src/main/res/layout/fragment_model.xml

@ -4,9 +4,13 @@ import android.content.Context;
import com.github.tvbox.osc.base.App;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -86,6 +90,32 @@ public class JarLoader {
return new SpiderNull();
}
public JSONObject jsonExt(String key, LinkedHashMap<String, String> jxs, String url) {
try {
String clsKey = "Json" + key;
String hotClass = "com.github.catvod.parser." + clsKey;
Class jsonParserCls = classLoader.loadClass(hotClass);
Method mth = jsonParserCls.getMethod("parse", LinkedHashMap.class, String.class);
return (JSONObject) mth.invoke(null, jxs, url);
} catch (Throwable th) {
th.printStackTrace();
}
return null;
}
public JSONObject jsonExtMix(String flag, String key, String name, LinkedHashMap<String, HashMap<String, String>> jxs, String url) {
try {
String clsKey = "Mix" + key;
String hotClass = "com.github.catvod.parser." + clsKey;
Class jsonParserCls = classLoader.loadClass(hotClass);
Method mth = jsonParserCls.getMethod("parse", LinkedHashMap.class, String.class, String.class, String.class);
return (JSONObject) mth.invoke(null, jxs, name, flag, url);
} catch (Throwable th) {
th.printStackTrace();
}
return null;
}
public Object[] proxyInvoke(Map params) {
try {
if (proxyFun != null) {

@ -22,6 +22,8 @@ import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.model.Response;
import com.orhanobut.hawk.Hawk;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
@ -47,6 +49,8 @@ public class ApiConfig {
private List<IJKCode> ijkCodes;
private String spider = null;
private SourceBean emptyHome = new SourceBean();
private JarLoader jarLoader = new JarLoader();
@ -120,11 +124,10 @@ public class ApiConfig {
e.printStackTrace();
callback.error("加载配置失败");
}
}
private void loadConfigServer(LoadConfigCallback callback, Activity activity) {
OkGo.<String>get("http://10.80.8.70:8890/baddychen/baddychen.json")
OkGo.<String>get(Hawk.get(HawkConfig.API_URL, ""))
.execute(new AbsCallback<String>() {
@Override
public void onSuccess(Response<String> response) {
@ -159,6 +162,7 @@ public class ApiConfig {
JsonObject infoJson = new Gson().fromJson(jsonStr, JsonObject.class);
// spider
spider = DefaultConfig.safeJsonString(infoJson, "spider", "");
spider = spider.split(";md5;")[0];
// 远端站点源
for (JsonElement opt : infoJson.get("sites").getAsJsonArray()) {
JsonObject obj = (JsonObject) opt;
@ -195,6 +199,8 @@ public class ApiConfig {
ParseBean pb = new ParseBean();
pb.setName(obj.get("name").getAsString().trim());
pb.setUrl(obj.get("url").getAsString().trim());
String ext = obj.has("ext") ? obj.get("ext").getAsJsonObject().toString() : "";
pb.setExt(ext);
pb.setType(DefaultConfig.safeJsonInt(obj, "type", 0));
parseBeanList.add(pb);
}
@ -273,6 +279,14 @@ public class ApiConfig {
return jarLoader.proxyInvoke(param);
}
public JSONObject jsonExt(String key, LinkedHashMap<String, String> jxs, String url) {
return jarLoader.jsonExt(key, jxs, url);
}
public JSONObject jsonExtMix(String flag, String key, String name, LinkedHashMap<String, HashMap<String, String>> jxs, String url) {
return jarLoader.jsonExtMix(flag, key, name, jxs, url);
}
public interface LoadConfigCallback {
void success();
@ -327,7 +341,7 @@ public class ApiConfig {
}
public SourceBean getHomeSourceBean() {
return mHomeSource;
return mHomeSource == null ? emptyHome : mHomeSource;
}
public List<LiveChannel> getChannelList() {

@ -1,5 +1,7 @@
package com.github.tvbox.osc.bean;
import android.util.Base64;
/**
* @author pj567
* @date :2021/3/8
@ -9,6 +11,7 @@ public class ParseBean {
private String name;
private String url;
private String ext;
private int type; // 0 普通嗅探 1 json 2 Json扩展 3 聚合
private boolean isDefault = false;
@ -37,7 +40,6 @@ public class ParseBean {
isDefault = b;
}
public int getType() {
return type;
}
@ -45,4 +47,22 @@ public class ParseBean {
public void setType(int type) {
this.type = type;
}
public String getExt() {
return ext;
}
public void setExt(String ext) {
this.ext = ext;
}
public String mixUrl() {
if (!ext.isEmpty()) {
int idx = url.indexOf("?");
if (idx > 0) {
return url.substring(0, idx + 1) + "cat_ext=" + Base64.encodeToString(ext.getBytes(), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP) + "&" + url.substring(idx + 1);
}
}
return url;
}
}

@ -287,7 +287,8 @@ public class HomeActivity extends BaseActivity {
public void run() {
if (dialog == null)
dialog = new AlertDialog.Builder(HomeActivity.this).setTitle("提示")
.setMessage(msg + "\n\n请重试!").setPositiveButton("确定", new DialogInterface.OnClickListener() {
.setMessage(msg + "\n\n请重试!")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
mHandler.post(new Runnable() {
@ -297,6 +298,21 @@ public class HomeActivity extends BaseActivity {
}
});
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dataInitOk = true;
jarInitOk = true;
initData();
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dataInitOk = true;
jarInitOk = true;
}
}).create();
if (!dialog.isShowing())
dialog.show();

@ -211,6 +211,8 @@ public class LivePlayActivity extends BaseActivity {
}
});
List<LiveChannel> list = ApiConfig.get().getChannelList();
if (list.isEmpty())
return;
if (list.size() > 0 && list.get(0).getUrls().startsWith("proxy://")) {
showLoading();
String url = DefaultConfig.checkReplaceProxy(list.get(0).getUrls());

@ -114,16 +114,21 @@ public class PlayActivity extends BaseActivity {
parseDialog.parse(sourceKey, object, new ParseDialog.ParseCallback() {
@Override
public void success(String playUrl, Map<String, String> headers) {
if (mVideoView != null) {
mVideoView.release();
if (headers != null) {
mVideoView.setUrl(playUrl, headers);
} else {
mVideoView.setUrl(playUrl);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mVideoView != null) {
mVideoView.release();
if (headers != null) {
mVideoView.setUrl(playUrl, headers);
} else {
mVideoView.setUrl(playUrl);
}
mVideoView.start();
}
tryDismissParse();
}
mVideoView.start();
}
tryDismissParse();
});
}
@Override

@ -43,6 +43,7 @@ public class SettingActivity extends BaseActivity {
private int sortFocused = 0;
private Handler mHandler = new Handler();
private String homeSourceKey;
private String currentApi;
private String homeSourceSort;
private boolean sourceMode;
@ -105,6 +106,7 @@ public class SettingActivity extends BaseActivity {
}
private void initData() {
currentApi = Hawk.get(HawkConfig.API_URL, "");
homeSourceKey = ApiConfig.get().getHomeSourceBean().getKey();
homeSourceSort = ApiConfig.get().getHomeSourceBean().getState().tidSort;
if (homeSourceSort == null)
@ -183,7 +185,8 @@ public class SettingActivity extends BaseActivity {
if (newHomeSourceSort == null)
newHomeSourceSort = "";
if (!homeSourceKey.equals(ApiConfig.get().getHomeSourceBean().getKey()) ||
if ((homeSourceKey != null && !homeSourceKey.equals(ApiConfig.get().getHomeSourceBean().getKey())) ||
!currentApi.equals(Hawk.get(HawkConfig.API_URL, "")) ||
!homeSourceSort.equals(newHomeSourceSort) ||
sourceMode != Hawk.get(HawkConfig.SOURCE_MODE_LOCAL, true)) {
AppManager.getInstance().finishAllActivity();

@ -58,6 +58,7 @@ import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -313,7 +314,7 @@ public class ParseDialog {
});
}
private void loadUrl(ParseBean pb, String url, ParseCallback callback) {
private void loadUrl(ParseBean pb, String flag, String url, ParseCallback callback) {
if (pb == null || pb.getType() == 0) {
if (mSysWebClient != null) {
mSysWebClient.setCallback(callback);
@ -333,6 +334,87 @@ public class ParseDialog {
}
} else if (pb.getType() == 1) { // json 解析
doJsonJx(pb.getUrl(), url, callback);
} else if (pb.getType() == 2) { // json 扩展
LinkedHashMap<String, String> jxs = new LinkedHashMap<>();
for (ParseBean p : ApiConfig.get().getParseBeanList()) {
if (p.getType() == 1) {
jxs.put(p.getName(), p.mixUrl());
}
}
new Thread(new Runnable() {
@Override
public void run() {
JSONObject rs = ApiConfig.get().jsonExt(pb.getUrl(), jxs, url);
if (rs == null || !rs.has("url")) {
callback.fail();
} 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) {
}
}
boolean parseWV = rs.optInt("parse", 0) == 1;
if (parseWV) {
String wvUrl = DefaultConfig.checkReplaceProxy(rs.optString("url", ""));
loadUrl(null, flag, wvUrl, callback);
} else {
callback.success(rs.optString("url", ""), headers);
}
}
}
}).start();
} else if (pb.getType() == 3) { // json 聚合
LinkedHashMap<String, HashMap<String, String>> jxs = new LinkedHashMap<>();
String extendName = "";
for (ParseBean p : ApiConfig.get().getParseBeanList()) {
HashMap data = new HashMap<String, String>();
data.put("url", p.getUrl());
if (p.getUrl().equals(pb.getUrl())) {
extendName = p.getName();
}
data.put("type", p.getType() + "");
data.put("ext", p.getExt());
jxs.put(p.getName(), data);
}
String finalExtendName = extendName;
new Thread(new Runnable() {
@Override
public void run() {
JSONObject rs = ApiConfig.get().jsonExtMix(flag, pb.getUrl(), finalExtendName, jxs, url);
if (rs == null || !rs.has("url")) {
callback.fail();
} 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) {
}
}
callback.success(rs.optString("url", ""), headers);
}
}
}).start();
}
mHandler.removeCallbacks(mParseTimeOut);
mHandler.postDelayed(mGridFocus, 200);
@ -356,7 +438,7 @@ public class ParseDialog {
ApiConfig.get().setDefaultParse(parseBean);
parseAdapter.notifyItemChanged(position);
loadFound = false;
loadUrl(parseBean, url, callback);
loadUrl(parseBean, flag, url, callback);
}
});
mGridView.setOnInBorderKeyEventListener(new TvRecyclerView.OnInBorderKeyEventListener() {
@ -386,11 +468,11 @@ public class ParseDialog {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
loadUrl(finalParseBean, url, callback);
loadUrl(finalParseBean, flag, url, callback);
}
}, 3000);
} else {
loadUrl(null, parseUrl + url, callback);
loadUrl(null, flag, parseUrl + url, callback);
}
}

@ -1,11 +1,16 @@
package com.github.tvbox.osc.ui.fragment;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.github.tvbox.osc.R;
import com.github.tvbox.osc.api.ApiConfig;
import com.github.tvbox.osc.base.BaseLazyFragment;
import com.github.tvbox.osc.bean.IJKCode;
import com.github.tvbox.osc.ui.activity.SettingActivity;
import com.github.tvbox.osc.ui.dialog.AboutDialog;
import com.github.tvbox.osc.ui.dialog.ChangeIJKCodeDialog;
@ -18,6 +23,8 @@ import com.github.tvbox.osc.util.PlayerHelper;
import com.github.tvbox.osc.util.XWalkUtils;
import com.orhanobut.hawk.Hawk;
import java.util.List;
/**
* @author pj567
* @date :2020/12/23
@ -32,6 +39,7 @@ public class ModelSettingFragment extends BaseLazyFragment {
private TextView tvPlay;
private TextView tvRender;
private TextView tvXWalkDown;
private TextView tvApi;
public static ModelSettingFragment newInstance() {
return new ModelSettingFragment().setArguments();
@ -56,12 +64,14 @@ public class ModelSettingFragment extends BaseLazyFragment {
tvPlay = findViewById(R.id.tvPlay);
tvRender = findViewById(R.id.tvRenderType);
tvXWalkDown = findViewById(R.id.tvXWalkDown);
tvApi = findViewById(R.id.tvApi);
tvMediaCodec.setText(Hawk.get(HawkConfig.IJK_CODEC, ""));
tvDebugOpen.setText(Hawk.get(HawkConfig.DEBUG_OPEN, false) ? "已打开" : "已关闭");
tvSourceMode.setText(Hawk.get(HawkConfig.SOURCE_MODE_LOCAL, true) ? "本地" : "云端");
tvTestChannel.setText(Hawk.get(HawkConfig.TEST_CHANNEL, false) ? "已打开" : "已关闭");
tvParseWebView.setText(Hawk.get(HawkConfig.PARSE_WEBVIEW, true) ? "系统自带" : "XWalkView");
tvXWalkDown.setText(XWalkUtils.xWalkLibExist(mContext) ? "已下载" : "未下载");
tvApi.setText(Hawk.get(HawkConfig.API_URL, ""));
findViewById(R.id.llXWalkCore).setVisibility(Hawk.get(HawkConfig.PARSE_WEBVIEW, true) ? View.GONE : View.VISIBLE);
changePlay();
changeRender();
@ -132,9 +142,36 @@ public class ModelSettingFragment extends BaseLazyFragment {
dialog.show();
}
});
findViewById(R.id.llApi).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle("请输入配置地址");
final EditText edit = new EditText(mActivity);
edit.setText(tvApi.getText());
builder.setView(edit);
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String url = edit.getText().toString().trim();
Hawk.put(HawkConfig.API_URL, url);
tvApi.setText(url);
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
}
});
findViewById(R.id.llMediaCodec).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List<IJKCode> ijkCodes = ApiConfig.get().getIjkCodes();
if (ijkCodes == null || ijkCodes.size() == 0)
return;
FastClickCheckUtil.check(v);
ChangeIJKCodeDialog dialog = new ChangeIJKCodeDialog().build(mActivity, new ChangeIJKCodeDialog.Callback() {
@Override

@ -28,14 +28,16 @@ public class DefaultConfig {
public static List<MovieSort.SortData> adjustSort(String sourceKey, List<MovieSort.SortData> list, boolean withMy) {
List<MovieSort.SortData> data = new ArrayList<>();
SourceBean sb = ApiConfig.get().getSource(sourceKey);
HashMap<String, Integer> tidSort = sb.getTidSort();
for (MovieSort.SortData sortData : list) {
// 默认排序 1000
sortData.sort = 1000;
if (tidSort != null && tidSort.containsKey(sortData.id))
sortData.sort = tidSort.get(sortData.id);
data.add(sortData);
if (sourceKey != null) {
SourceBean sb = ApiConfig.get().getSource(sourceKey);
HashMap<String, Integer> tidSort = sb.getTidSort();
for (MovieSort.SortData sortData : list) {
// 默认排序 1000
sortData.sort = 1000;
if (tidSort != null && tidSort.containsKey(sortData.id))
sortData.sort = tidSort.get(sortData.id);
data.add(sortData);
}
}
if (withMy)
data.add(0, new MovieSort.SortData("my0", "我的"));

@ -6,6 +6,7 @@ package com.github.tvbox.osc.util;
* @description:
*/
public class HawkConfig {
public static final String API_URL = "api_url";
public static final String DEFAULT_PARSE = "parse_default";
public static final String DEBUG_OPEN = "debug_open";
public static final String PARSE_WEBVIEW = "parse_webview"; // true 系统 false xwalk

@ -55,6 +55,10 @@ public class SourceViewModel extends ViewModel {
public static final ExecutorService spThreadPool = Executors.newFixedThreadPool(3);
public void getSort(String sourceKey) {
if (sourceKey == null) {
sortResult.postValue(null);
return;
}
SourceBean sourceBean = ApiConfig.get().getSource(sourceKey);
int type = sourceBean.getType();
if (type == 3) {

@ -159,6 +159,52 @@
android:textSize="30pt" />
</LinearLayout>
<LinearLayout
android:id="@+id/llApi"
android:layout_width="match_parent"
android:layout_height="50pt"
android:layout_marginLeft="30pt"
android:layout_marginTop="20pt"
android:layout_marginRight="30pt"
android:background="@drawable/setting_model_focus"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="20pt"
android:paddingRight="20pt">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="配置地址"
android:textColor="@android:color/white"
android:textSize="24pt" />
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/tvApi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="middle"
android:textColor="@android:color/white"
android:textSize="24pt"
android:singleLine="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10pt"
android:paddingBottom="5pt"
android:text=">"
android:textColor="@android:color/white"
android:textSize="30pt" />
</LinearLayout>
<LinearLayout
android:id="@+id/llPlay"
android:layout_width="match_parent"

Loading…
Cancel
Save