From b073d6f8e9599416ab4a3ceab0d89f5baf88e8df Mon Sep 17 00:00:00 2001 From: FongMi Date: Wed, 19 Oct 2022 23:44:48 +0800 Subject: [PATCH] support live - part 3 --- .../com/fongmi/android/tv/api/ApiConfig.java | 6 ++ .../com/fongmi/android/tv/api/LiveConfig.java | 65 +++++++++++++++++++ .../com/fongmi/android/tv/bean/Channel.java | 27 +++++++- .../com/fongmi/android/tv/bean/Group.java | 9 ++- .../java/com/fongmi/android/tv/bean/Live.java | 35 ++++------ .../java/com/fongmi/android/tv/bean/Site.java | 6 +- 6 files changed, 118 insertions(+), 30 deletions(-) create mode 100644 app/src/main/java/com/fongmi/android/tv/api/LiveConfig.java diff --git a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java index 13ea11a03..69c92a159 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java @@ -5,6 +5,7 @@ import android.os.Looper; import android.text.TextUtils; import com.fongmi.android.tv.R; +import com.fongmi.android.tv.bean.Channel; import com.fongmi.android.tv.bean.Config; import com.fongmi.android.tv.bean.Parse; import com.fongmi.android.tv.bean.Site; @@ -127,6 +128,11 @@ public class ApiConfig { if (parse.getName().equals(Prefers.getParse())) setParse(parse); if (!parses.contains(parse)) parses.add(parse); } + for (JsonElement element : Json.safeListElement(object, "lives")) { + for (JsonElement channel : element.getAsJsonObject().get("channels").getAsJsonArray()) { + LiveConfig.get().parse(Channel.objectFrom(channel)); + } + } if (home == null) setHome(sites.isEmpty() ? new Site() : sites.get(0)); if (parse == null) setParse(parses.isEmpty() ? new Parse() : parses.get(0)); flags.addAll(Json.safeListString(object, "flags")); diff --git a/app/src/main/java/com/fongmi/android/tv/api/LiveConfig.java b/app/src/main/java/com/fongmi/android/tv/api/LiveConfig.java new file mode 100644 index 000000000..b066a90fb --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/api/LiveConfig.java @@ -0,0 +1,65 @@ +package com.fongmi.android.tv.api; + +import android.util.Base64; + +import com.fongmi.android.tv.bean.Channel; +import com.fongmi.android.tv.bean.Group; +import com.fongmi.android.tv.bean.Live; +import com.fongmi.android.tv.net.OKHttp; + +import java.util.ArrayList; +import java.util.List; + +public class LiveConfig { + + private List lives; + + private static class Loader { + static volatile LiveConfig INSTANCE = new LiveConfig(); + } + + public static LiveConfig get() { + return Loader.INSTANCE; + } + + public LiveConfig init() { + this.lives = new ArrayList<>(); + return this; + } + + public List getLives() { + return lives; + } + + public void parse(Channel item) { + if (lives == null) init(); + if (item.getUrls().isEmpty()) return; + if (!item.getUrls().get(0).startsWith("proxy://")) return; + try { + String base64 = item.getUrls().get(0).split("ext=")[1]; + String url = new String(Base64.decode(base64, Base64.DEFAULT)); + Live live = new Live(item.getName(), new ArrayList<>()); + parse(OKHttp.newCall(url).execute().body().string(), live); + if (live.getGroups().size() > 0) getLives().add(live); + } catch (Exception ignored) { + ignored.printStackTrace(); + } + } + + private void parse(String result, Live live) { + for (String line : result.split("\n")) { + String[] split = line.split(","); + if (split.length < 2) continue; + if (line.contains("#genre#")) { + live.getGroups().add(new Group(split[0])); + } + if (split[1].contains("://")) { + Group group = live.getGroups().get(live.getGroups().size() - 1); + Channel channel = new Channel(group.getChannel().size() + 1, split[0], split[1].split("#")); + int index = group.getChannel().indexOf(channel); + if (index != -1) group.getChannel().get(index).getUrls().addAll(channel.getUrls()); + else group.getChannel().add(channel); + } + } + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Channel.java b/app/src/main/java/com/fongmi/android/tv/bean/Channel.java index d0ada6af0..85c064200 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Channel.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Channel.java @@ -5,20 +5,36 @@ import android.view.View; import android.widget.ImageView; import com.fongmi.android.tv.utils.ImgUtil; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.annotations.SerializedName; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; public class Channel { + @SerializedName("urls") private List urls; + @SerializedName("number") private String number; + @SerializedName("icon") private String icon; + @SerializedName("name") private String name; + @SerializedName("type") private Group type; + @SerializedName("ua") private String ua; + private boolean select; + public static Channel objectFrom(JsonElement element) { + return new Gson().fromJson(element, Channel.class); + } + public static Channel create(String number) { return new Channel(String.format(Locale.getDefault(), "%03d", Integer.valueOf(number))); } @@ -27,9 +43,14 @@ public class Channel { this.number = number; } - public Channel(String number, String name) { - this.number = number; + public Channel(int number, String name, String... urls) { + this(number, name, new ArrayList<>(Arrays.asList(urls))); + } + + public Channel(int number, String name, List urls) { + this.number = String.format(Locale.getDefault(), "%03d", number); this.name = name; + this.urls = urls; } public List getUrls() { @@ -101,6 +122,6 @@ public class Channel { if (this == obj) return true; if (!(obj instanceof Channel)) return false; Channel it = (Channel) obj; - return getNumber().equals(it.getNumber()); + return getNumber().equals(it.getNumber()) || getName().equals(it.getName()); } } diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Group.java b/app/src/main/java/com/fongmi/android/tv/bean/Group.java index e4ad4f76a..67928d619 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Group.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Group.java @@ -5,24 +5,31 @@ import android.view.View; import android.widget.ImageView; import com.fongmi.android.tv.utils.ImgUtil; +import com.google.gson.annotations.SerializedName; +import java.util.ArrayList; import java.util.List; public class Group { + @SerializedName("channel") private List channel; + @SerializedName("icon") private String icon; + @SerializedName("name") private String name; + @SerializedName("pass") private String pass; private boolean select; private int position; public Group(String name) { this.name = name; + if (name.contains("_")) setPass(name.split("_")[1]); } public List getChannel() { - return channel; + return channel = channel == null ? new ArrayList<>() : channel; } public void setChannel(List channel) { 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 2a04089cc..9e4c27be6 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 @@ -6,32 +6,21 @@ import java.util.List; public class Live { - @SerializedName("group") - private String group; - @SerializedName("channels") - private List channels; - - public String getGroup() { - return group; + @SerializedName("name") + private String name; + @SerializedName("groups") + private List groups; + + public Live(String name, List groups) { + this.name = name; + this.groups = groups; } - public List getChannels() { - return channels; + public String getName() { + return name; } - public static class Channels { - - @SerializedName("name") - private String name; - @SerializedName("urls") - private List urls; - - public String getName() { - return name; - } - - public List getUrls() { - return urls; - } + public List getGroups() { + return groups; } } diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Site.java b/app/src/main/java/com/fongmi/android/tv/bean/Site.java index e2a34781e..5028472cb 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Site.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Site.java @@ -25,7 +25,7 @@ public class Site { @SerializedName("name") private String name; @SerializedName("type") - private int type; + private Integer type; @SerializedName("api") private String api; @SerializedName("playUrl") @@ -80,8 +80,8 @@ public class Site { this.name = name; } - public int getType() { - return type; + public Integer getType() { + return type == null ? 0 : type; } public void setType(int type) {