diff --git a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java index 790a58446..5f9f19733 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java +++ b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java @@ -33,7 +33,7 @@ public class Decoder { private static String verify(String url, String data) throws Exception { if (data.isEmpty()) throw new Exception(); - if (Json.valid(data)) return fix(url, data); + if (Json.isObj(data)) return fix(url, data); if (data.contains("**")) data = base64(data); if (data.startsWith("2423")) data = cbc(data); return fix(url, data); diff --git a/app/src/main/java/com/fongmi/android/tv/api/LiveParser.java b/app/src/main/java/com/fongmi/android/tv/api/LiveParser.java index 2f532d7c0..1fea0a9d0 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/LiveParser.java +++ b/app/src/main/java/com/fongmi/android/tv/api/LiveParser.java @@ -8,16 +8,12 @@ import com.fongmi.android.tv.bean.ClearKey; import com.fongmi.android.tv.bean.Drm; import com.fongmi.android.tv.bean.Group; import com.fongmi.android.tv.bean.Live; -import com.fongmi.android.tv.bean.XCategory; -import com.fongmi.android.tv.bean.XInfo; -import com.fongmi.android.tv.bean.XStream; import com.fongmi.android.tv.utils.UrlUtil; import com.github.catvod.net.OkHttp; import com.github.catvod.utils.Json; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -50,16 +46,20 @@ public class LiveParser { public static void start(Live live) throws Exception { if (!live.getGroups().isEmpty()) return; - if (live.getType() == 0) text(live, getText(live)); - if (live.getType() == 1) json(live, getText(live)); - if (live.getType() == 3) spider(live); + String text = getText(live); + if (Json.isArray(text)) json(live, text); + else text(live, text); + } + + private static String getText(Live live) throws Exception { + if (live.getType() == 3) return live.spider().liveContent(live.getUrl()); + return OkHttp.string(UrlUtil.convert(live.getUrl()), live.getHeaders()); } public static void text(Live live, String text) { int number = 0; if (!live.getGroups().isEmpty()) return; if (M3U.matcher(text).find()) m3u(live, text); else txt(live, text); - if (live.isXtream()) xtream(live); for (Group group : live.getGroups()) { for (Channel channel : group.getChannel()) { if (channel.getNumber().isEmpty()) channel.setNumber(++number); @@ -69,20 +69,16 @@ public class LiveParser { } private static void json(Live live, String text) { + int number = 0; live.getGroups().addAll(Group.arrayFrom(text)); for (Group group : live.getGroups()) { for (Channel channel : group.getChannel()) { + if (channel.getNumber().isEmpty()) channel.setNumber(++number); channel.live(live); } } } - private static void spider(Live live) throws Exception { - String text = live.spider().liveContent(live.getUrl()); - if (Json.valid(text)) json(live, text); - else text(live, text); - } - private static void m3u(Live live, String text) { Setting setting = Setting.create(); Catchup catchup = Catchup.create(); @@ -119,27 +115,6 @@ public class LiveParser { } } - private static void xtream(Live live) { - XInfo info = XtreamParser.getInfo(live); - if (live.getEpg().isEmpty()) live.setEpg(XtreamParser.getEpgUrl(live)); - if (live.getTimeZone().isEmpty()) live.setTimeZone(info.getServerInfo().getTimezone()); - if (!live.getGroups().isEmpty()) return; - List categoryList = XtreamParser.getCategoryList(live); - List streamList = XtreamParser.getStreamList(live); - Map categoryMap = new HashMap<>(); - for (XCategory category : categoryList) { - categoryMap.put(category.getCategoryId(), category.getCategoryName()); - } - for (XStream stream : streamList) { - if (!categoryMap.containsKey(stream.getCategoryId())) continue; - Group group = live.find(Group.create(categoryMap.get(stream.getCategoryId()), live.isPass())); - Channel channel = group.find(Channel.create(stream.getName())); - if (!stream.getStreamIcon().isEmpty()) channel.setLogo(stream.getStreamIcon()); - if (!stream.getEpgChannelId().isEmpty()) channel.setTvgName(stream.getEpgChannelId()); - channel.getUrls().addAll(stream.getPlayUrl(live, info.getUserInfo().getAllowedOutputFormats())); - } - } - private static void txt(Live live, String text) { Setting setting = Setting.create(); text = text.replace("\r\n", "\n").replace("\r", ""); @@ -160,11 +135,6 @@ public class LiveParser { } } - private static String getText(Live live) { - if (live.isXtream() && !XtreamParser.isGetUrl(live.getUrl())) return ""; - return OkHttp.string(UrlUtil.convert(live.getUrl()), live.getHeaders()); - } - private static class Setting { private String ua; diff --git a/app/src/main/java/com/fongmi/android/tv/api/XtreamParser.java b/app/src/main/java/com/fongmi/android/tv/api/XtreamParser.java deleted file mode 100644 index b4458896d..000000000 --- a/app/src/main/java/com/fongmi/android/tv/api/XtreamParser.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.fongmi.android.tv.api; - -import android.net.Uri; - -import com.fongmi.android.tv.bean.Live; -import com.fongmi.android.tv.bean.XCategory; -import com.fongmi.android.tv.bean.XInfo; -import com.fongmi.android.tv.bean.XStream; -import com.github.catvod.net.OkHttp; - -import java.util.List; - -import okhttp3.HttpUrl; - -public class XtreamParser { - - public static HttpUrl.Builder getBuilder(Live live) { - HttpUrl url = HttpUrl.parse(live.getUrl()); - return new HttpUrl.Builder().scheme(url.scheme()).host(url.host()).port(url.port()); - } - - public static boolean isVerify(Uri uri) { - return uri.getPath() != null && uri.getQueryParameter("username") != null && uri.getQueryParameter("password") != null && (uri.getPath().contains("player_api.php") || uri.getPath().contains("get.php")); - } - - public static boolean isApiUrl(String url) { - return isApiUrl(Uri.parse(url)); - } - - public static boolean isApiUrl(Uri uri) { - return uri.getPath() != null && uri.getQueryParameter("username") != null && uri.getQueryParameter("password") != null && uri.getPath().contains("player_api.php"); - } - - public static boolean isGetUrl(String url) { - return isGetUrl(Uri.parse(url)); - } - - public static boolean isGetUrl(Uri uri) { - return uri.getPath() != null && uri.getQueryParameter("username") != null && uri.getQueryParameter("password") != null && uri.getPath().contains("get.php"); - } - - public static String getEpgUrl(Live live) { - return getBuilder(live).addPathSegment("xmltv.php").addQueryParameter("username", live.getUsername()).addQueryParameter("password", live.getPassword()).build().toString(); - } - - public static String getApiUrl(Live live) { - return getBuilder(live).addPathSegment("player_api.php").addQueryParameter("username", live.getUsername()).addQueryParameter("password", live.getPassword()).build().toString(); - } - - public static String getApiUrl(Live live, String action) { - return getBuilder(live).addPathSegment("player_api.php").addQueryParameter("username", live.getUsername()).addQueryParameter("password", live.getPassword()).addQueryParameter("action", action).build().toString(); - } - - public static XInfo getInfo(Live live) { - return XInfo.objectFrom(OkHttp.string(getApiUrl(live))); - } - - public static List getLiveCategoryList(Live live) { - return XCategory.arrayFrom(OkHttp.string(getApiUrl(live, "get_live_categories"))); - } - - public static List getLiveStreamList(Live live) { - return XStream.arrayFrom(OkHttp.string(getApiUrl(live, "get_live_streams"))); - } - - public static List getVodCategoryList(Live live) { - return XCategory.arrayFrom(OkHttp.string(getApiUrl(live, "get_vod_categories"))); - } - - public static List getVodStreamList(Live live) { - return XStream.arrayFrom(OkHttp.string(getApiUrl(live, "get_vod_streams"))); - } - - public static List getCategoryList(Live live) { - List categoryList = XtreamParser.getLiveCategoryList(live); - categoryList.addAll(XtreamParser.getVodCategoryList(live)); - return categoryList; - } - - public static List getStreamList(Live live) { - List streamList = XtreamParser.getLiveStreamList(live); - streamList.addAll(XtreamParser.getVodStreamList(live)); - return streamList; - } -} diff --git a/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java b/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java index 9b2690532..e7388a0b9 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java @@ -8,7 +8,6 @@ import com.fongmi.android.tv.R; import com.fongmi.android.tv.Setting; import com.fongmi.android.tv.api.Decoder; import com.fongmi.android.tv.api.LiveParser; -import com.fongmi.android.tv.api.XtreamParser; import com.fongmi.android.tv.api.loader.BaseLoader; import com.fongmi.android.tv.bean.Channel; import com.fongmi.android.tv.bean.Config; @@ -114,8 +113,7 @@ public class LiveConfig { private void loadConfig(Callback callback) { try { - boolean xtream = XtreamParser.isApiUrl(config.getUrl()); - parseConfig(xtream ? "" : Decoder.getJson(config.getUrl()), callback); + parseConfig(Decoder.getJson(config.getUrl()), callback); } catch (Throwable e) { if (TextUtils.isEmpty(config.getUrl())) App.post(() -> callback.error("")); else App.post(() -> callback.error(Notify.getError(R.string.error_config_get, e))); @@ -124,7 +122,7 @@ public class LiveConfig { } private void parseConfig(String text, Callback callback) { - if (Json.invalid(text)) { + if (!Json.isObj(text)) { parseText(text, callback); } else { checkJson(Json.parse(text).getAsJsonObject(), callback); @@ -132,7 +130,7 @@ public class LiveConfig { } private void parseText(String text, Callback callback) { - Live live = new Live(parseName(config.getUrl()), config.getUrl()).check().sync(); + Live live = new Live(parseName(config.getUrl()), config.getUrl()).sync(); LiveParser.text(live, text); lives.add(live); setHome(live, true); @@ -187,7 +185,7 @@ public class LiveConfig { live.setApi(UrlUtil.convert(live.getApi())); live.setExt(UrlUtil.convert(live.getExt())); live.setJar(parseJar(live, spider)); - lives.add(live.check().sync()); + lives.add(live.sync()); } for (Live live : lives) { if (live.getName().equals(config.getHome())) { diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Live.java b/app/src/main/java/com/fongmi/android/tv/bean/Live.java index 809dc0709..0571013b7 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Live.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Live.java @@ -1,6 +1,5 @@ package com.fongmi.android.tv.bean; -import android.net.Uri; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -11,7 +10,6 @@ import androidx.room.PrimaryKey; import com.fongmi.android.tv.App; import com.fongmi.android.tv.Constant; import com.fongmi.android.tv.R; -import com.fongmi.android.tv.api.XtreamParser; import com.fongmi.android.tv.api.loader.BaseLoader; import com.fongmi.android.tv.db.AppDatabase; import com.fongmi.android.tv.gson.ExtAdapter; @@ -313,10 +311,6 @@ public class Live { this.width = width; } - public boolean isXtream() { - return !getUsername().isEmpty() && !getPassword().isEmpty(); - } - public boolean isEmpty() { return getName().isEmpty(); } @@ -360,14 +354,6 @@ public class Live { return this; } - public Live check() { - Uri uri = Uri.parse(getUrl()); - boolean xtream = XtreamParser.isVerify(uri); - if (xtream) setUsername(uri.getQueryParameter("username")); - if (xtream) setPassword(uri.getQueryParameter("password")); - return this; - } - public Live recent() { BaseLoader.get().setRecent(getName(), getApi(), getJar()); return this; diff --git a/app/src/main/java/com/fongmi/android/tv/bean/XCategory.java b/app/src/main/java/com/fongmi/android/tv/bean/XCategory.java deleted file mode 100644 index 420d5bff0..000000000 --- a/app/src/main/java/com/fongmi/android/tv/bean/XCategory.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.fongmi.android.tv.bean; - -import android.text.TextUtils; - -import com.fongmi.android.tv.App; -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; - -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.List; - -public class XCategory { - - @SerializedName("category_id") - private String categoryId; - @SerializedName("category_name") - private String categoryName; - - public static List arrayFrom(String str) { - Type listType = new TypeToken>() {}.getType(); - List items = App.gson().fromJson(str, listType); - return items == null ? Collections.emptyList() : items; - } - - public String getCategoryId() { - return TextUtils.isEmpty(categoryId) ? "" : categoryId; - } - - public String getCategoryName() { - return TextUtils.isEmpty(categoryName) ? "" : categoryName; - } -} diff --git a/app/src/main/java/com/fongmi/android/tv/bean/XInfo.java b/app/src/main/java/com/fongmi/android/tv/bean/XInfo.java deleted file mode 100644 index 968eb2497..000000000 --- a/app/src/main/java/com/fongmi/android/tv/bean/XInfo.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.fongmi.android.tv.bean; - -import android.text.TextUtils; - -import com.fongmi.android.tv.App; -import com.google.gson.annotations.SerializedName; - -import java.util.ArrayList; -import java.util.List; - -public class XInfo { - - @SerializedName("user_info") - private UserInfo userInfo; - @SerializedName("server_info") - private ServerInfo serverInfo; - - public static XInfo objectFrom(String str) { - XInfo item = App.gson().fromJson(str, XInfo.class); - return item == null ? new XInfo() : item; - } - - public UserInfo getUserInfo() { - return userInfo == null ? new UserInfo() : userInfo; - } - - public ServerInfo getServerInfo() { - return serverInfo == null ? new ServerInfo() : serverInfo; - } - - public static class UserInfo { - - @SerializedName("allowed_output_formats") - private List allowedOutputFormats; - - public List getAllowedOutputFormats() { - if (allowedOutputFormats == null) allowedOutputFormats = new ArrayList<>(); - if (allowedOutputFormats.isEmpty()) allowedOutputFormats.add("ts"); - allowedOutputFormats.remove("rtmp"); - return allowedOutputFormats; - } - } - - public static class ServerInfo { - - @SerializedName("timezone") - private String timezone; - - public String getTimezone() { - return TextUtils.isEmpty(timezone) ? "" : timezone; - } - } -} diff --git a/app/src/main/java/com/fongmi/android/tv/bean/XStream.java b/app/src/main/java/com/fongmi/android/tv/bean/XStream.java deleted file mode 100644 index d2e91fdcb..000000000 --- a/app/src/main/java/com/fongmi/android/tv/bean/XStream.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.fongmi.android.tv.bean; - -import android.text.TextUtils; - -import com.fongmi.android.tv.App; -import com.fongmi.android.tv.api.XtreamParser; -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class XStream { - - @SerializedName("name") - private String name; - @SerializedName("stream_id") - private String streamId; - @SerializedName("stream_type") - private String streamType; - @SerializedName("stream_icon") - private String streamIcon; - @SerializedName("epg_channel_id") - private String epgChannelId; - @SerializedName("category_id") - private String categoryId; - @SerializedName("container_extension") - private String containerExtension; - - public static List arrayFrom(String str) { - Type listType = new TypeToken>() { - }.getType(); - List items = App.gson().fromJson(str, listType); - return items == null ? Collections.emptyList() : items; - } - - public String getName() { - return TextUtils.isEmpty(name) ? "" : name; - } - - public String getStreamId() { - return TextUtils.isEmpty(streamId) ? "" : streamId; - } - - public String getStreamType() { - return TextUtils.isEmpty(streamType) ? "" : streamType; - } - - public String getStreamIcon() { - return TextUtils.isEmpty(streamIcon) ? "" : streamIcon; - } - - public String getEpgChannelId() { - return TextUtils.isEmpty(epgChannelId) ? "" : epgChannelId; - } - - public String getCategoryId() { - return TextUtils.isEmpty(categoryId) ? "" : categoryId; - } - - public String getContainerExtension() { - return TextUtils.isEmpty(containerExtension) ? "" : containerExtension; - } - - public List getPlayUrl(Live live, List formats) { - List urls = new ArrayList<>(); - if (!getContainerExtension().isEmpty()) urls.add(XtreamParser.getBuilder(live).addPathSegment(getStreamType()).addPathSegment(live.getUsername()).addPathSegment(live.getPassword()).addPathSegment(getStreamId() + "." + getContainerExtension()).build().toString()); - else for (String format : formats) urls.add(XtreamParser.getBuilder(live).addPathSegment(getStreamType()).addPathSegment(live.getUsername()).addPathSegment(live.getPassword()).addPathSegment(getStreamId() + "." + format + "$" + format.toUpperCase()).build().toString()); - return urls; - } -} diff --git a/app/src/main/java/com/fongmi/android/tv/gson/DanmakuAdapter.java b/app/src/main/java/com/fongmi/android/tv/gson/DanmakuAdapter.java index 0c71eacc1..d9269da79 100644 --- a/app/src/main/java/com/fongmi/android/tv/gson/DanmakuAdapter.java +++ b/app/src/main/java/com/fongmi/android/tv/gson/DanmakuAdapter.java @@ -2,6 +2,7 @@ package com.fongmi.android.tv.gson; import com.fongmi.android.tv.App; import com.fongmi.android.tv.bean.Danmaku; +import com.github.catvod.utils.Json; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -16,7 +17,7 @@ public class DanmakuAdapter implements JsonDeserializer> { public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (!json.isJsonPrimitive()) return App.gson().fromJson(json, typeOfT); String text = json.getAsString().trim(); - if (text.startsWith("[")) return App.gson().fromJson(text, typeOfT); + if (Json.isArray(text)) return App.gson().fromJson(text, typeOfT); else return Danmaku.from(text); } } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java b/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java index a0b4edbad..5e3c3adff 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java @@ -21,7 +21,7 @@ public class Sniffer { public static final Pattern SNIFFER = Pattern.compile("http((?!http).){12,}?\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac|mpd)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac|mpd)|http((?!http).)*?video/tos*|http((?!http).)*?obj/tos*|rtmp:[^\\s]+"); public static String getUrl(String text) { - if (Json.valid(text) || text.contains("$")) return text; + if (Json.isObj(text) || text.contains("$")) return text; Matcher m = AI_PUSH.matcher(text); if (m.find()) return m.group(0); return text; diff --git a/catvod/src/main/java/com/github/catvod/utils/Json.java b/catvod/src/main/java/com/github/catvod/utils/Json.java index 3a3c1c72e..d2728fc40 100644 --- a/catvod/src/main/java/com/github/catvod/utils/Json.java +++ b/catvod/src/main/java/com/github/catvod/utils/Json.java @@ -6,6 +6,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import org.json.JSONArray; import org.json.JSONObject; import java.util.ArrayList; @@ -23,8 +24,9 @@ public class Json { } } - public static boolean valid(String text) { + public static boolean isObj(String text) { try { + if (TextUtils.isEmpty(text)) return false; new JSONObject(text); return true; } catch (Exception e) { @@ -32,8 +34,14 @@ public class Json { } } - public static boolean invalid(String text) { - return !valid(text); + public static boolean isArray(String text) { + try { + if (TextUtils.isEmpty(text)) return false; + new JSONArray(text); + return true; + } catch (Exception e) { + return false; + } } public static String safeString(JsonObject obj, String key) { diff --git a/other/sample/live/xtream.json b/other/sample/live/xtream.json deleted file mode 100644 index 5abf5531b..000000000 --- a/other/sample/live/xtream.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "lives": [ - { - "name": "Xtream", - "url": "http://127.0.0.2:8888", - "username": "tangsan", - "password": "tangsan" - } - ] -} \ No newline at end of file diff --git a/quickjs/src/main/java/com/fongmi/quickjs/crawler/Spider.java b/quickjs/src/main/java/com/fongmi/quickjs/crawler/Spider.java index 248129f4a..ef6e55946 100644 --- a/quickjs/src/main/java/com/fongmi/quickjs/crawler/Spider.java +++ b/quickjs/src/main/java/com/fongmi/quickjs/crawler/Spider.java @@ -65,7 +65,7 @@ public class Spider extends com.github.catvod.crawler.Spider { @Override public void init(Context context, String extend) throws Exception { if (cat) call("init", submit(() -> cfg(extend)).get()); - else call("init", Json.valid(extend) ? ctx.parse(extend) : extend); + else call("init", Json.isObj(extend) ? ctx.parse(extend) : extend); } @Override @@ -196,7 +196,7 @@ public class Spider extends com.github.catvod.crawler.Spider { JSObject cfg = ctx.createNewJSObject(); cfg.setProperty("stype", 3); cfg.setProperty("skey", key); - if (Json.invalid(ext)) cfg.setProperty("ext", ext); + if (!Json.isObj(ext)) cfg.setProperty("ext", ext); else cfg.setProperty("ext", (JSObject) ctx.parse(ext)); return cfg; }