Merge branch 'FongMi:main' into main

This commit is contained in:
2023-12-15 13:25:45 +08:00 committed by GitHub
commit e69499f83b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 441 additions and 566 deletions

View File

@ -34,11 +34,12 @@ import com.github.catvod.net.OkHttp;
import com.github.catvod.net.OkResult;
import com.github.catvod.spider.Init;
import com.github.catvod.spider.Proxy;
import com.github.catvod.utils.MultiThreadedDownloader;
import com.github.catvod.utils.Notify;
import com.github.catvod.utils.Path;
import com.github.catvod.utils.ProxyVideo;
import com.github.catvod.utils.QRCode;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.ResUtil;
import com.github.catvod.utils.Util;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@ -67,10 +68,9 @@ public class AliYun {
private final List<String> tempIds;
private final ReentrantLock lock;
private final Cache cache;
private ScheduledExecutorService service;
private AlertDialog dialog;
private String refreshToken;
private AlertDialog dialog;
private Share share;
private static class Loader {
@ -101,7 +101,7 @@ public class AliYun {
public HashMap<String, String> getHeader() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
headers.put("Referer", "https://www.aliyundrive.com/");
return headers;
}
@ -155,7 +155,7 @@ public class AliYun {
private boolean isManyRequest(String result) {
if (!result.contains("Too Many Requests")) return false;
Utils.notify("洗洗睡吧Too Many Requests。");
Notify.show("洗洗睡吧Too Many Requests。");
cache.getOAuth().clean();
return true;
}
@ -173,7 +173,7 @@ public class AliYun {
param.addProperty("share_pwd", "");
String json = post("v2/share_link/get_share_token", param);
share = Share.objectFrom(json).setShareId(shareId).setTime();
if (share.getShareToken().isEmpty()) Utils.notify("來晚啦,該分享已失效。");
if (share.getShareToken().isEmpty()) Notify.show("來晚啦,該分享已失效。");
}
private boolean refreshAccessToken() {
@ -278,7 +278,7 @@ public class AliYun {
folders.add(file);
} else if (file.getCategory().equals("video") || file.getCategory().equals("audio")) {
files.add(file.parent(parent.getName()));
} else if (Utils.isSub(file.getExt())) {
} else if (Util.isSub(file.getExt())) {
subs.add(file);
}
}
@ -299,17 +299,17 @@ public class AliYun {
private void pair(String name1, List<Item> items, List<Item> subs) {
for (Item item : items) {
String name2 = Utils.removeExt(item.getName()).toLowerCase();
String name2 = Util.removeExt(item.getName()).toLowerCase();
if (name1.contains(name2) || name2.contains(name1)) subs.add(item);
}
}
private String findSubs(String name1, List<Item> items) {
List<Item> subs = new ArrayList<>();
pair(Utils.removeExt(name1).toLowerCase(), items, subs);
pair(Util.removeExt(name1).toLowerCase(), items, subs);
if (subs.isEmpty()) subs.addAll(items);
StringBuilder sb = new StringBuilder();
for (Item sub : subs) sb.append("+").append(Utils.removeExt(sub.getName())).append("@@@").append(sub.getExt()).append("@@@").append(sub.getFileId());
for (Item sub : subs) sb.append("+").append(Util.removeExt(sub.getName())).append("@@@").append(sub.getExt()).append("@@@").append(sub.getFileId());
return sb.toString();
}
@ -328,7 +328,7 @@ public class AliYun {
public String getShareDownloadUrl(String shareId, String fileId) {
try {
if (shareDownloadMap.containsKey(fileId) && shareDownloadMap.get(fileId) != null && !isExpire(shareDownloadMap.get(fileId), 600)) return shareDownloadMap.get(fileId);
if (shareDownloadMap.containsKey(fileId) && shareDownloadMap.get(fileId) != null && !isExpire(shareDownloadMap.get(fileId))) return shareDownloadMap.get(fileId);
refreshShareToken(shareId);
SpiderDebug.log("getShareDownloadUrl..." + fileId);
JsonObject param = new JsonObject();
@ -347,7 +347,7 @@ public class AliYun {
public String getDownloadUrl(String shareId, String fileId) {
try {
if (downloadMap.containsKey(fileId) && downloadMap.get(fileId) != null && !isExpire(downloadMap.get(fileId), 900)) return downloadMap.get(fileId);
if (downloadMap.containsKey(fileId) && downloadMap.get(fileId) != null && !isExpire(downloadMap.get(fileId))) return downloadMap.get(fileId);
refreshShareToken(shareId);
SpiderDebug.log("getDownloadUrl..." + fileId);
tempIds.add(0, copy(shareId, fileId));
@ -449,7 +449,11 @@ public class AliYun {
}
private String proxyVideoUrl(String cate, String shareId, String fileId) {
return String.format(Proxy.getUrl() + "?do=ali&type=video&cate=%s&shareId=%s&fileId=%s", cate, shareId, fileId);
int thread = 1;
String url = String.format(Proxy.getUrl() + "?do=ali&type=video&cate=%s&shareId=%s&fileId=%s", cate, shareId, fileId);
if ("open".equals(cate)) thread = 10;
if ("share".equals(cate)) thread = 10;
return thread == 1 ? url : ProxyVideo.url(url, thread);
}
private String proxyVideoUrl(String cate, String shareId, String fileId, String templateId) {
@ -460,10 +464,10 @@ public class AliYun {
return String.format(Proxy.getUrl() + "?do=ali&type=video&cate=%s&shareId=%s&fileId=%s&templateId=%s&mediaId=%s", cate, shareId, fileId, templateId, mediaId);
}
private static boolean isExpire(String url, int time) {
private static boolean isExpire(String url) {
String expires = new UrlQuerySanitizer(url).getValue("x-oss-expires");
if (TextUtils.isEmpty(expires)) return false;
return Long.parseLong(expires) - getTimeStamp() <= time / 60;
return Long.parseLong(expires) - getTimeStamp() <= 60;
}
private static long getTimeStamp() {
@ -477,22 +481,19 @@ public class AliYun {
String fileId = params.get("fileId");
String cate = params.get("cate");
String downloadUrl = "";
int thread = 1;
if ("preview".equals(cate)) {
return previewProxy(shareId, fileId, templateId);
}
if ("open".equals(cate)) {
thread = 10;
downloadUrl = getDownloadUrl(shareId, fileId);
} else if ("share".equals(cate)) {
thread = 10;
downloadUrl = getShareDownloadUrl(shareId, fileId);
} else if ("m3u8".equals(cate)) {
lock.lock();
String mediaUrl = m3u8MediaMap.get(fileId).get(mediaId);
if (isExpire(mediaUrl, 900)) {
if (isExpire(mediaUrl)) {
getM3u8(shareId, fileId, templateId);
mediaUrl = m3u8MediaMap.get(fileId).get(mediaId);
}
@ -512,16 +513,11 @@ public class AliYun {
headers.remove("templateId");
headers.remove("remote-addr");
headers.remove("http-client-ip");
if (thread == 1) {
return new Object[]{ProxyVideo.proxy(downloadUrl, headers)};
} else {
return new Object[]{new MultiThreadedDownloader(downloadUrl, headers, thread).start()};
}
}
private Object[] previewProxy(String shareId, String fileId, String templateId) {
String m3u8 = getM3u8(shareId, fileId, templateId);
return new Object[]{200, "application/vnd.apple.mpegurl", new ByteArrayInputStream(m3u8.getBytes())};
return new Object[]{200, "application/vnd.apple.mpegurl", new ByteArrayInputStream(getM3u8(shareId, fileId, templateId).getBytes())};
}
private String getM3u8Url(String shareId, String fileId, String templateId) {
@ -537,7 +533,7 @@ public class AliYun {
private String getM3u8(String shareId, String fileId, String templateId) {
String m3u8Url = getM3u8Url(shareId, fileId, templateId);
String m3u8 = OkHttp.string(m3u8Url, getHeader());
String[] m3u8Arr = m3u8.split("\\\n");
String[] m3u8Arr = m3u8.split("\n");
List<String> listM3u8 = new ArrayList<>();
Map<String, String> media = new HashMap<>();
String site = m3u8Url.substring(0, m3u8Url.lastIndexOf("/")) + "/";
@ -545,8 +541,8 @@ public class AliYun {
for (String oneLine : m3u8Arr) {
String thisOne = oneLine;
if (oneLine.contains("x-oss-expires")) {
media.put("" + mediaId, site + thisOne);
thisOne = proxyVideoUrl("m3u8", shareId, fileId, templateId, "" + mediaId);
media.put(String.valueOf(mediaId), site + thisOne);
thisOne = proxyVideoUrl("m3u8", shareId, fileId, templateId, String.valueOf(mediaId));
mediaId++;
}
listM3u8.add(thisOne);
@ -559,7 +555,7 @@ public class AliYun {
String fileId = params.get("fileId");
String shareId = params.get("shareId");
Response res = OkHttp.newCall(getDownloadUrl(shareId, fileId), getHeaderAuth());
byte[] body = Utils.toUtf8(res.body().bytes());
byte[] body = Util.toUtf8(res.body().bytes());
Object[] result = new Object[3];
result[0] = 200;
result[1] = "application/octet-stream";
@ -573,9 +569,10 @@ public class AliYun {
private void showInput() {
try {
int margin = ResUtil.dp2px(16);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(Utils.dp2px(16), Utils.dp2px(16), Utils.dp2px(16), Utils.dp2px(16));
FrameLayout frame = new FrameLayout(Init.context());
params.setMargins(margin, margin, margin, margin);
EditText input = new EditText(Init.context());
frame.addView(input, params);
dialog = new AlertDialog.Builder(Init.getActivity()).setTitle("請輸入Token").setView(frame).setNeutralButton("QRCode", (dialog, which) -> onNeutral()).setNegativeButton(android.R.string.cancel, null).setPositiveButton(android.R.string.ok, (dialog, which) -> onPositive(input.getText().toString())).show();
@ -617,16 +614,17 @@ public class AliYun {
private void showQRCode(Data data) {
try {
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(Utils.dp2px(240), Utils.dp2px(240));
int size = ResUtil.dp2px(240);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(size, size);
ImageView image = new ImageView(Init.context());
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
image.setImageBitmap(QRCode.getBitmap(data.getCodeContent(), 240, 2));
image.setImageBitmap(QRCode.getBitmap(data.getCodeContent(), size, 2));
FrameLayout frame = new FrameLayout(Init.context());
params.gravity = Gravity.CENTER;
frame.addView(image, params);
dialog = new AlertDialog.Builder(Init.getActivity()).setView(frame).setOnCancelListener(this::dismiss).setOnDismissListener(this::dismiss).show();
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Utils.notify("請使用阿里雲盤 App 掃描二維碼");
Notify.show("請使用阿里雲盤 App 掃描二維碼");
} catch (Exception ignored) {
}
}
@ -643,7 +641,7 @@ public class AliYun {
private void setToken(String value) {
cache.getUser().setRefreshToken(value);
SpiderDebug.log("Token:" + value);
Utils.notify("Token:" + value);
Notify.show("Token:" + value);
refreshAccessToken();
stopService();
}

View File

@ -2,7 +2,7 @@ package com.github.catvod.bean.ali;
import android.text.TextUtils;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
@ -70,7 +70,7 @@ public class Item implements Comparable<Item> {
}
public String getSize() {
return size == 0 ? "" : "[" + Utils.getSize(size) + "]";
return size == 0 ? "" : "[" + Util.getSize(size) + "]";
}
public String getParent() {
@ -87,7 +87,7 @@ public class Item implements Comparable<Item> {
}
public String getSortName() {
return TextUtils.join(" ", Arrays.asList(getParent(), Utils.getDigit(getName()))).trim();
return TextUtils.join(" ", Arrays.asList(getParent(), Util.getDigit(getName()))).trim();
}
@Override

View File

@ -6,7 +6,7 @@ import android.text.TextUtils;
import com.github.catvod.bean.Class;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Image;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
@ -164,7 +164,7 @@ public class Drive {
public HashMap<String, String> getHeader() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
if (!getToken().isEmpty()) headers.put("Authorization", token);
return headers;
}

View File

@ -3,7 +3,7 @@ package com.github.catvod.bean.alist;
import android.text.TextUtils;
import com.github.catvod.bean.Vod;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
@ -110,7 +110,7 @@ public class Item {
}
public String getExt() {
return Utils.getExt(getName());
return Util.getExt(getName());
}
public String getVodId(String id) {
@ -122,7 +122,7 @@ public class Item {
}
public String getRemark() {
return Utils.getSize(getSize());
return Util.getSize(getSize());
}
public Vod getVod(String id, String pic) {

View File

@ -3,7 +3,7 @@ package com.github.catvod.bean.bili;
import android.net.Uri;
import android.text.TextUtils;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.annotations.SerializedName;
import java.net.URLEncoder;
@ -40,8 +40,8 @@ public class Wbi {
StringBuilder sb = new StringBuilder();
params.put("wts", System.currentTimeMillis() / 1000);
for (String key : params.keySet()) sb.append(key).append("=").append(URLEncoder.encode(params.get(key).toString())).append("&");
String param = Utils.substring(sb.toString());
String wbiSign = Utils.MD5(param + mixinKey);
String param = Util.substring(sb.toString());
String wbiSign = Util.MD5(param + mixinKey);
return param + "&w_rid=" + wbiSign;
}
}

View File

@ -3,7 +3,7 @@ package com.github.catvod.bean.jianpian;
import android.text.TextUtils;
import com.github.catvod.bean.Vod;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.annotations.SerializedName;
import java.util.Collections;
@ -91,13 +91,13 @@ public class Data {
public String getValues(List<Value> items, boolean link) {
StringBuilder sb = new StringBuilder();
for (Value value : items) sb.append(value.getValue(link)).append(" ");
return Utils.substring(sb.toString());
return Util.substring(sb.toString());
}
public String getPlayUrl() {
StringBuilder sb = new StringBuilder();
for (BtboDown value : getBtboDownlist()) sb.append(value.getVal()).append("#");
return Utils.substring(sb.toString());
return Util.substring(sb.toString());
}
public static class Value {

View File

@ -5,7 +5,7 @@ import android.text.TextUtils;
import com.github.catvod.bean.Class;
import com.github.catvod.bean.Vod;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.thegrizzlylabs.sardineandroid.DavResource;
@ -88,7 +88,7 @@ public class Drive {
}
public Vod vod(DavResource item, String vodPic) {
return new Vod(getName() + item.getPath(), item.getName(), vodPic, Utils.getSize(item.getContentLength()), item.isDirectory());
return new Vod(getName() + item.getPath(), item.getName(), vodPic, Util.getSize(item.getContentLength()), item.isDirectory());
}
@Override

View File

@ -1,6 +1,6 @@
package com.github.catvod.js;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Notify;
import com.whl.quickjs.wrapper.JSMethod;
import com.whl.quickjs.wrapper.QuickJSContext;
@ -14,6 +14,6 @@ public class Method {
@JSMethod
public void showToast(String msg) {
Utils.notify(msg);
Notify.show(msg);
}
}

View File

@ -2,7 +2,7 @@ package com.github.catvod.net;
import android.text.TextUtils;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import java.io.IOException;
import java.util.Map;
@ -65,7 +65,7 @@ class OkRequest {
private void setParams() {
url = url + "?";
for (String key : params.keySet()) url = url.concat(key + "=" + params.get(key) + "&");
url = Utils.substring(url);
url = Util.substring(url);
}
public OkResult execute(OkHttpClient client) {

View File

@ -1,6 +1,6 @@
package com.github.catvod.net;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import java.io.IOException;
import java.util.zip.Inflater;
@ -42,7 +42,7 @@ public class OkhttpInterceptor implements Interceptor {
private Request getRequest(Chain chain) {
Request request = chain.request();
if (request.url().host().equals("gitcode.net")) return request.newBuilder().addHeader("User-Agent", Utils.CHROME).build();
if (request.url().host().equals("gitcode.net")) return request.newBuilder().addHeader("User-Agent", Util.CHROME).build();
return request;
}
}

View File

@ -14,7 +14,7 @@ import com.github.catvod.bean.alist.Sorter;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONObject;
import org.jsoup.Jsoup;
@ -225,7 +225,7 @@ public class AList extends Spider {
private String findSubs(String path, List<Item> items) {
StringBuilder sb = new StringBuilder();
for (Item item : items) if (Utils.isSub(item.getExt())) sb.append("~~~").append(item.getName()).append("@@@").append(item.getExt()).append("@@@").append(item.getVodId(path));
for (Item item : items) if (Util.isSub(item.getExt())) sb.append("~~~").append(item.getName()).append("@@@").append(item.getExt()).append("@@@").append(item.getVodId(path));
return sb.toString();
}
@ -265,7 +265,7 @@ public class AList extends Spider {
String[] splits = a.text().split("#");
if (!splits[0].contains("/")) continue;
int index = splits[0].lastIndexOf("/");
boolean file = Utils.isMedia(splits[0]);
boolean file = Util.isMedia(splits[0]);
Item item = new Item();
item.setType(file ? 0 : 1);
item.setThumb(splits.length > 3 ? splits[4] : "");

View File

@ -6,7 +6,7 @@ import android.text.TextUtils;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONArray;
import org.json.JSONException;
@ -310,7 +310,7 @@ public class AppYsV2 extends Spider {
@Override
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
if (flag.contains("fanqie") && Utils.isVideoFormat(id)) {
if (flag.contains("fanqie") && Util.isVideoFormat(id)) {
JSONObject result = new JSONObject();
result.put("parse", 0);
result.put("playUrl", "");
@ -323,7 +323,7 @@ public class AppYsV2 extends Spider {
JSONObject result = getFinalVideo(flag, parseUrls, id);
if (result != null) return result.toString();
}
if (Utils.isVideoFormat(id)) {
if (Util.isVideoFormat(id)) {
JSONObject result = new JSONObject();
result.put("parse", 0);
result.put("playUrl", "");
@ -735,7 +735,7 @@ public class AppYsV2 extends Spider {
@Override
public boolean isVideoFormat(String url) {
return Utils.isVideoFormat(url);
return Util.isVideoFormat(url);
}
private String getApiUrl() {
@ -759,11 +759,11 @@ public class AppYsV2 extends Spider {
return null;
}
if (url.equals(input)) {
if (Utils.isVip(url) || !Utils.isVideoFormat(url)) {
if (Util.isVip(url) || !Util.isVideoFormat(url)) {
return null;
}
}
if (Utils.isBlackVodUrl(url)) {
if (Util.isBlackVodUrl(url)) {
return null;
}
JSONObject headers = new JSONObject();
@ -813,7 +813,7 @@ public class AppYsV2 extends Spider {
headers.put("User-Agent", " Mozilla/5.0");
} else if (input.contains("bilibili")) {
headers.put("Referer", " https://www.bilibili.com/");
headers.put("User-Agent", " " + Utils.CHROME);
headers.put("User-Agent", " " + Util.CHROME);
}
return headers;
}

View File

@ -16,7 +16,7 @@ import com.github.catvod.bean.bili.Resp;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Path;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@ -50,7 +50,7 @@ public class Bili extends Spider {
private static Map<String, String> getHeader() {
Map<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
if (cookie != null) headers.put("cookie", cookie);
headers.put("Referer", "https://www.bilibili.com");
return headers;

View File

@ -8,7 +8,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -31,8 +31,8 @@ public class Dm84 extends Spider {
private HashMap<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("Accept", Utils.ACCEPT);
headers.put("User-Agent", Util.CHROME);
headers.put("Accept", Util.ACCEPT);
return headers;
}

View File

@ -7,7 +7,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.JsonParser;
import org.json.JSONArray;
@ -123,7 +123,7 @@ public class Douban extends Spider {
private String getPic(JSONObject item) {
try {
return item.getJSONObject("pic").optString("normal") + "@Referer=https://api.douban.com/@User-Agent=" + Utils.CHROME;
return item.getJSONObject("pic").optString("normal") + "@Referer=https://api.douban.com/@User-Agent=" + Util.CHROME;
} catch (Exception e) {
return "";
}
@ -133,7 +133,7 @@ public class Douban extends Spider {
try {
StringBuilder tags = new StringBuilder();
for (String key : extend.keySet()) if (!key.equals("sort")) tags.append(extend.get(key)).append(",");
return Utils.substring(tags.toString());
return Util.substring(tags.toString());
} catch (Exception e) {
return "";
}

View File

@ -8,7 +8,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONObject;
import org.jsoup.Jsoup;
@ -34,7 +34,7 @@ public class Duanju extends Spider {
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
return header;
}

View File

@ -9,7 +9,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -89,7 +89,7 @@ public class Eighteen extends Spider {
@Override
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
HashMap<String, String> result = new HashMap<>();
Utils.loadWebView(url + id, getClient(result));
Util.loadWebView(url + id, getClient(result));
while (result.isEmpty()) SystemClock.sleep(10);
return Result.get().url(result.get("url")).string();
}

View File

@ -6,7 +6,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONObject;
import org.jsoup.Jsoup;
@ -24,7 +24,7 @@ public class Hanime extends Spider {
private HashMap<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
return headers;
}

View File

@ -5,7 +5,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -26,7 +26,7 @@ public class Jable extends Spider {
private HashMap<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
return headers;
}
@ -79,7 +79,7 @@ public class Jable extends Spider {
vod.setVodYear(year.replace("上市於 ", ""));
vod.setVodName(name);
vod.setVodPlayFrom("Jable");
vod.setVodPlayUrl("播放$" + Utils.getVar(doc.html(), "hlsUrl"));
vod.setVodPlayUrl("播放$" + Util.getVar(doc.html(), "hlsUrl"));
return Result.string(vod);
}

View File

@ -0,0 +1,170 @@
package com.github.catvod.spider;
import android.content.Context;
import android.text.TextUtils;
import com.github.catvod.bean.Class;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Util;
import org.json.JSONArray;
import org.json.JSONObject;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @author Qile
*/
public class JustLive extends Spider {
private String siteUrl = "http://live.yj1211.work";
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Util.CHROME);
return header;
}
@Override
public void init(Context context, String extend) throws Exception {
if (!extend.isEmpty()) siteUrl = extend;
}
@Override
public String homeContent(boolean filter) throws Exception {
List<Class> classes = new ArrayList<>();
List<String> typeIds = Arrays.asList("网游", "手游", "单机", "娱乐", "其他");
List<String> typeNames = Arrays.asList("网游", "手游", "单机", "娱乐", "其他");
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
String f = "{\"网游\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"英雄联盟\", \"v\": \"英雄联盟\"}, {\"n\": \"无畏契约\", \"v\": \"无畏契约\"}, {\"n\": \"CS:GO\", \"v\": \"CS:GO\"}, {\"n\": \"APEX英雄\", \"v\": \"APEX英雄\"}, {\"n\": \"永劫无间\", \"v\": \"永劫无间\"}, {\"n\": \"穿越火线\", \"v\": \"穿越火线\"}, {\"n\": \"命运方舟\", \"v\": \"命运方舟\"}, {\"n\": \"DOTA2\", \"v\": \"DOTA2\"}, {\"n\": \"吃鸡行动\", \"v\": \"吃鸡行动\"}, {\"n\": \"逃离塔科夫\", \"v\": \"逃离塔科夫\"}, {\"n\": \"传奇\", \"v\": \"传奇\"}, {\"n\": \"DNF\", \"v\": \"DNF\"}, {\"n\": \"卡拉彼丘\", \"v\": \"卡拉彼丘\"}, {\"n\": \"幕后高手\", \"v\": \"幕后高手\"}, {\"n\": \"生死狙击2\", \"v\": \"生死狙击2\"}, {\"n\": \"洛奇英雄传\", \"v\": \"洛奇英雄传\"}, {\"n\": \"最终幻想14\", \"v\": \"最终幻想14\"}, {\"n\": \"重生边缘\", \"v\": \"重生边缘\"}, {\"n\": \"星际战甲\", \"v\": \"星际战甲\"}, {\"n\": \"梦三国\", \"v\": \"梦三国\"}, {\"n\": \"英魂之刃\", \"v\": \"英魂之刃\"}, {\"n\": \"剑网3\", \"v\": \"剑网3\"}]}], \"手游\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"王者荣耀\", \"v\": \"王者荣耀\"}, {\"n\": \"和平精英\", \"v\": \"和平精英\"}, {\"n\": \"原神\", \"v\": \"原神\"}, {\"n\": \"崩坏:星穹铁道\", \"v\": \"崩坏:星穹铁道\"}, {\"n\": \"第五人格\", \"v\": \"第五人格\"}, {\"n\": \"LOL手游\", \"v\": \"LOL手游\"}, {\"n\": \"明日方舟\", \"v\": \"明日方舟\"}, {\"n\": \"黎明觉醒:生机\", \"v\": \"黎明觉醒:生机\"}, {\"n\": \"蛋仔派对\", \"v\": \"蛋仔派对\"}, {\"n\": \"冒险岛手游\", \"v\": \"冒险岛手游\"}, {\"n\": \"闪耀!优俊少女\", \"v\": \"闪耀!优俊少女\"}, {\"n\": \"斯露德\", \"v\": \"斯露德\"}, {\"n\": \"千年之旅\", \"v\": \"千年之旅\"}, {\"n\": \"白夜极光\", \"v\": \"白夜极光\"}, {\"n\": \"逆水寒手游\", \"v\": \"逆水寒手游\"}, {\"n\": \"率土之滨\", \"v\": \"率土之滨\"}, {\"n\": \"月圆之夜\", \"v\": \"月圆之夜\"}]}],\"单机\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"主机游戏\", \"v\": \"主机游戏\"}, {\"n\": \"我的世界\", \"v\": \"我的世界\"}, {\"n\": \"独立游戏\", \"v\": \"独立游戏\"}, {\"n\": \"怀旧游戏\", \"v\": \"怀旧游戏\"}, {\"n\": \"猛兽派对\", \"v\": \"猛兽派对\"}, {\"n\": \"星空\", \"v\": \"星空\"}, {\"n\": \"塞尔达传说\", \"v\": \"塞尔达传说\"}, {\"n\": \"苍翼:混沌效应\", \"v\": \"苍翼:混沌效应\"}, {\"n\": \"命运2\", \"v\": \"命运2\"}, {\"n\": \"收获日3\", \"v\": \"收获日3\"}, {\"n\": \"机战佣兵VI 境界天火\", \"v\": \"机战佣兵VI 境界天火\"}, {\"n\": \"暗黑破坏神Ⅳ\", \"v\": \"暗黑破坏神Ⅳ\"}, {\"n\": \"匹诺曹的谎言\", \"v\": \"匹诺曹的谎言\"}, {\"n\": \"博德之门3\", \"v\": \"博德之门3\"}, {\"n\": \"绝世好武功\", \"v\": \"绝世好武功\"}, {\"n\": \"恐怖游戏\", \"v\": \"恐怖游戏\"}, {\"n\": \"Dark and Darker\", \"v\": \"Dark and Darker\"}, {\"n\": \"Warlander\", \"v\": \"Warlander\"}, {\"n\": \"FORZA 极限竞速\", \"v\": \"FORZA 极限竞速\"}, {\"n\": \"边境\", \"v\": \"边境\"}, {\"n\": \"生化危机\", \"v\": \"生化危机\"}]}], \"娱乐\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"聊天室\", \"v\": \"聊天室\"}, {\"n\": \"视频唱见\", \"v\": \"视频唱见\"}, {\"n\": \"萌宅领域\", \"v\": \"萌宅领域\"}, {\"n\": \"视频聊天\", \"v\": \"视频聊天\"}, {\"n\": \"舞见\", \"v\": \"舞见\"}, {\"n\": \"唱见电台\", \"v\": \"唱见电台\"}, {\"n\": \"聊天电台\", \"v\": \"聊天电台\"}, {\"n\": \"甜宠电台\", \"v\": \"甜宠电台\"}, {\"n\": \"TopStar\", \"v\": \"TopStar\"}, {\"n\": \"虚拟Singer\", \"v\": \"虚拟Singer\"}, {\"n\": \"虚拟Gamer\", \"v\": \"虚拟Gamer\"}, {\"n\": \"虚拟声优\", \"v\": \"虚拟声优\"}, {\"n\": \"虚拟日常\", \"v\": \"虚拟日常\"}, {\"n\": \"星秀\", \"v\": \"星秀\"}]}], \"其他\": [{\"key\": \"class\", \"name\": \"类型\", \"value\": [{\"n\": \"生活分享\", \"v\": \"生活分享\"}, {\"n\": \"户外\", \"v\": \"户外\"}, {\"n\": \"日常\", \"v\": \"日常\"}, {\"n\": \"情感\", \"v\": \"情感\"}, {\"n\": \"运动\", \"v\": \"运动\"}, {\"n\": \"搞笑\", \"v\": \"搞笑\"}, {\"n\": \"手工绘画\", \"v\": \"手工绘画\"}, {\"n\": \"萌宠\", \"v\": \"萌宠\"}, {\"n\": \"美食\", \"v\": \"美食\"}, {\"n\": \"时尚\", \"v\": \"时尚\"}, {\"n\": \"社科法律心理\", \"v\": \"社科法律心理\"}, {\"n\": \"人文历史\", \"v\": \"人文历史\"}, {\"n\": \"校园学习\", \"v\": \"校园学习\"}, {\"n\": \"职场·技能\", \"v\": \"职场·技能\"}, {\"n\": \"科技\", \"v\": \"科技\"}]}]}";
JSONObject filterConfig = new JSONObject(f);
String content = OkHttp.string(siteUrl + "/api/live/getRecommend?page=1&size=20", getHeader());
List<Vod> list = new ArrayList<>();
JSONArray dataArray = new JSONObject(content).getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject jsonObject = dataArray.getJSONObject(i);
String platform = jsonObject.getString("platForm");
String roomId = jsonObject.getString("roomId");
String categoryName = jsonObject.getString("categoryName");
String roomName = jsonObject.getString("roomName");
String name = categoryName + roomName;
String pic = jsonObject.getString("roomPic");
String remark = jsonObject.getString("ownerName");
String vid = "platform=" + platform + "&roomId=" + roomId;
list.add(new Vod(vid, name, pic, remark));
}
return Result.string(classes, list, filterConfig);
}
@Override
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
Map<String, String> ClassTypeMap = new HashMap<>();
ClassTypeMap.put("网游", "英雄联盟");
ClassTypeMap.put("手游", "王者荣耀");
ClassTypeMap.put("单机", "主机游戏");
ClassTypeMap.put("娱乐", "聊天室");
ClassTypeMap.put("其他", "生活分享");
String cateId = extend.get("cateId") == null ? tid : extend.get("cateId");
String classType = extend.get("class") == null ? ClassTypeMap.get(cateId) : extend.get("class");
String cateUrl = siteUrl + String.format("/api/live/getRecommendByAreaAll?areaType=%s&area=%s&page=%s", cateId, classType, pg);
String content = OkHttp.string(cateUrl, getHeader());
List<Vod> list = new ArrayList<>();
JSONArray dataArray = new JSONObject(content).getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject jsonObject = dataArray.getJSONObject(i);
String platform = jsonObject.getString("platForm");
String roomId = jsonObject.getString("roomId");
String categoryName = jsonObject.getString("categoryName");
String name = jsonObject.getString("roomName");
String pic = jsonObject.getString("roomPic");
String remark = jsonObject.getString("ownerName");
remark = remark + "-" + categoryName;
String vid = "platform=" + platform + "&roomId=" + roomId;
list.add(new Vod(vid, name, pic, remark));
}
return Result.string(list);
}
@Override
public String detailContent(List<String> ids) throws Exception {
String getRoomInfo = siteUrl + "/api/live/getRoomInfo?" + ids.get(0);
String getRealUrl = siteUrl + "/api/live/getRealUrlMultiSource?" + ids.get(0);
String content = OkHttp.string(getRealUrl, getHeader());
String content1 = OkHttp.string(getRoomInfo, getHeader());
JSONObject dataObject = new JSONObject(content).getJSONObject("data");
List<String> lineNames = new ArrayList<>();
List<String> vodItems = new ArrayList<>();
Iterator<String> keys = dataObject.keys();
while (keys.hasNext()) {
String key = keys.next();
if (key.startsWith("线路")) lineNames.add(key);
}
Collections.sort(lineNames, (line1, line2) -> {
int num1 = Integer.parseInt(line1.substring(2));
int num2 = Integer.parseInt(line2.substring(2));
return Integer.compare(num1, num2);
});
for (String lineName : lineNames) {
JSONArray lineArray = dataObject.getJSONArray(lineName);
List<String> episodeItems = new ArrayList<>();
for (int i = 0; i < lineArray.length(); i++) {
JSONObject item = lineArray.getJSONObject(i);
String qualityName = item.getString("qualityName");
String playUrl = item.getString("playUrl");
episodeItems.add(qualityName + "$" + playUrl);
}
vodItems.add(TextUtils.join("#", episodeItems));
}
String vod_play_from = TextUtils.join("$$$", lineNames);
String vod_play_urls = TextUtils.join("$$$", vodItems);
JSONObject data = new JSONObject(content1).getJSONObject("data");
Vod vod = new Vod();
vod.setVodId(ids.get(0));
vod.setVodPic(data.getString("roomPic"));
vod.setVodName(data.getString("roomName"));
vod.setVodArea(data.getString("platForm").replace("douyu", "斗鱼").replace("huya", "虎牙").replace("bilibili", "哔哩哔哩").replace("douyin", "抖音").replace("cc", "网易CC"));
vod.setVodActor(data.getString("ownerName"));
vod.setVodRemarks("在线" + data.getInt("online") + "");
vod.setVodContent(getRealUrl);
vod.setVodDirector("Qile");
vod.setTypeName(data.getString("categoryName"));
vod.setVodPlayFrom(vod_play_from);
vod.setVodPlayUrl(vod_play_urls);
return Result.string(vod);
}
@Override
public String searchContent(String key, boolean quick) throws Exception {
String searchUrl = siteUrl + "/api/live/search?platform=all&keyWords=" + URLEncoder.encode(key) + "&uid=35717d71548f4ec9ab6f327cc16ad2bf";
String content = OkHttp.string(searchUrl, getHeader());
List<Vod> list = new ArrayList<>();
JSONArray dataArray = new JSONObject(content).getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject jsonObject = dataArray.getJSONObject(i);
String platform = jsonObject.optString("platform");
String roomId = jsonObject.optString("roomId");
String name = jsonObject.optString("nickName");
String pic = jsonObject.optString("headPic");
String remark = jsonObject.optString("isLive");
remark = remark.equals("1") ? "直播中" : "未开播";
String vid = "platform=" + platform + "&roomId=" + roomId;
list.add(new Vod(vid, name, pic, remark));
}
return Result.string(list);
}
@Override
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
return Result.get().url(id).header(getHeader()).string();
}
}

View File

@ -8,7 +8,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONArray;
import org.json.JSONObject;
@ -31,7 +31,7 @@ public class Kanqiu extends Spider {
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
return header;
}

View File

@ -7,7 +7,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONArray;
import org.json.JSONObject;
@ -29,7 +29,7 @@ public class Kugou extends Spider {
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
return header;
}

View File

@ -10,7 +10,7 @@ import com.github.catvod.bean.Sub;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.utils.Image;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import java.io.File;
import java.text.SimpleDateFormat;
@ -55,7 +55,7 @@ public class Local extends Spider {
for (File file : files) {
if (file.getName().startsWith(".")) continue;
if (file.isDirectory()) folders.add(create(file));
else if (Utils.isMedia(file.getName())) media.add(create(file));
else if (Util.isMedia(file.getName())) media.add(create(file));
}
items.addAll(folders);
items.addAll(media);
@ -109,8 +109,8 @@ public class Local extends Spider {
if (file.getParentFile() == null) return Collections.emptyList();
List<Sub> subs = new ArrayList<>();
for (File f : file.getParentFile().listFiles()) {
String ext = Utils.getExt(f.getName());
if (Utils.isSub(ext)) subs.add(Sub.create().name(Utils.removeExt(f.getName())).ext(ext).url("file://" + f.getAbsolutePath()));
String ext = Util.getExt(f.getName());
if (Util.isSub(ext)) subs.add(Sub.create().name(Util.removeExt(f.getName())).ext(ext).url("file://" + f.getAbsolutePath()));
}
return subs;
}

View File

@ -13,8 +13,9 @@ import com.github.catvod.bean.market.Item;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.FileUtil;
import com.github.catvod.utils.Notify;
import com.github.catvod.utils.Path;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import java.io.BufferedInputStream;
import java.io.File;
@ -89,11 +90,11 @@ public class Market extends Spider {
download(file, response.body().byteStream(), Double.parseDouble(response.header("Content-Length", "1")));
if (file.getName().endsWith(".zip")) FileUtil.unzip(file, Path.download());
if (file.getName().endsWith(".apk")) FileUtil.openFile(Path.chmod(file));
else Utils.notify("下載完成");
else Notify.show("下載完成");
checkCopy(url);
dismiss();
} catch (Exception e) {
Utils.notify(e.getMessage());
Notify.show(e.getMessage());
dismiss();
}
}
@ -117,7 +118,7 @@ public class Market extends Spider {
int index = data.getList().indexOf(new Item(url));
if (index == -1) continue;
String text = data.getList().get(index).getCopy();
if (!text.isEmpty()) Utils.copy(text);
if (!text.isEmpty()) Util.copy(text);
break;
}
}

View File

@ -10,7 +10,8 @@ import android.widget.FrameLayout;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.ui.ScrollTextView;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.ResUtil;
import com.github.catvod.utils.Util;
import org.json.JSONObject;
@ -69,7 +70,7 @@ public class Notice extends Spider {
view.setDuration(duration);
view.setText(sb.toString());
view.setTypeface(null, Typeface.BOLD);
view.setPadding(0, Utils.dp2px(16), 0, Utils.dp2px(16));
view.setPadding(0, ResUtil.dp2px(16), 0, ResUtil.dp2px(16));
view.setBackgroundColor(Color.argb(200, 255, 255, 255));
view.startScroll();
}
@ -77,11 +78,11 @@ public class Notice extends Spider {
private void createRoot() {
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.TOP;
Utils.addView(view, params);
Util.addView(view, params);
}
private void hide() {
Init.run(() -> Utils.removeView(view), duration * 1000);
Init.run(() -> Util.removeView(view), duration * 1000);
}
private void setColor() {

View File

@ -3,7 +3,7 @@ package com.github.catvod.spider;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONArray;
import org.json.JSONObject;
@ -24,7 +24,7 @@ public class PanSearch extends Ali {
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
return header;
}

View File

@ -3,7 +3,7 @@ package com.github.catvod.spider;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
@ -25,7 +25,7 @@ public class PanSou extends Ali {
private Map<String, String> getHeaders(String id) {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
headers.put("Referer", siteUrl + id);
headers.put("_bid", "6d14a5dd6c07980d9dc089a693805ad8");
return headers;
@ -33,7 +33,7 @@ public class PanSou extends Ali {
private Map<String, String> getHeader() {
HashMap<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
return header;
}

View File

@ -3,7 +3,6 @@ package com.github.catvod.spider;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.MultiThread;
import java.io.ByteArrayInputStream;
import java.util.Map;
@ -16,8 +15,6 @@ public class Proxy extends Spider {
switch (params.get("do")) {
case "ck":
return new Object[]{200, "text/plain; charset=utf-8", new ByteArrayInputStream("ok".getBytes("UTF-8"))};
case "multi":
return MultiThread.proxy(params);
case "ali":
return Ali.proxy(params);
case "bili":
@ -43,6 +40,11 @@ public class Proxy extends Spider {
}
}
public static int getPort() {
adjustPort();
return port;
}
public static String getUrl() {
adjustPort();
return "http://127.0.0.1:" + port + "/proxy";

View File

@ -9,7 +9,7 @@ import com.github.catvod.bean.Sub;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import java.io.File;
import java.util.ArrayList;
@ -64,12 +64,12 @@ public class Push extends Spider {
private void setHttpSub(String url, List<Sub> subs) {
List<String> vodTypes = Arrays.asList("mp4", "mkv");
List<String> subTypes = Arrays.asList("srt", "ass");
if (!vodTypes.contains(Utils.getExt(url))) return;
if (!vodTypes.contains(Util.getExt(url))) return;
for (String ext : subTypes) detectSub(url, ext, subs);
}
private void detectSub(String url, String ext, List<Sub> subs) {
url = Utils.removeExt(url).concat(".").concat(ext);
url = Util.removeExt(url).concat(".").concat(ext);
if (OkHttp.string(url).length() < 100) return;
String name = Uri.parse(url).getLastPathSegment();
subs.add(Sub.create().name(name).ext(ext).url(url));
@ -79,8 +79,8 @@ public class Push extends Spider {
File file = new File(url.replace("file://", ""));
if (file.getParentFile() == null) return;
for (File f : file.getParentFile().listFiles()) {
String ext = Utils.getExt(f.getName());
if (Utils.isSub(ext)) subs.add(Sub.create().name(Utils.removeExt(f.getName())).ext(ext).url("file://" + f.getAbsolutePath()));
String ext = Util.getExt(f.getName());
if (Util.isSub(ext)) subs.add(Sub.create().name(Util.removeExt(f.getName())).ext(ext).url("file://" + f.getAbsolutePath()));
}
}
}

View File

@ -13,7 +13,7 @@ import com.github.catvod.bean.star.Detail;
import com.github.catvod.bean.star.Query;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONObject;
import org.jsoup.Jsoup;
@ -39,7 +39,7 @@ public class Star extends Spider {
private Map<String, String> getHeader() {
Map<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
headers.put("Cookie", "userIP=127.0.0.1; aws-waf-token=");
headers.put("Referer", siteUrl);
return headers;

View File

@ -13,7 +13,7 @@ import com.github.catvod.bean.webdav.Sorter;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Image;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.thegrizzlylabs.sardineandroid.DavResource;
import java.io.IOException;
@ -46,11 +46,11 @@ public class WebDAV extends Spider {
}
private String getExt(DavResource item) {
return Utils.getExt(item.getName());
return Util.getExt(item.getName());
}
private String removeExt(DavResource item) {
return Utils.removeExt(item.getName());
return Util.removeExt(item.getName());
}
private static Drive getDrive(String name) {
@ -60,7 +60,7 @@ public class WebDAV extends Spider {
@Override
public void init(Context context, String extend) {
this.allExt = new ArrayList<>(Arrays.asList("ass", "ssa", "srt"));
this.allExt.addAll(Utils.MEDIA);
this.allExt.addAll(Util.MEDIA);
this.extend = extend;
fetchRule();
}
@ -84,7 +84,7 @@ public class WebDAV extends Spider {
List<DavResource> files = new ArrayList<>();
List<Vod> list = new ArrayList<>();
Drive drive = getDrive(key);
for (DavResource item : getList(drive, path, Utils.MEDIA)) {
for (DavResource item : getList(drive, path, Util.MEDIA)) {
if (item.isDirectory()) folders.add(item);
else files.add(item);
}
@ -110,7 +110,7 @@ public class WebDAV extends Spider {
Sorter.sort("name", "asc", parents);
List<String> playUrls = new ArrayList<>();
for (DavResource item : parents) {
if (Utils.isMedia(item.getName())) {
if (Util.isMedia(item.getName())) {
playUrls.add(item.getName() + "$" + drive.getName() + item.getPath() + findSubs(drive, item, subs));
}
}
@ -144,7 +144,7 @@ public class WebDAV extends Spider {
private List<DavResource> getSubs(List<DavResource> items) {
List<DavResource> subs = new ArrayList<>();
for (DavResource item : items) if (Utils.isSub(getExt(item))) subs.add(item);
for (DavResource item : items) if (Util.isSub(getExt(item))) subs.add(item);
return subs;
}

View File

@ -6,7 +6,7 @@ import com.github.catvod.bean.Class;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@ -36,7 +36,7 @@ public class Wogg extends Ali {
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
return header;
}

View File

@ -10,7 +10,7 @@ import com.github.catvod.bean.xpath.Rule;
import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONArray;
import org.json.JSONObject;
@ -27,7 +27,7 @@ public class XPath extends Spider {
private HashMap<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", rule.getUa().isEmpty() ? Utils.CHROME : rule.getUa());
headers.put("User-Agent", rule.getUa().isEmpty() ? Util.CHROME : rule.getUa());
return headers;
}
@ -68,7 +68,7 @@ public class XPath extends Spider {
id = rule.getHomeVodIdR(id);
String pic = vodNodes.get(i).selOne(rule.getHomeVodImg()).asString().trim();
pic = rule.getHomeVodImgR(pic);
pic = Utils.fixUrl(webUrl, pic);
pic = Util.fixUrl(webUrl, pic);
String mark = "";
if (!rule.getHomeVodMark().isEmpty()) {
try {
@ -102,7 +102,7 @@ public class XPath extends Spider {
id = rule.getCateVodIdR(id);
String pic = vodNodes.get(i).selOne(rule.getCateVodImg()).asString().trim();
pic = rule.getCateVodImgR(pic);
pic = Utils.fixUrl(webUrl, pic);
pic = Util.fixUrl(webUrl, pic);
String mark = "";
if (!rule.getCateVodMark().isEmpty()) {
try {
@ -129,7 +129,7 @@ public class XPath extends Spider {
title = rule.getDetailNameR(title);
cover = vodNode.selOne(rule.getDetailImg()).asString().trim();
cover = rule.getDetailImgR(cover);
cover = Utils.fixUrl(webUrl, cover);
cover = Util.fixUrl(webUrl, cover);
if (!rule.getDetailCate().isEmpty()) {
try {
category = vodNode.selOne(rule.getDetailCate()).asString().trim();
@ -272,7 +272,7 @@ public class XPath extends Spider {
id = rule.getSearchVodIdR(id);
String pic = vod.optString(rule.getSearchVodImg()).trim();
pic = rule.getSearchVodImgR(pic);
pic = Utils.fixUrl(webUrl, pic);
pic = Util.fixUrl(webUrl, pic);
String mark = vod.optString(rule.getSearchVodMark()).trim();
mark = rule.getSearchVodMarkR(mark);
list.add(new Vod(id, name, pic, mark));
@ -291,7 +291,7 @@ public class XPath extends Spider {
id = rule.getSearchVodIdR(id);
String pic = vodNodes.get(i).selOne(rule.getSearchVodImg()).asString().trim();
pic = rule.getSearchVodImgR(pic);
pic = Utils.fixUrl(webUrl, pic);
pic = Util.fixUrl(webUrl, pic);
String mark = "";
if (!rule.getCateVodMark().isEmpty()) {
try {
@ -314,7 +314,7 @@ public class XPath extends Spider {
@Override
public boolean isVideoFormat(String url) {
return Utils.isVideoFormat(url);
return Util.isVideoFormat(url);
}
protected String ext = null;

View File

@ -5,7 +5,7 @@ import android.text.TextUtils;
import android.util.Base64;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import com.google.gson.Gson;
import org.json.JSONException;
@ -151,7 +151,7 @@ public class XPathMac extends XPath {
}
if (videoUrl != null) {
// 適配2.0.6的調用應用內解析列表的支持, 需要配合直連分析和匹配官源解析一起使用參考cjt影視和極品直連
if (decodeVipFlag && Utils.isVip(videoUrl)) { // 使用jx:1
if (decodeVipFlag && Util.isVip(videoUrl)) { // 使用jx:1
try {
JSONObject result = new JSONObject();
result.put("parse", 1);

View File

@ -8,7 +8,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -40,14 +40,14 @@ public class Xb6v extends Spider {
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
header.put("Referer", siteUrl + "/");
return header;
}
private Map<String, String> getDetailHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Utils.CHROME);
header.put("User-Agent", Util.CHROME);
return header;
}
@ -220,7 +220,7 @@ public class Xb6v extends Spider {
.addEncoded("keyboard", key)
.build();
Request request = new Request.Builder().url(searchUrl)
.addHeader("User-Agent", Utils.CHROME)
.addHeader("User-Agent", Util.CHROME)
.addHeader("Origin", siteUrl)
.addHeader("Referer", siteUrl + "/")
.post(formBody)

View File

@ -6,7 +6,7 @@ import android.text.TextUtils;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.json.JSONArray;
import org.json.JSONException;
@ -33,7 +33,7 @@ public class XiaoZhiTiao extends Ali {
private Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<>();
params.put("Host", "gitcafe.net");
params.put("User-Agent", Utils.CHROME);
params.put("User-Agent", Util.CHROME);
return params;
}

View File

@ -8,7 +8,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -31,7 +31,7 @@ public class Ying extends Spider {
private HashMap<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
return headers;
}

View File

@ -8,7 +8,7 @@ import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -32,7 +32,7 @@ public class Ysj extends Spider {
private HashMap<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
return headers;
}

View File

@ -5,7 +5,7 @@ import android.content.Context;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Utils;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -30,7 +30,7 @@ public class Zhaozy extends Ali {
private Map<String, String> getHeader() {
Map<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
headers.put("Referer", siteUrl);
headers.put("Cookie", getCookie());
return headers;
@ -41,7 +41,7 @@ public class Zhaozy extends Ali {
params.put("username", username);
params.put("password", password);
Map<String, String> headers = new HashMap<>();
headers.put("User-Agent", Utils.CHROME);
headers.put("User-Agent", Util.CHROME);
headers.put("Referer", siteUrl + "stop.html");
headers.put("Origin", siteUrl);
StringBuilder sb = new StringBuilder();

View File

@ -1,36 +0,0 @@
package com.github.catvod.utils;
import com.github.catvod.spider.Proxy;
import java.net.URLEncoder;
import java.util.Map;
import java.util.TreeMap;
import fi.iki.elonen.NanoHTTPD;
public class MultiThread {
public static String url(String url, int thread) {
return String.format(Proxy.getUrl() + "?do=multi&url=%s&thread=%d", URLEncoder.encode(url), thread);
}
public static Object[] proxy(Map<String, String> params) throws Exception {
String url = params.get("url");
int thread = Integer.parseInt(params.get("thread"));
Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (String key : params.keySet()) headers.put(key, params.get(key));
MultiThreadedDownloader downloader = new MultiThreadedDownloader(url, removeHeaders(headers), thread);
NanoHTTPD.Response response = downloader.start();
return new Object[]{response};
}
private static Map<String, String> removeHeaders(Map<String, String> headers) {
headers.remove("do");
headers.remove("url");
headers.remove("host");
headers.remove("thread");
headers.remove("remote-addr");
headers.remove("http-client-ip");
return headers;
}
}

View File

@ -1,290 +0,0 @@
package com.github.catvod.utils;
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
import android.os.SystemClock;
import com.github.catvod.net.OkHttp;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import fi.iki.elonen.NanoHTTPD;
import okhttp3.Response;
public class MultiThreadedDownloader {
//已开始下载的 chunk 队列
private final BlockingQueue<Chunk> readyChunkQueue;
private final Map<String, String> headers;
private final String url;
private final Lock lock;
//最多缓存多少个未被取走的chunk
private final int maxBufferedChunk = 1024;
//线程数
private final int numThreads;
//读超时
private final int timeout = 10;
//每个线程每轮下载的字节数
private int chunkSize = 1024 * 64;
//下载起始的偏移量
private long startOffset = -1;
//下载结束的偏移量
private long endOffset = -1;
//当前读取的偏移量
private long currentOffset = -1;
//下一个 chunk 的起始偏移量
private long nextChunkStartOffset = -1;
//多线程是否在运行中
private boolean running;
public MultiThreadedDownloader(String url, Map<String, String> headers, int numThreads) {
this.url = url;
this.headers = headers;
this.numThreads = numThreads;
this.lock = new ReentrantLock();
this.readyChunkQueue = new LinkedBlockingQueue<>();
}
//开始下载
public NanoHTTPD.Response start() throws Exception {
//确保请求header包含Range
NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.PARTIAL_CONTENT;
if (!headers.containsKey("Range")) {
headers.put("Range", "bytes=0-");
status = NanoHTTPD.Response.Status.OK;
}
//尝试从Range判断下载的起始偏移量和结束偏移量
Matcher matcher = Pattern.compile("bytes=(\\d+)-(\\d+)?").matcher(headers.get("Range"));
if (matcher.find()) {
startOffset = Long.parseLong(matcher.group(1));
if (matcher.group(2) != null) {
endOffset = Long.parseLong(matcher.group(2));
}
} else {
throw new Exception("invalid Range: " + headers.get("Range"));
}
nextChunkStartOffset = startOffset;
currentOffset = startOffset;
//建立连接
Response response = OkHttp.newCall(getDownloadUrl(), headers);
//尽早关闭连接我们不需要body的数据
if (response.body() != null) response.body().close();
//检查状态码
int responseCode = response.code();
if (responseCode < 200 || responseCode >= 300) {
throw new Exception("response code: " + responseCode);
}
//获取header
String contentType = response.headers().get("Content-Type");
String contentDisposition = response.headers().get("Content-Disposition");
if (contentDisposition != null) contentType = Utils.getMimeType(contentDisposition);
if (contentType == null) throw new Exception("missing response header: Content-Type");
String hContentLength = response.headers().get("Content-Length");
if (hContentLength == null) throw new Exception("missing response header: Content-Length");
long contentLength = Long.parseLong(hContentLength);
//尝试从Content-Range获取下载结束的偏移量
if (endOffset <= 0) {
String hContentRange = response.headers().get("Content-Range");
if (hContentRange != null) {
matcher = Pattern.compile(".*/(\\d+)").matcher(hContentRange);
if (matcher.find()) {
endOffset = Long.parseLong(matcher.group(1)) - 1;
} else {
throw new Exception("invalid `Content-Range`: " + hContentRange);
}
} else {
throw new Exception("missing response header: Content-Range");
}
}
//如果下载的内容过小那么减少chunkSize使得每个线程刚好只需要下载一轮
long downloadSize = endOffset - startOffset + 1;
long onetimeChunkSize = downloadSize / numThreads + 1;
if (chunkSize > onetimeChunkSize) {
chunkSize = (int) onetimeChunkSize;
}
//开启多线程下载
running = true;
for (int i = 0; i < numThreads; ++i) {
new Thread(MultiThreadedDownloader.this::worker).start();
}
//构造response
PipedInputStream input = new PipedInputStream();
PipedOutputStream output = new PipedOutputStream(input);
NanoHTTPD.Response mResponse = newFixedLengthResponse(status, contentType, input, contentLength);
for (String key : response.headers().names()) {
String value = response.headers().get(key);
if (!key.equalsIgnoreCase("Content-Type") && !key.equalsIgnoreCase("Content-Length")) {
mResponse.addHeader(key, value);
}
}
//搬运数据流
new Thread(() -> {
try {
while (true) {
byte[] buffer = read();
if (buffer == null || buffer.length == 0) {
break;
}
output.write(buffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
stop();
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
return mResponse;
}
//读取文件内容
private byte[] read() throws Exception {
//判断文件是否下载结束
if (currentOffset > endOffset) {
stop();
return null;
}
//获取当前的chunk的数据
Chunk currentChunk = readyChunkQueue.poll(timeout, TimeUnit.SECONDS);
if (currentChunk == null) {
stop();
throw new Exception("read timeout");
}
while (running) {
byte[] buffer = currentChunk.get();
if (buffer != null) {
currentOffset += buffer.length;
return buffer;
} else {
SystemClock.sleep(100);
}
}
return null;
}
private void worker() {
while (running) {
//生成下一个chunk
Chunk chunk = null;
lock.lock();
long startOffset = nextChunkStartOffset;
nextChunkStartOffset += chunkSize;
if (startOffset <= endOffset) {
long endOffset = startOffset + chunkSize - 1;
if (endOffset > this.endOffset) {
endOffset = this.endOffset;
}
chunk = new Chunk(startOffset, endOffset);
readyChunkQueue.add(chunk);
}
lock.unlock();
//所有chunk已下载完
if (chunk == null) {
break;
}
while (running) {
//过多的数据未被取走先休息一下避免内存溢出
if (chunk.startOffset - currentOffset >= (long) chunkSize * maxBufferedChunk) {
SystemClock.sleep(1000);
} else {
break;
}
}
while (running) {
try {
//建立连接
Map<String, String> mHeaders = new HashMap<>();
for (Map.Entry<String, String> entry : headers.entrySet()) {
if (entry.getKey().equalsIgnoreCase("Range")) {
//设置下载范围
mHeaders.put("Range", String.format(Locale.getDefault(), "bytes=%d-%d", chunk.startOffset, chunk.endOffset));
} else {
mHeaders.put(entry.getKey(), entry.getValue());
}
}
Response response = OkHttp.newCall(getDownloadUrl(), mHeaders);
//检查状态码
int responseCode = response.code();
if (responseCode < 200 || responseCode >= 300) {
throw new Exception("response code: " + responseCode);
}
//接收数据
if (response.body() != null) {
chunk.put(response.body().bytes());
}
break;
} catch (Exception e) {
e.printStackTrace();
SystemClock.sleep(1000);
}
}
}
}
private String getDownloadUrl() {
if (url.contains("/proxy?")) {
return OkHttp.string(url);
} else {
return url;
}
}
public void stop() {
running = false;
}
private static class Chunk {
private final long startOffset;
private final long endOffset;
private byte[] buffer;
public Chunk(long startOffset, long endOffset) {
this.startOffset = startOffset;
this.endOffset = endOffset;
}
public byte[] get() {
return buffer;
}
public void put(byte[] buffer) throws InterruptedException {
this.buffer = buffer;
}
}
}

View File

@ -0,0 +1,30 @@
package com.github.catvod.utils;
import android.text.TextUtils;
import android.widget.Toast;
import com.github.catvod.spider.Init;
public class Notify {
private Toast mToast;
private static class Loader {
static volatile Notify INSTANCE = new Notify();
}
private static Notify get() {
return Loader.INSTANCE;
}
public static void show(String text) {
Init.run(() -> get().makeText(text));
}
private void makeText(String message) {
if (TextUtils.isEmpty(message)) return;
if (mToast != null) mToast.cancel();
mToast = Toast.makeText(Init.context(), message, Toast.LENGTH_LONG);
mToast.show();
}
}

View File

@ -1,7 +1,6 @@
package com.github.catvod.utils;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
@ -15,8 +14,6 @@ import java.util.List;
public class Path {
private static final String TAG = Path.class.getSimpleName();
private static File check(File file) {
if (!file.exists()) file.mkdirs();
return file;
@ -47,14 +44,6 @@ public class Path {
}
}
public static String read(String path) {
try {
return read(new FileInputStream(path));
} catch (Exception e) {
return "";
}
}
public static String read(InputStream is) {
try {
byte[] data = new byte[is.available()];
@ -84,18 +73,6 @@ public class Path {
}
}
public static void move(File in, File out) {
copy(in, out);
clear(in);
}
public static void copy(File in, File out) {
try {
copy(new FileInputStream(in), new FileOutputStream(out));
} catch (Exception ignored) {
}
}
public static void copy(InputStream in, File out) {
try {
copy(in, new FileOutputStream(out));
@ -116,12 +93,6 @@ public class Path {
return files == null ? Collections.emptyList() : Arrays.asList(files);
}
public static void clear(File dir) {
if (dir == null) return;
if (dir.isDirectory()) for (File file : list(dir)) clear(file);
if (dir.delete()) Log.d(TAG, "Deleted:" + dir.getAbsolutePath());
}
public static File chmod(File file) {
try {
Process process = Runtime.getRuntime().exec("chmod 777 " + file);

View File

@ -1,9 +1,15 @@
package com.github.catvod.utils;
import static fi.iki.elonen.NanoHTTPD.Response.Status;
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
import com.github.catvod.net.OkHttp;
import android.os.SystemClock;
import com.github.catvod.net.OkHttp;
import com.github.catvod.spider.Proxy;
import java.net.URLEncoder;
import java.util.Locale;
import java.util.Map;
import fi.iki.elonen.NanoHTTPD;
@ -11,18 +17,61 @@ import okhttp3.Response;
public class ProxyVideo {
public static NanoHTTPD.Response proxy(String url, Map<String, String> headers) throws Exception {
NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.PARTIAL_CONTENT;
if (!headers.containsKey("Range")) {
headers.put("Range", "bytes=0-");
status = NanoHTTPD.Response.Status.OK;
private static final String GO_SERVER = "http://127.0.0.1:7777/";
public static void go() {
if (OkHttp.string(GO_SERVER).isEmpty()) OkHttp.string("http://127.0.0.1:" + Proxy.getPort() + "/go");
while (OkHttp.string(GO_SERVER).isEmpty()) SystemClock.sleep(20);
}
public static String url(String url, int thread) {
go();
return String.format(Locale.getDefault(), "%s?url=%s&thread=%d", GO_SERVER, URLEncoder.encode(url), thread);
}
public static NanoHTTPD.Response proxy(String url, Map<String, String> headers) throws Exception {
Status status = headers.containsKey("Range") ? Status.PARTIAL_CONTENT : Status.OK;
if (!headers.containsKey("Range")) headers.put("Range", "bytes=0-");
Response response = OkHttp.newCall(url, headers);
String contentType = response.headers().get("Content-Type");
String hContentLength = response.headers().get("Content-Length");
String contentDisposition = response.headers().get("Content-Disposition");
long contentLength = hContentLength != null ? Long.parseLong(hContentLength) : 0;
if (contentDisposition != null) contentType = Utils.getMimeType(contentDisposition);
return newFixedLengthResponse(status, contentType, response.body().byteStream(), contentLength);
if (contentDisposition != null) contentType = getMimeType(contentDisposition);
NanoHTTPD.Response resp = newFixedLengthResponse(status, contentType, response.body().byteStream(), contentLength);
for (String key : response.headers().names()) resp.addHeader(key, response.headers().get(key));
return resp;
}
private static String getMimeType(String contentDisposition) {
if (contentDisposition.endsWith(".mp4")) {
return "video/mp4";
} else if (contentDisposition.endsWith(".webm")) {
return "video/webm";
} else if (contentDisposition.endsWith(".avi")) {
return "video/x-msvideo";
} else if (contentDisposition.endsWith(".wmv")) {
return "video/x-ms-wmv";
} else if (contentDisposition.endsWith(".flv")) {
return "video/x-flv";
} else if (contentDisposition.endsWith(".mov")) {
return "video/quicktime";
} else if (contentDisposition.endsWith(".mkv")) {
return "video/x-matroska";
} else if (contentDisposition.endsWith(".mpeg")) {
return "video/mpeg";
} else if (contentDisposition.endsWith(".3gp")) {
return "video/3gpp";
} else if (contentDisposition.endsWith(".ts")) {
return "video/MP2T";
} else if (contentDisposition.endsWith(".mp3")) {
return "audio/mp3";
} else if (contentDisposition.endsWith(".wav")) {
return "audio/wav";
} else if (contentDisposition.endsWith(".aac")) {
return "audio/aac";
} else {
return null;
}
}
}

View File

@ -35,7 +35,7 @@ public class QRCode {
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, margin);
return createBitmap(new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, Utils.dp2px(size), Utils.dp2px(size), hints));
return createBitmap(new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, size, size, hints));
} catch (Exception e) {
e.printStackTrace();
return null;

View File

@ -0,0 +1,17 @@
package com.github.catvod.utils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import com.github.catvod.spider.Init;
public class ResUtil {
private static DisplayMetrics getDisplayMetrics() {
return Init.context().getResources().getDisplayMetrics();
}
public static int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getDisplayMetrics());
}
}

View File

@ -5,14 +5,11 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import com.github.catvod.spider.Init;
@ -26,9 +23,9 @@ import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Utils {
public class Util {
public static final Pattern RULE = Pattern.compile("http((?!http).){12,}?\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)|http((?!http).)*?video/tos*");
public static final Pattern RULE = Pattern.compile("http((?!http).){12,}?\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)|http((?!http).)*?video/tos*");
public static final String CHROME = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36";
public static final String ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7";
public static final List<String> MEDIA = Arrays.asList("mp4", "mkv", "wmv", "flv", "avi", "iso", "mpg", "ts", "mp3", "aac", "flac", "m4a", "ape", "ogg");
@ -147,18 +144,10 @@ public class Utils {
}
}
public static DisplayMetrics getDisplayMetrics() {
return Init.context().getResources().getDisplayMetrics();
}
public static int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getDisplayMetrics());
}
public static void copy(String text) {
ClipboardManager manager = (ClipboardManager) Init.context().getSystemService(Context.CLIPBOARD_SERVICE);
manager.setPrimaryClip(ClipData.newPlainText("fongmi", text));
notify("已複製 " + text);
Notify.show("已複製 " + text);
}
public static void loadUrl(WebView webView, String script) {
@ -170,10 +159,6 @@ public class Utils {
else webView.loadUrl(script);
}
public static void notify(String msg) {
Init.run(() -> Toast.makeText(Init.context(), msg, Toast.LENGTH_LONG).show());
}
public static void addView(View view, ViewGroup.LayoutParams params) {
try {
ViewGroup group = Init.getActivity().getWindow().getDecorView().findViewById(android.R.id.content);
@ -216,36 +201,4 @@ public class Utils {
return "";
}
}
public static String getMimeType(String contentDisposition) {
if (contentDisposition.endsWith(".mp4")) {
return "video/mp4";
} else if (contentDisposition.endsWith(".webm")) {
return "video/webm";
} else if (contentDisposition.endsWith(".avi")) {
return "video/x-msvideo";
} else if (contentDisposition.endsWith(".wmv")) {
return "video/x-ms-wmv";
} else if (contentDisposition.endsWith(".flv")) {
return "video/x-flv";
} else if (contentDisposition.endsWith(".mov")) {
return "video/quicktime";
} else if (contentDisposition.endsWith(".mkv")) {
return "video/x-matroska";
} else if (contentDisposition.endsWith(".mpeg")) {
return "video/mpeg";
} else if (contentDisposition.endsWith(".3gp")) {
return "video/3gpp";
} else if (contentDisposition.endsWith(".ts")) {
return "video/MP2T";
} else if (contentDisposition.endsWith(".mp3")) {
return "audio/mp3";
} else if (contentDisposition.endsWith(".wav")) {
return "audio/wav";
} else if (contentDisposition.endsWith(".aac")) {
return "audio/aac";
} else {
return null;
}
}
}

Binary file not shown.

View File

@ -1 +1 @@
9060b67dfec8782aca6e79ba17c0979b
5d1ab45ff233a49e9bc9b9a1554b38a9

View File

@ -1,5 +1,5 @@
{
"spider": "https://fm.t4tv.hz.cz/jar/custom_spider.jar;md5;9060b67dfec8782aca6e79ba17c0979b",
"spider": "https://fm.t4tv.hz.cz/jar/custom_spider.jar;md5;5d1ab45ff233a49e9bc9b9a1554b38a9",
"wallpaper": "https://gao.chuqiuyu.workers.dev",
"sites": [
{

View File

@ -1,5 +1,5 @@
{
"spider": "https://fm.t4tv.hz.cz/jar/custom_spider.jar;md5;9060b67dfec8782aca6e79ba17c0979b",
"spider": "https://fm.t4tv.hz.cz/jar/custom_spider.jar;md5;5d1ab45ff233a49e9bc9b9a1554b38a9",
"wallpaper": "http://饭太硬.top/深色壁纸/api.php",
"sites": [
{
@ -262,6 +262,14 @@
"changeable": 0,
"ext": "https://fm.t4tv.hz.cz/json/webdav.json"
},
{
"key": "JustLive",
"name": "JustLive",
"type": 3,
"api": "csp_JustLive",
"searchable": 1,
"changeable": 0
},
{
"key": "七夜",
"name": "七夜",
@ -451,7 +459,8 @@
"hd.ffzy"
],
"regex": [
"25.0666"
"25.0666",
"25.08"
]
},
{