Redesign parse and support parse type = 1

pull/102/head
FongMi 4 years ago
parent 1562a35aec
commit e91bc3cd08
  1. 10
      app/src/main/java/com/fongmi/android/tv/bean/Result.java
  2. 108
      app/src/main/java/com/fongmi/android/tv/player/ParseTask.java
  3. 82
      app/src/main/java/com/fongmi/android/tv/player/Players.java
  4. 21
      app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java
  5. 9
      app/src/main/java/com/fongmi/android/tv/utils/Json.java

@ -4,6 +4,7 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import com.fongmi.android.tv.utils.Json;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
@ -11,6 +12,7 @@ import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
@ -22,8 +24,10 @@ import org.simpleframework.xml.core.Persister;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Root(name = "rss", strict = false)
public class Result {
@ -139,6 +143,12 @@ public class Result {
this.url = url;
}
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
if (getHeader().isEmpty()) return headers;
return Json.toMap(JsonParser.parseString(getHeader()));
}
@NonNull
@Override
public String toString() {

@ -0,0 +1,108 @@
package com.fongmi.android.tv.player;
import android.os.Handler;
import android.os.Looper;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Parse;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.net.OKHttp;
import com.fongmi.android.tv.utils.Json;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import okhttp3.Headers;
import okhttp3.Response;
public class ParseTask {
private final Handler handler;
private ExecutorService executor;
private Callback callback;
private Parse parse;
public static ParseTask create(Callback callback) {
return new ParseTask(callback);
}
public ParseTask(Callback callback) {
this.executor = Executors.newSingleThreadExecutor();
this.handler = new Handler(Looper.getMainLooper());
this.callback = callback;
}
public void run(Result result) {
boolean useParse = (result.getPlayUrl().isEmpty() && ApiConfig.get().getFlags().contains(result.getFlag())) || result.getJx().equals("1");
setParse(result.getPlayUrl() + result.getUrl(), useParse);
executor.submit(this::doInBackground);
}
private void setParse(String url, boolean useParse) {
if (useParse) parse = ApiConfig.get().getParse();
if (url.startsWith("json:")) parse = Parse.get(1, url.substring(5));
if (url.startsWith("parse:")) parse = ApiConfig.get().getParse(url.substring(6));
if (parse == null) parse = Parse.get(0, url);
}
private void doInBackground() {
switch (parse.getType()) {
case 0: //嗅探
handler.post(() -> Players.get().web().start(parse.getUrl(), callback));
break;
case 1: //Json
jsonParse();
break;
case 2: //Json 擴展
break;
case 3: //聚合
break;
}
}
private void jsonParse() {
try {
Headers headers = new Headers.Builder().build();
if (parse.hasHeader()) headers = Headers.of(Json.toMap(parse.getHeader()));
Response response = OKHttp.newCall(parse.getUrl(), headers).execute();
JsonObject object = JsonParser.parseString(response.body().string()).getAsJsonObject();
HashMap<String, String> header = new HashMap<>();
for (String key : object.keySet()) if (key.equalsIgnoreCase("user-agent") || key.equalsIgnoreCase("referer")) header.put(key, object.get(key).getAsString());
onParseSuccess(header, object.get("url").getAsString());
} catch (Exception e) {
e.printStackTrace();
onParseError();
}
}
private void onParseSuccess(Map<String, String> headers, String url) {
handler.post(() -> {
if (callback != null) callback.onParseSuccess(headers, url);
});
}
private void onParseError() {
handler.post(() -> {
if (callback != null) callback.onParseError();
});
}
public void cancel() {
if (executor != null) executor.shutdownNow();
executor = null;
callback = null;
}
public interface Callback {
void onParseSuccess(Map<String, String> headers, String url);
void onParseError();
}
}

@ -4,32 +4,19 @@ import androidx.annotation.NonNull;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Parse;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.event.PlayerEvent;
import com.fongmi.android.tv.net.Callback;
import com.fongmi.android.tv.net.OKHttp;
import com.fongmi.android.tv.ui.custom.CustomWebView;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.util.Util;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Headers;
import okhttp3.Response;
public class Players implements Player.Listener {
public class Players implements Player.Listener, ParseTask.Callback {
private CustomWebView webView;
private StringBuilder builder;
@ -57,6 +44,10 @@ public class Players implements Player.Listener {
return exoPlayer;
}
public CustomWebView web() {
return webView;
}
public String getKey() {
return key;
}
@ -116,58 +107,9 @@ public class Players implements Player.Listener {
if (result.getUrl().isEmpty()) {
PlayerEvent.error(R.string.error_play_load);
} else if (result.getParse().equals("1") || result.getJx().equals("1")) {
startParse(result);
ParseTask.create(this).run(result);
} else {
setMediaSource(getHeaders(result), result.getPlayUrl() + result.getUrl());
}
}
private HashMap<String, String> getHeaders(Result result) {
HashMap<String, String> headers = new HashMap<>();
if (result.getHeader().isEmpty()) return headers;
return getHeaders(JsonParser.parseString(result.getHeader()));
}
private HashMap<String, String> getHeaders(JsonElement element) {
HashMap<String, String> headers = new HashMap<>();
if (!element.isJsonObject()) return headers;
JsonObject object = element.getAsJsonObject();
for (String key : object.keySet()) headers.put(key, object.get(key).getAsString());
return headers;
}
private Parse getParse(String playUrl, boolean useParse) {
if (useParse) return ApiConfig.get().getParse();
if (playUrl.startsWith("json:")) return Parse.get(1, playUrl.substring(5));
if (playUrl.startsWith("parse:")) {
Parse parse = ApiConfig.get().getParse(playUrl.substring(6));
if (parse != null) return parse;
}
return Parse.get(0, playUrl);
}
private void startParse(Result result) {
boolean useParse = (result.getPlayUrl().isEmpty() && ApiConfig.get().getFlags().contains(result.getFlag())) || result.getJx().equals("1");
Parse parse = getParse(result.getPlayUrl(), useParse);
if (parse.getType() == 0) {
webView.start(parse.getUrl() + result.getUrl());
} else if (parse.getType() == 1) {
Headers headers = new Headers.Builder().build();
if (parse.hasHeader()) headers = Headers.of(getHeaders(parse.getHeader()));
OKHttp.newCall(parse.getUrl() + result.getUrl(), headers).enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
}
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
}
});
} else if (parse.getType() == 2) {
} else if (parse.getType() == 3) {
setMediaSource(result.getHeaders(), result.getPlayUrl() + result.getUrl());
}
}
@ -213,6 +155,16 @@ public class Players implements Player.Listener {
}
}
@Override
public void onParseSuccess(Map<String, String> headers, String url) {
setMediaSource(headers, url);
}
@Override
public void onParseError() {
PlayerEvent.error(R.string.error_play_parse);
}
@Override
public void onPlayerError(@NonNull PlaybackException error) {
PlayerEvent.error(R.string.error_play_format);

@ -15,10 +15,8 @@ import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.event.PlayerEvent;
import com.fongmi.android.tv.player.Players;
import com.fongmi.android.tv.player.ParseTask;
import com.fongmi.android.tv.utils.Utils;
import java.io.ByteArrayInputStream;
@ -29,6 +27,7 @@ import java.util.Map;
public class CustomWebView extends WebView {
private ParseTask.Callback callback;
private WebResourceResponse empty;
private List<String> keys;
private Handler handler;
@ -58,7 +57,8 @@ public class CustomWebView extends WebView {
setWebViewClient(webViewClient());
}
public void start(String url) {
public void start(String url, ParseTask.Callback callback) {
this.callback = callback;
stopLoading();
loadUrl(url);
retry = 0;
@ -75,7 +75,7 @@ public class CustomWebView extends WebView {
handler.removeCallbacks(mTimer);
handler.postDelayed(mTimer, 5000);
Map<String, String> headers = request.getRequestHeaders();
if (Utils.isVideoFormat(url) || headers.containsKey("Range")) post(get(headers), url);
if (Utils.isVideoFormat(url) || headers.containsKey("Range")) post(headers, url);
return super.shouldInterceptRequest(view, request);
}
@ -100,23 +100,20 @@ public class CustomWebView extends WebView {
}
};
private Map<String, String> get(Map<String, String> headers) {
private void post(Map<String, String> headers, String url) {
Map<String, String> news = new HashMap<>();
for (String key : headers.keySet()) if (keys.contains(key.toLowerCase())) news.put(key, headers.get(key));
return news;
}
private void post(Map<String, String> headers, String url) {
handler.removeCallbacks(mTimer);
handler.post(() -> {
callback.onParseSuccess(news, url);
stop(false);
Players.get().setMediaSource(headers, url);
});
}
public void stop(boolean error) {
stopLoading();
loadUrl("about:blank");
if (error) PlayerEvent.error(R.string.error_play_parse);
handler.removeCallbacks(mTimer);
if (error) handler.post(() -> callback.onParseError());
}
}

@ -4,6 +4,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Json {
@ -20,4 +21,12 @@ public class Json {
else for (JsonElement opt : obj.getAsJsonArray(key)) result.add(opt.getAsString());
return result;
}
public static HashMap<String, String> toMap(JsonElement element) {
HashMap<String, String> map = new HashMap<>();
if (!element.isJsonObject()) return map;
JsonObject object = element.getAsJsonObject();
for (String key : object.keySet()) map.put(key, object.get(key).getAsString());
return map;
}
}

Loading…
Cancel
Save