mirror of https://github.com/FongMi/TV.git
parent
ce4efbb456
commit
43284c97ee
@ -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<Extractor> 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(); |
||||
} |
||||
} |
||||
@ -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() { |
||||
} |
||||
} |
||||
@ -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<String> 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() { |
||||
} |
||||
} |
||||
@ -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() { |
||||
} |
||||
} |
||||
@ -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; |
||||
} |
||||
} |
||||
} |
||||
@ -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(); |
||||
} |
||||
} |
||||
@ -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<String> 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 ""; |
||||
} |
||||
} |
||||
@ -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(); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue