Support xtream code

pull/586/head
FongMi 1 year ago
parent acf8a2265b
commit 8b45aefcaf
  1. 2
      app/src/main/java/com/fongmi/android/tv/api/EpgParser.java
  2. 23
      app/src/main/java/com/fongmi/android/tv/api/LiveParser.java
  3. 38
      app/src/main/java/com/fongmi/android/tv/api/XtreamParser.java
  4. 4
      app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java
  5. 46
      app/src/main/java/com/fongmi/android/tv/bean/Live.java
  6. 33
      app/src/main/java/com/fongmi/android/tv/bean/XCategory.java
  7. 51
      app/src/main/java/com/fongmi/android/tv/bean/XStream.java

@ -28,7 +28,7 @@ import java.util.Set;
public class EpgParser {
public static boolean start(Live live) throws Exception {
if (!live.getEpg().endsWith(".xml") && !live.getEpg().endsWith(".gz")) return false;
if (!live.getEpg().contains("xml") && !live.getEpg().contains("gz")) return false;
File file = Path.epg(Uri.parse(live.getEpg()).getLastPathSegment());
if (shouldDownload(file)) Download.create(live.getEpg(), file).start();
if (file.getName().endsWith(".gz")) readGzip(live, file);

@ -10,6 +10,8 @@ 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.XStream;
import com.fongmi.android.tv.utils.UrlUtil;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Json;
@ -17,6 +19,7 @@ import com.github.catvod.utils.Path;
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;
@ -30,6 +33,7 @@ public class LiveParser {
private static final Pattern TVG_URL = Pattern.compile(".*x-tvg-url=\"(.?|.+?)\".*");
private static final Pattern GROUP = Pattern.compile(".*group-title=\"(.?|.+?)\".*");
private static final Pattern NAME = Pattern.compile(".*,(.+?)$");
private static final Pattern M3U = Pattern.compile("#EXTM3U|#EXTINF");
private static String extract(String line, Pattern pattern) {
Matcher matcher = pattern.matcher(line.trim());
@ -47,7 +51,8 @@ public class LiveParser {
public static void text(Live live, String text) {
int number = 0;
if (live.getGroups().size() > 0) return;
if (text.contains("#EXTM3U")) m3u(live, text);
if (M3U.matcher(text).find()) m3u(live, text);
else if (live.isXtream()) xtream(live);
else txt(live, text);
for (Group group : live.getGroups()) {
for (Channel channel : group.getChannel()) {
@ -102,6 +107,22 @@ public class LiveParser {
}
}
private static void xtream(Live live) {
List<XCategory> categoryList = XtreamParser.getCategoryList(live);
List<XStream> streamList = XtreamParser.getStreamList(live);
Map<String, String> categoryMap = new HashMap<>();
for (XCategory category : categoryList) {
categoryMap.put(category.getCategoryId(), category.getCategoryName());
}
for (XStream stream : streamList) {
Group group = live.find(Group.create(categoryMap.get(stream.getCategoryId()), live.isPass()));
Channel channel = group.find(Channel.create(stream.getName()));
channel.getUrls().add(XtreamParser.getTsUrl(live, stream.getStreamId()));
if (!stream.getStreamIcon().isEmpty()) channel.setLogo(stream.getStreamIcon());
if (!stream.getEpgChannelId().isEmpty()) channel.setTvgName(stream.getEpgChannelId());
}
}
private static void txt(Live live, String text) {
Setting setting = Setting.create();
for (String line : text.split("\n")) {

@ -0,0 +1,38 @@
package com.fongmi.android.tv.api;
import com.fongmi.android.tv.bean.Live;
import com.fongmi.android.tv.bean.XCategory;
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 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, String action) {
return getBuilder(live).addPathSegment("player_api.php").addQueryParameter("username", live.getUsername()).addQueryParameter("password", live.getPassword()).addQueryParameter("action", action).build().toString();
}
public static String getTsUrl(Live live, String id) {
return getBuilder(live).addPathSegment("live").addPathSegment(live.getUsername()).addPathSegment(live.getPassword()).addPathSegment(id + ".ts").build().toString();
}
public static List<XCategory> getCategoryList(Live live) {
return XCategory.arrayFrom(OkHttp.string(getApiUrl(live, "get_live_categories")));
}
public static List<XStream> getStreamList(Live live) {
return XStream.arrayFrom(OkHttp.string(getApiUrl(live, "get_live_streams")));
}
}

@ -130,7 +130,7 @@ public class LiveConfig {
}
private void parseText(String text, Callback callback) {
Live live = new Live(parseName(config.getUrl()), config.getUrl()).sync();
Live live = new Live(parseName(config.getUrl()), config.getUrl()).check().sync();
LiveParser.text(live, text);
lives.add(live);
setHome(live, true);
@ -185,7 +185,7 @@ public class LiveConfig {
live.setApi(parseApi(live.getApi()));
live.setExt(parseExt(live.getExt()));
live.setJar(parseJar(live, spider));
lives.add(live.sync());
lives.add(live.check().sync());
}
for (Live live : lives) {
if (live.getName().equals(config.getHome())) {

@ -1,5 +1,6 @@
package com.fongmi.android.tv.bean;
import android.net.Uri;
import android.text.TextUtils;
import androidx.annotation.NonNull;
@ -10,9 +11,11 @@ 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;
import com.fongmi.android.tv.utils.UrlUtil;
import com.github.catvod.crawler.Spider;
import com.github.catvod.utils.Json;
import com.google.common.net.HttpHeaders;
@ -76,6 +79,14 @@ public class Live {
@SerializedName("referer")
private String referer;
@Ignore
@SerializedName("username")
private String username;
@Ignore
@SerializedName("password")
private String password;
@Ignore
@SerializedName("type")
private Integer type;
@ -148,6 +159,10 @@ public class Live {
return TextUtils.isEmpty(url) ? "" : url;
}
public void setUrl(String url) {
this.url = url;
}
public String getApi() {
return TextUtils.isEmpty(api) ? "" : api;
}
@ -200,6 +215,22 @@ public class Live {
return TextUtils.isEmpty(referer) ? "" : referer;
}
public String getUsername() {
return TextUtils.isEmpty(username) ? "" : username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return TextUtils.isEmpty(password) ? "" : password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getType() {
return type == null ? 0 : type;
}
@ -260,6 +291,10 @@ public class Live {
this.width = width;
}
public boolean isXtream() {
return !getUsername().isEmpty() && !getPassword().isEmpty();
}
public boolean isEmpty() {
return getName().isEmpty();
}
@ -297,6 +332,17 @@ public class Live {
return this;
}
public Live check() {
Uri uri = Uri.parse(getUrl());
boolean php = UrlUtil.path(uri).contains("get.php");
String username = uri.getQueryParameter("username");
String password = uri.getQueryParameter("password");
if (php && username != null) setUsername(username);
if (php && password != null) setPassword(password);
if (isXtream() && getEpg().isEmpty()) setEpg(XtreamParser.getEpgUrl(this));
return this;
}
public Live recent() {
BaseLoader.get().setRecent(getName(), getApi(), getJar());
return this;

@ -0,0 +1,33 @@
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<XCategory> arrayFrom(String str) {
Type listType = new TypeToken<List<XCategory>>() {}.getType();
List<XCategory> 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;
}
}

@ -0,0 +1,51 @@
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 XStream {
@SerializedName("name")
private String name;
@SerializedName("stream_id")
private String streamId;
@SerializedName("stream_icon")
private String streamIcon;
@SerializedName("epg_channel_id")
private String epgChannelId;
@SerializedName("category_id")
private String categoryId;
public static List<XStream> arrayFrom(String str) {
Type listType = new TypeToken<List<XStream>>() {}.getType();
List<XStream> 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 getStreamIcon() {
return TextUtils.isEmpty(streamIcon) ? "" : streamIcon;
}
public String getEpgChannelId() {
return TextUtils.isEmpty(epgChannelId) ? "" : epgChannelId;
}
public String getCategoryId() {
return TextUtils.isEmpty(categoryId) ? "" : categoryId;
}
}
Loading…
Cancel
Save