diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java index f7f601e5a..f15404ad4 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java @@ -47,7 +47,7 @@ import com.fongmi.android.tv.impl.Callback; import com.fongmi.android.tv.model.SiteViewModel; import com.fongmi.android.tv.player.ExoUtil; import com.fongmi.android.tv.player.Players; -import com.fongmi.android.tv.player.source.Source; +import com.fongmi.android.tv.player.Source; import com.fongmi.android.tv.ui.base.BaseActivity; import com.fongmi.android.tv.ui.custom.CustomKeyDownVod; import com.fongmi.android.tv.ui.custom.dialog.DescDialog; @@ -1275,9 +1275,9 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis @Override protected void onDestroy() { super.onDestroy(); - Source.stopAll(); mPlayers.release(); Clock.get().release(); + Source.get().destroy(); RefreshEvent.history(); App.removeCallbacks(mR1, mR2, mR3); } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java index b9102e100..ee4525599 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java @@ -33,6 +33,7 @@ import com.fongmi.android.tv.event.RefreshEvent; import com.fongmi.android.tv.event.ServerEvent; import com.fongmi.android.tv.impl.Callback; import com.fongmi.android.tv.model.SiteViewModel; +import com.fongmi.android.tv.player.Source; import com.fongmi.android.tv.server.Server; import com.fongmi.android.tv.ui.base.BaseActivity; import com.fongmi.android.tv.ui.custom.CustomRowPresenter; @@ -57,10 +58,10 @@ import java.util.List; public class HomeActivity extends BaseActivity implements CustomTitleView.Listener, VodPresenter.OnClickListener, FuncPresenter.OnClickListener, HistoryPresenter.OnClickListener { + private ArrayObjectAdapter mHistoryAdapter; private ActivityHomeBinding mBinding; + private HistoryPresenter mPresenter; private ArrayObjectAdapter mAdapter; - private ArrayObjectAdapter mHistoryAdapter; - private HistoryPresenter mHistoryPresenter; private SiteViewModel mViewModel; private boolean confirm; private Result result; @@ -94,7 +95,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen @Override public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable RecyclerView.ViewHolder child, int position, int subposition) { mBinding.toolbar.setVisibility(position == 0 ? View.VISIBLE : View.GONE); - if (mHistoryPresenter.isDelete()) setHistoryDelete(false); + if (mPresenter.isDelete()) setHistoryDelete(false); } }); } @@ -130,7 +131,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen mAdapter.add(getFuncRow()); mAdapter.add(R.string.home_history); mAdapter.add(R.string.home_recommend); - mHistoryAdapter = new ArrayObjectAdapter(mHistoryPresenter = new HistoryPresenter(this)); + mHistoryAdapter = new ArrayObjectAdapter(mPresenter = new HistoryPresenter(this)); } private void initConfig() { @@ -204,14 +205,14 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen int historyIndex = getHistoryIndex(); int recommendIndex = getRecommendIndex(); boolean exist = recommendIndex - historyIndex == 2; - if (renew) mHistoryAdapter = new ArrayObjectAdapter(mHistoryPresenter = new HistoryPresenter(this)); + if (renew) mHistoryAdapter = new ArrayObjectAdapter(mPresenter = new HistoryPresenter(this)); if ((items.isEmpty() && exist) || (renew && exist)) mAdapter.removeItems(historyIndex, 1); if ((items.size() > 0 && !exist) || (renew && exist)) mAdapter.add(historyIndex, new ListRow(mHistoryAdapter)); mHistoryAdapter.setItems(items, null); } private void setHistoryDelete(boolean delete) { - mHistoryPresenter.setDelete(delete); + mPresenter.setDelete(delete); mHistoryAdapter.notifyArrayItemRangeChanged(0, mHistoryAdapter.size()); } @@ -276,7 +277,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen mHistoryAdapter.remove(item.delete()); if (mHistoryAdapter.size() > 0) return; mAdapter.removeItems(getHistoryIndex(), 1); - mHistoryPresenter.setDelete(false); + mPresenter.setDelete(false); } @Override @@ -380,7 +381,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen public void onBackPressed() { if (mBinding.progressLayout.isProgress()) { mBinding.progressLayout.showContent(); - } else if (mHistoryPresenter.isDelete()) { + } else if (mPresenter.isDelete()) { setHistoryDelete(false); } else if (mBinding.recycler.getSelectedPosition() != 0) { mBinding.recycler.scrollToPosition(0); @@ -397,6 +398,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen WallConfig.get().clear(); LiveConfig.get().clear(); ApiConfig.get().clear(); + Source.get().release(); Server.get().stop(); } } \ No newline at end of file diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java index 917a690a9..63dca2bb8 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java @@ -38,7 +38,7 @@ import com.fongmi.android.tv.impl.PassCallback; import com.fongmi.android.tv.model.LiveViewModel; import com.fongmi.android.tv.player.ExoUtil; import com.fongmi.android.tv.player.Players; -import com.fongmi.android.tv.player.source.Source; +import com.fongmi.android.tv.player.Source; import com.fongmi.android.tv.ui.base.BaseActivity; import com.fongmi.android.tv.ui.custom.CustomKeyDownLive; import com.fongmi.android.tv.ui.custom.CustomLiveListView; @@ -816,8 +816,8 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick @Override protected void onDestroy() { super.onDestroy(); - Source.stopAll(); mPlayers.release(); + Source.get().destroy(); App.removeCallbacks(mR1, mR2, mR3, mR4); } } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/LiveDialog.java b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/LiveDialog.java index 005ce69b2..d84ec0f7f 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/LiveDialog.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/LiveDialog.java @@ -7,7 +7,6 @@ import android.view.WindowManager; import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.GridLayoutManager; -import com.fongmi.android.tv.App; import com.fongmi.android.tv.api.LiveConfig; import com.fongmi.android.tv.bean.Live; import com.fongmi.android.tv.databinding.DialogLiveBinding; diff --git a/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java b/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java index da4816eca..3d06acd34 100644 --- a/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java +++ b/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java @@ -8,7 +8,7 @@ import com.fongmi.android.tv.api.LiveParser; 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.player.source.Source; +import com.fongmi.android.tv.player.Source; import java.util.Iterator; import java.util.concurrent.Callable; @@ -45,8 +45,8 @@ public class LiveViewModel extends ViewModel { public void fetch(Channel item) { execute(CHANNEL, () -> { - Source.stop(); - item.setUrl(Source.getUrl(item.getCurrent().split("\\$")[0])); + Source.get().stop(); + item.setUrl(Source.get().fetch(item.getCurrent().split("\\$")[0])); return item; }); } diff --git a/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java b/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java index f337b056b..f26830a85 100644 --- a/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java +++ b/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java @@ -14,7 +14,7 @@ import com.fongmi.android.tv.api.ApiConfig; import com.fongmi.android.tv.bean.Result; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.bean.Vod; -import com.fongmi.android.tv.player.source.Source; +import com.fongmi.android.tv.player.Source; import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.Sniffer; import com.fongmi.android.tv.utils.Trans; @@ -136,7 +136,7 @@ public class SiteViewModel extends ViewModel { public void playerContent(String key, String flag, String id) { execute(player, () -> { - Source.stop(); + Source.get().stop(); Site site = ApiConfig.get().getSite(key); if (site.getType() == 3) { Spider spider = ApiConfig.get().getCSP(site); @@ -145,7 +145,7 @@ public class SiteViewModel extends ViewModel { ApiConfig.get().setRecent(site); Result result = Result.objectFrom(playerContent); if (result.getFlag().isEmpty()) result.setFlag(flag); - result.setUrl(Source.getUrl(result.getUrl())); + result.setUrl(Source.get().fetch(result.getUrl())); result.setKey(key); return result; } else if (site.getType() == 4) { @@ -156,13 +156,13 @@ public class SiteViewModel extends ViewModel { SpiderDebug.log(body); Result result = Result.fromJson(body); if (result.getFlag().isEmpty()) result.setFlag(flag); - result.setUrl(Source.getUrl(result.getUrl())); + result.setUrl(Source.get().fetch(result.getUrl())); return result; } else if (key.equals("push_agent")) { Result result = new Result(); - result.setFlag(flag); result.setParse(0); - result.setUrl(id); + result.setFlag(flag); + result.setUrl(Source.get().fetch(result.getUrl())); return result; } else { String url = id; diff --git a/app/src/main/java/com/fongmi/android/tv/player/Source.java b/app/src/main/java/com/fongmi/android/tv/player/Source.java new file mode 100644 index 000000000..d0ff5f9a2 --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/player/Source.java @@ -0,0 +1,73 @@ +package com.fongmi.android.tv.player; + +import android.net.Uri; + +import com.fongmi.android.tv.player.extractor.BiliBili; +import com.fongmi.android.tv.player.extractor.Force; +import com.fongmi.android.tv.player.extractor.JianPian; +import com.fongmi.android.tv.player.extractor.TVBus; +import com.fongmi.android.tv.player.extractor.Youtube; +import com.fongmi.android.tv.player.extractor.ZLive; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class Source { + + private final List extractors; + + private static class Loader { + static volatile Source INSTANCE = new Source(); + } + + public static Source get() { + return Loader.INSTANCE; + } + + public Source() { + extractors = new ArrayList<>(); + extractors.add(new BiliBili()); + extractors.add(new Force()); + extractors.add(new JianPian()); + extractors.add(new TVBus()); + extractors.add(new Youtube()); + extractors.add(new ZLive()); + } + + public String fetch(String url) throws Exception { + Uri uri = Uri.parse(url); + String host = Objects.requireNonNullElse(uri.getHost(), ""); + String scheme = Objects.requireNonNullElse(uri.getScheme(), ""); + for (Extractor extractor : extractors) if (extractor.match(scheme, host)) return extractor.fetch(url); + return url; + } + + public void stop() { + if (extractors == null) return; + for (Extractor extractor : extractors) extractor.stop(); + } + + public void destroy() { + if (extractors == null) return; + for (Extractor extractor : extractors) extractor.destroy(); + } + + public void release() { + if (extractors == null) return; + for (Extractor extractor : extractors) extractor.release(); + } + + public interface Extractor { + + boolean match(String scheme, String host); + + String fetch(String url) throws Exception; + + void stop(); + + void destroy(); + + void release(); + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/player/extractor/BiliBili.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/BiliBili.java new file mode 100644 index 000000000..a3bc25f97 --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/BiliBili.java @@ -0,0 +1,39 @@ +package com.fongmi.android.tv.player.extractor; + +import android.net.Uri; + +import com.fongmi.android.tv.player.Source; +import com.fongmi.android.tv.utils.Sniffer; +import com.github.catvod.net.OkHttp; +import com.google.common.net.HttpHeaders; +import com.google.gson.JsonParser; + +import okhttp3.Headers; + +public class BiliBili implements Source.Extractor { + + @Override + public boolean match(String scheme, String host) { + return "live.bilibili.com".equals(host); + } + + @Override + public String fetch(String url) throws Exception { + String room = Uri.parse(url).getPath().replace("/", ""); + String api = String.format("https://api.live.bilibili.com/room/v1/Room/playUrl?cid=%s&qn=20000&platform=h5", room); + String result = OkHttp.newCall(api, Headers.of(HttpHeaders.USER_AGENT, Sniffer.CHROME)).execute().body().string(); + return JsonParser.parseString(result).getAsJsonObject().get("data").getAsJsonObject().get("durl").getAsJsonArray().get(0).getAsJsonObject().get("url").getAsString(); + } + + @Override + public void stop() { + } + + @Override + public void destroy() { + } + + @Override + public void release() { + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/player/source/Force.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/Force.java similarity index 57% rename from app/src/main/java/com/fongmi/android/tv/player/source/Force.java rename to app/src/main/java/com/fongmi/android/tv/player/extractor/Force.java index 4907acf04..303cb79b9 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/source/Force.java +++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/Force.java @@ -1,4 +1,4 @@ -package com.fongmi.android.tv.player.source; +package com.fongmi.android.tv.player.extractor; import android.content.ComponentName; import android.content.Context; @@ -8,6 +8,7 @@ import android.os.IBinder; import android.os.SystemClock; import com.fongmi.android.tv.App; +import com.fongmi.android.tv.player.Source; import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Github; import com.forcetech.Util; @@ -18,20 +19,13 @@ import java.util.HashSet; import okhttp3.Headers; -public class Force { +public class Force implements Source.Extractor { - private final HashSet set; + private final HashSet set = new HashSet<>(); - private static class Loader { - static volatile Force INSTANCE = new Force(); - } - - public static Force get() { - return Loader.INSTANCE; - } - - public Force() { - set = new HashSet<>(); + @Override + public boolean match(String scheme, String host) { + return scheme.startsWith("p") || scheme.equals("mitv"); } private void init(String url) throws Exception { @@ -41,25 +35,30 @@ public class Force { App.get().bindService(Util.intent(App.get(), url, file), mConn, Context.BIND_AUTO_CREATE); } - public String fetch(String url) { - try { - String scheme = Util.scheme(url); - if (!set.contains(scheme)) init(url); - while (!set.contains(scheme)) SystemClock.sleep(10); - Uri uri = Uri.parse(url); - int port = Util.port(url); - String id = uri.getLastPathSegment(); - String cmd = "http://127.0.0.1:" + port + "/cmd.xml?cmd=switch_chan&server=" + uri.getHost() + ":" + uri.getPort() + "&id=" + id; - String result = "http://127.0.0.1:" + port + "/" + id; - OkHttp.newCall(cmd, Headers.of("user-agent", "MTV")).execute().body().string(); - return result; - } catch (Exception e) { - e.printStackTrace(); - return url; - } + @Override + public String fetch(String url) throws Exception { + String scheme = Util.scheme(url); + if (!set.contains(scheme)) init(url); + while (!set.contains(scheme)) SystemClock.sleep(10); + Uri uri = Uri.parse(url); + int port = Util.port(url); + String id = uri.getLastPathSegment(); + String cmd = "http://127.0.0.1:" + port + "/cmd.xml?cmd=switch_chan&server=" + uri.getHost() + ":" + uri.getPort() + "&id=" + id; + String result = "http://127.0.0.1:" + port + "/" + id; + OkHttp.newCall(cmd, Headers.of("user-agent", "MTV")).execute().body().string(); + return result; } + @Override public void stop() { + } + + @Override + public void destroy() { + } + + @Override + public void release() { try { if (!set.isEmpty()) App.get().unbindService(mConn); } catch (Exception e) { diff --git a/app/src/main/java/com/fongmi/android/tv/player/source/JianPian.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/JianPian.java similarity index 76% rename from app/src/main/java/com/fongmi/android/tv/player/source/JianPian.java rename to app/src/main/java/com/fongmi/android/tv/player/extractor/JianPian.java index cc7c0e6a2..a0dbb4d8a 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/source/JianPian.java +++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/JianPian.java @@ -1,9 +1,10 @@ -package com.fongmi.android.tv.player.source; +package com.fongmi.android.tv.player.extractor; import android.net.Uri; import com.fongmi.android.tv.App; import com.fongmi.android.tv.BuildConfig; +import com.fongmi.android.tv.player.Source; import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Github; import com.github.catvod.net.OkHttp; @@ -13,17 +14,14 @@ import java.io.File; import java.net.URLDecoder; import java.net.URLEncoder; -public class JianPian { +public class JianPian implements Source.Extractor { private P2PClass p2p; private String url; - private static class Loader { - static volatile JianPian INSTANCE = new JianPian(); - } - - public static JianPian get() { - return Loader.INSTANCE; + @Override + public boolean match(String scheme, String host) { + return scheme.equals("tvbox-xg"); } private void init() throws Exception { @@ -34,6 +32,7 @@ public class JianPian { p2p = new P2PClass(App.get(), file.getAbsolutePath()); } + @Override public String fetch(String u) throws Exception { init(); stop(); @@ -58,6 +57,7 @@ public class JianPian { } } + @Override public void stop() { try { if (p2p == null || url == null) return; @@ -68,4 +68,20 @@ public class JianPian { e.printStackTrace(); } } + + @Override + public void destroy() { + stop(); + } + + @Override + public void release() { + try { + if (p2p != null) p2p.P2Pdoxendhttpd(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + p2p = null; + } + } } diff --git a/app/src/main/java/com/fongmi/android/tv/player/source/TVBus.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java similarity index 77% rename from app/src/main/java/com/fongmi/android/tv/player/source/TVBus.java rename to app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java index 541780174..5b50ab772 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/source/TVBus.java +++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java @@ -1,23 +1,21 @@ -package com.fongmi.android.tv.player.source; +package com.fongmi.android.tv.player.extractor; import com.fongmi.android.tv.App; import com.fongmi.android.tv.api.LiveConfig; import com.fongmi.android.tv.bean.Core; +import com.fongmi.android.tv.player.Source; import com.google.gson.JsonObject; import com.tvbus.engine.Listener; import com.tvbus.engine.TVCore; -public class TVBus implements Listener { +public class TVBus implements Source.Extractor, Listener { private TVCore tvcore; private String hls; - private static class Loader { - static volatile TVBus INSTANCE = new TVBus(); - } - - public static TVBus get() { - return Loader.INSTANCE; + @Override + public boolean match(String scheme, String host) { + return scheme.equals("tvbus"); } private void init(Core core) { @@ -28,7 +26,8 @@ public class TVBus implements Listener { tvcore.init(App.get()); } - public String fetch(String url) throws InterruptedException { + @Override + public String fetch(String url) throws Exception { if (tvcore == null) init(LiveConfig.get().getHome().getCore()); tvcore.start(url); onWait(); @@ -47,11 +46,22 @@ public class TVBus implements Listener { } } + @Override public void stop() { if (tvcore != null) tvcore.stop(); if (hls != null) hls = null; } + @Override + public void destroy() { + stop(); + } + + @Override + public void release() { + tvcore = null; + } + @Override public void onPrepared(String result) { JsonObject json = App.gson().fromJson(result, JsonObject.class); diff --git a/app/src/main/java/com/fongmi/android/tv/player/extractor/Youtube.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/Youtube.java new file mode 100644 index 000000000..32be65f0a --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/Youtube.java @@ -0,0 +1,59 @@ +package com.fongmi.android.tv.player.extractor; + +import com.fongmi.android.tv.player.Source; +import com.fongmi.android.tv.utils.Sniffer; +import com.github.catvod.net.OkHttp; +import com.google.common.net.HttpHeaders; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import okhttp3.Headers; + +public class Youtube implements Source.Extractor { + + @Override + public boolean match(String scheme, String host) { + return host.contains("youtube.com"); + } + + @Override + public String fetch(String url) throws Exception { + String result = OkHttp.newCall(url, Headers.of(HttpHeaders.USER_AGENT, Sniffer.CHROME)).execute().body().string(); + Pattern pattern = Pattern.compile("hlsManifestUrl\\S*?(https\\S*?\\.m3u8)"); + Matcher matcher = pattern.matcher(result); + if (!matcher.find()) return ""; + String stable = matcher.group(1); + result = OkHttp.newCall(stable, Headers.of(HttpHeaders.USER_AGENT, Sniffer.CHROME)).execute().body().string(); + String quality = find(result); + return quality.isEmpty() ? url : quality; + } + + private String find(String result) { + String url = ""; + List items = Arrays.asList("301", "300", "96", "95", "94"); + for (String item : items) if (!(url = find(result, "https:/.*/" + item + "/.*index.m3u8")).isEmpty()) break; + return url; + } + + private String find(String result, String rule) { + Pattern pattern = Pattern.compile(rule); + Matcher matcher = pattern.matcher(result); + if (matcher.find()) return matcher.group(); + return ""; + } + + @Override + public void stop() { + } + + @Override + public void destroy() { + } + + @Override + public void release() { + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/player/extractor/ZLive.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/ZLive.java new file mode 100644 index 000000000..513072124 --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/ZLive.java @@ -0,0 +1,60 @@ +package com.fongmi.android.tv.player.extractor; + +import com.fongmi.android.tv.player.Source; +import com.fongmi.android.tv.utils.FileUtil; +import com.github.catvod.net.OkHttp; + +public class ZLive implements Source.Extractor { + + private final String BASE = "http://127.0.0.1:6677/stream/"; + private boolean init; + + public void init() { + //com.east.android.zlive.ZLive.INSTANCE.OnLiveStart(6677); + //init = true; + } + + private String getLive(String uuid) { + return BASE + "live?uuid=" + uuid; + } + + private String getOpen(String uuid) { + return BASE + "open?uuid=" + uuid; + } + + @Override + public boolean match(String scheme, String host) { + return scheme.equals("zlive"); + } + + @Override + public String fetch(String url) throws Exception { + if (!init) init(); + String[] split = url.split("/"); + String server = split[2]; + String uuid = split[3]; + String param = "&group=5850&mac=00:00:00:00:00:00&dir="; + String result = getLive(uuid) + "&server=" + server + param + FileUtil.getCachePath(); + OkHttp.newCall(getOpen(uuid)).execute(); + return result; + } + + @Override + public void stop() { + try { + //if (init) com.east.android.zlive.ZLive.INSTANCE.OnLiveStop(); + //init = false; + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + public void destroy() { + stop(); + } + + @Override + public void release() { + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/player/source/BiliBili.java b/app/src/main/java/com/fongmi/android/tv/player/source/BiliBili.java deleted file mode 100644 index f26af8f63..000000000 --- a/app/src/main/java/com/fongmi/android/tv/player/source/BiliBili.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.fongmi.android.tv.player.source; - -import android.net.Uri; - -import com.fongmi.android.tv.utils.Sniffer; -import com.github.catvod.net.OkHttp; -import com.google.common.net.HttpHeaders; -import com.google.gson.JsonParser; - -import okhttp3.Headers; - -public class BiliBili { - - private static class Loader { - static volatile BiliBili INSTANCE = new BiliBili(); - } - - public static BiliBili get() { - return Loader.INSTANCE; - } - - public String fetch(String url) { - try { - String room = Uri.parse(url).getPath().replace("/", ""); - String api = String.format("https://api.live.bilibili.com/room/v1/Room/playUrl?cid=%s&qn=20000&platform=h5", room); - String result = OkHttp.newCall(api, Headers.of(HttpHeaders.USER_AGENT, Sniffer.CHROME)).execute().body().string(); - return JsonParser.parseString(result).getAsJsonObject().get("data").getAsJsonObject().get("durl").getAsJsonArray().get(0).getAsJsonObject().get("url").getAsString(); - } catch (Exception e) { - e.printStackTrace(); - return url; - } - } -} diff --git a/app/src/main/java/com/fongmi/android/tv/player/source/Source.java b/app/src/main/java/com/fongmi/android/tv/player/source/Source.java deleted file mode 100644 index 389db8974..000000000 --- a/app/src/main/java/com/fongmi/android/tv/player/source/Source.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.fongmi.android.tv.player.source; - -import android.net.Uri; - -public class Source { - - private static String getScheme(Uri uri) { - return uri.getScheme() == null ? "" : uri.getScheme().toLowerCase(); - } - - private static String getHost(Uri uri) { - return uri.getHost() == null ? "" : uri.getHost(); - } - - private static boolean isHttp(Uri uri) { - return getScheme(uri).startsWith("http"); - } - - private static boolean isForce(Uri uri) { - return getScheme(uri).startsWith("p") || getScheme(uri).equals("mitv"); - } - - private static boolean isZLive(Uri uri) { - return getScheme(uri).startsWith("zlive"); - } - - private static boolean isTVBus(Uri uri) { - return getScheme(uri).startsWith("tvbus"); - } - - private static boolean isJianPian(Uri uri) { - return getScheme(uri).equals("tvbox-xg"); - } - - private static boolean isYoutube(Uri uri) { - return getHost(uri).contains("youtube.com"); - } - - private static boolean isBiliBili(Uri uri) { - return getHost(uri).equals("live.bilibili.com"); - } - - public static String getUrl(String url) throws Exception { - Uri uri = Uri.parse(url); - if (isHttp(uri)) { - if (isYoutube(uri)) return Youtube.get().fetch(url); - if (isBiliBili(uri)) return BiliBili.get().fetch(url); - return url; - } else { - if (isForce(uri)) return Force.get().fetch(url); - if (isZLive(uri)) return ZLive.get().fetch(url); - if (isTVBus(uri)) return TVBus.get().fetch(url); - if (isJianPian(uri)) return JianPian.get().fetch(url); - return url; - } - } - - public static void stop() { - TVBus.get().stop(); - JianPian.get().stop(); - } - - public static void stopAll() { - Force.get().stop(); - ZLive.get().stop(); - TVBus.get().stop(); - JianPian.get().stop(); - } -} diff --git a/app/src/main/java/com/fongmi/android/tv/player/source/Youtube.java b/app/src/main/java/com/fongmi/android/tv/player/source/Youtube.java deleted file mode 100644 index 8a429d32f..000000000 --- a/app/src/main/java/com/fongmi/android/tv/player/source/Youtube.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.fongmi.android.tv.player.source; - -import com.fongmi.android.tv.utils.Sniffer; -import com.github.catvod.net.OkHttp; -import com.google.common.net.HttpHeaders; - -import java.util.Arrays; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import okhttp3.Headers; - -public class Youtube { - - private static class Loader { - static volatile Youtube INSTANCE = new Youtube(); - } - - public static Youtube get() { - return Loader.INSTANCE; - } - - public String fetch(String url) { - try { - String result = OkHttp.newCall(url, Headers.of(HttpHeaders.USER_AGENT, Sniffer.CHROME)).execute().body().string(); - Pattern pattern = Pattern.compile("hlsManifestUrl\\S*?(https\\S*?\\.m3u8)"); - Matcher matcher = pattern.matcher(result); - if (!matcher.find()) return ""; - String stable = matcher.group(1); - result = OkHttp.newCall(stable, Headers.of(HttpHeaders.USER_AGENT, Sniffer.CHROME)).execute().body().string(); - String quality = find(result); - return quality.isEmpty() ? url : quality; - } catch (Exception e) { - e.printStackTrace(); - return url; - } - } - - private String find(String result) { - String url = ""; - List items = Arrays.asList("301", "300", "96", "95", "94"); - for (String item : items) if (!(url = find(result, "https:/.*/" + item + "/.*index.m3u8")).isEmpty()) break; - return url; - } - - private String find(String result, String rule) { - Pattern pattern = Pattern.compile(rule); - Matcher matcher = pattern.matcher(result); - if (matcher.find()) return matcher.group(); - return ""; - } -} diff --git a/app/src/main/java/com/fongmi/android/tv/player/source/ZLive.java b/app/src/main/java/com/fongmi/android/tv/player/source/ZLive.java deleted file mode 100644 index 109771445..000000000 --- a/app/src/main/java/com/fongmi/android/tv/player/source/ZLive.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.fongmi.android.tv.player.source; - -import com.fongmi.android.tv.utils.FileUtil; -import com.github.catvod.net.OkHttp; - -public class ZLive { - - private final String BASE = "http://127.0.0.1:6677/stream/"; - private boolean init; - - private static class Loader { - static volatile ZLive INSTANCE = new ZLive(); - } - - public static ZLive get() { - return Loader.INSTANCE; - } - - public void init() { - //com.east.android.zlive.ZLive.INSTANCE.OnLiveStart(6677); - //init = true; - } - - private String getLive(String uuid) { - return BASE + "live?uuid=" + uuid; - } - - private String getOpen(String uuid) { - return BASE + "open?uuid=" + uuid; - } - - public String fetch(String url) { - try { - if (!init) init(); - String[] split = url.split("/"); - String server = split[2]; - String uuid = split[3]; - String param = "&group=5850&mac=00:00:00:00:00:00&dir="; - String result = getLive(uuid) + "&server=" + server + param + FileUtil.getCachePath(); - OkHttp.newCall(getOpen(uuid)).execute(); - return result; - } catch (Exception e) { - e.printStackTrace(); - return url; - } - } - - public void stop() { - try { - //if (init) com.east.android.zlive.ZLive.INSTANCE.OnLiveStop(); - //init = false; - } catch (Throwable e) { - e.printStackTrace(); - } - } -} diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java index 65e9b8953..cb821dc0b 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java @@ -50,7 +50,7 @@ import com.fongmi.android.tv.event.RefreshEvent; import com.fongmi.android.tv.model.SiteViewModel; import com.fongmi.android.tv.player.ExoUtil; import com.fongmi.android.tv.player.Players; -import com.fongmi.android.tv.player.source.Source; +import com.fongmi.android.tv.player.extractor.Source; import com.fongmi.android.tv.receiver.PiPReceiver; import com.fongmi.android.tv.service.PlaybackService; import com.fongmi.android.tv.ui.adapter.EpisodeAdapter; diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java index b2a29e039..944bc8a79 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java @@ -36,7 +36,7 @@ import com.fongmi.android.tv.impl.LiveCallback; import com.fongmi.android.tv.impl.PassCallback; import com.fongmi.android.tv.model.LiveViewModel; import com.fongmi.android.tv.player.Players; -import com.fongmi.android.tv.player.source.Source; +import com.fongmi.android.tv.player.extractor.Source; import com.fongmi.android.tv.receiver.PiPReceiver; import com.fongmi.android.tv.service.PlaybackService; import com.fongmi.android.tv.ui.adapter.ChannelAdapter; diff --git a/jianpian/src/main/java/com/p2p/P2PClass.java b/jianpian/src/main/java/com/p2p/P2PClass.java index 396dba577..94e3b78c1 100644 --- a/jianpian/src/main/java/com/p2p/P2PClass.java +++ b/jianpian/src/main/java/com/p2p/P2PClass.java @@ -24,6 +24,14 @@ public class P2PClass { } } + public int P2Pdoxstarthttpd(byte[] bArr, byte[] bArr2) { + return doxstarthttpd(bArr, bArr2); + } + + public int P2Pdoxendhttpd() { + return doxendhttpd(); + } + public void P2Pdoxstart(byte[] bArr) { doxstart(bArr); } @@ -40,17 +48,15 @@ public class P2PClass { doxdel(bArr); } - public int P2Pdoxstarthttpd(byte[] bArr, byte[] bArr2) { - return doxstarthttpd(bArr, bArr2); - } + private native int doxstarthttpd(byte[] bArr, byte[] bArr2); - private native int doxadd(byte[] bArr); + private native int doxendhttpd(); - private native int doxdel(byte[] bArr); + private native int doxstart(byte[] bArr); - private native int doxpause(byte[] bArr); + private native int doxadd(byte[] bArr); - private native int doxstart(byte[] bArr); + private native int doxpause(byte[] bArr); - private native int doxstarthttpd(byte[] bArr, byte[] bArr2); + private native int doxdel(byte[] bArr); }