Add files via upload
This commit is contained in:
@@ -0,0 +1,663 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.Misc;
|
||||
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Author: @SDL
|
||||
*/
|
||||
public class Kmys extends Spider {
|
||||
private String apiDomain = "";
|
||||
private String staticDomain = "";
|
||||
|
||||
private String appId = "1"; // 飞瓜 1 酷猫 5
|
||||
|
||||
private String device = null;
|
||||
|
||||
public static final String KEY_ALGORITHM = "RSA";
|
||||
|
||||
private static final int MAX_DECRYPT_BLOCK = 128;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
getkey();
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences("sp_Kmys", Context.MODE_PRIVATE);
|
||||
try {
|
||||
device = sharedPreferences.getString("device", null);
|
||||
} catch (Throwable th) {
|
||||
} finally {
|
||||
if (device == null) {
|
||||
device = Misc.MD5(UUID.randomUUID().toString(), Misc.CharsetUTF8).toLowerCase();
|
||||
sharedPreferences.edit().putString("device", device).commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("versionNumber", "360");
|
||||
headers.put("versionName", "3.6.0");
|
||||
headers.put("device", device);
|
||||
headers.put("appId", appId);
|
||||
headers.put("platformId", "7");
|
||||
headers.put("User-Agent", "okhttp/3.14.7");
|
||||
return headers;
|
||||
}
|
||||
|
||||
private void checkDomain() {
|
||||
if (staticDomain.isEmpty()) {
|
||||
String url = "http://feigua2021.oss-cn-beijing.aliyuncs.com/static/config/video/" + appId + ".json";
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", "okhttp/3.14.7");
|
||||
String json = OkHttpUtil.string(url, headers);
|
||||
try {
|
||||
JSONObject obj = new JSONObject(json);
|
||||
apiDomain = obj.getString("apiDomain");
|
||||
staticDomain = obj.getString("staticDomain");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
checkDomain();
|
||||
getkey();
|
||||
String url = staticDomain + "/static/" + appId + "/config/lib-new.json";
|
||||
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||
JSONObject jsonObject = new JSONObject(content).getJSONObject("data");
|
||||
|
||||
JSONArray years = jsonObject.getJSONArray("year");
|
||||
JSONArray types = jsonObject.getJSONArray("types");
|
||||
|
||||
JSONArray classes = new JSONArray();
|
||||
JSONObject filterConfig = new JSONObject();
|
||||
|
||||
for (int i = 0; i < types.length(); i++) {
|
||||
JSONObject item = types.getJSONObject(i);
|
||||
String typeId = item.getString("typeId").trim();
|
||||
if (typeId.isEmpty())
|
||||
continue;
|
||||
String typeName = item.getString("typeName");
|
||||
JSONObject newCls = new JSONObject();
|
||||
newCls.put("type_id", typeId);
|
||||
newCls.put("type_name", typeName);
|
||||
classes.put(newCls);
|
||||
|
||||
JSONArray tags = item.getJSONArray("tags");
|
||||
JSONArray extendsAll = new JSONArray();
|
||||
// 类型
|
||||
JSONObject newTypeExtend = new JSONObject();
|
||||
newTypeExtend.put("key", "type");
|
||||
newTypeExtend.put("name", "类型");
|
||||
JSONArray newTypeExtendKV = new JSONArray();
|
||||
JSONObject kv = new JSONObject();
|
||||
kv.put("n", "全部");
|
||||
kv.put("v", "-1");
|
||||
newTypeExtendKV.put(kv);
|
||||
for (int j = 0; j < tags.length(); j++) {
|
||||
JSONObject child = tags.getJSONObject(j);
|
||||
kv = new JSONObject();
|
||||
kv.put("n", child.getString("typeName"));
|
||||
kv.put("v", child.getString("typeId"));
|
||||
newTypeExtendKV.put(kv);
|
||||
}
|
||||
newTypeExtend.put("value", newTypeExtendKV);
|
||||
extendsAll.put(newTypeExtend);
|
||||
// 排序
|
||||
newTypeExtend = new JSONObject();
|
||||
newTypeExtend.put("key", "sort");
|
||||
newTypeExtend.put("name", "排序");
|
||||
newTypeExtendKV = new JSONArray();
|
||||
kv = new JSONObject();
|
||||
kv.put("n", "最热");
|
||||
kv.put("v", "2");
|
||||
newTypeExtendKV.put(kv);
|
||||
kv = new JSONObject();
|
||||
kv.put("n", "最新");
|
||||
kv.put("v", "1");
|
||||
newTypeExtendKV.put(kv);
|
||||
kv = new JSONObject();
|
||||
kv.put("n", "好评");
|
||||
kv.put("v", "3");
|
||||
newTypeExtendKV.put(kv);
|
||||
newTypeExtend.put("value", newTypeExtendKV);
|
||||
extendsAll.put(newTypeExtend);
|
||||
// 地区
|
||||
JSONArray regions = item.getJSONArray("children");
|
||||
newTypeExtend = new JSONObject();
|
||||
newTypeExtend.put("key", "area");
|
||||
newTypeExtend.put("name", "地区");
|
||||
newTypeExtendKV = new JSONArray();
|
||||
kv = new JSONObject();
|
||||
kv.put("n", "全部");
|
||||
kv.put("v", "-1");
|
||||
newTypeExtendKV.put(kv);
|
||||
for (int j = 0; j < regions.length(); j++) {
|
||||
JSONObject child = regions.getJSONObject(j);
|
||||
kv = new JSONObject();
|
||||
kv.put("n", child.getString("typeName"));
|
||||
kv.put("v", child.getString("typeId"));
|
||||
newTypeExtendKV.put(kv);
|
||||
}
|
||||
newTypeExtend.put("value", newTypeExtendKV);
|
||||
extendsAll.put(newTypeExtend);
|
||||
|
||||
// 年份
|
||||
newTypeExtend = new JSONObject();
|
||||
newTypeExtend.put("key", "year");
|
||||
newTypeExtend.put("name", "年份");
|
||||
newTypeExtendKV = new JSONArray();
|
||||
kv = new JSONObject();
|
||||
kv.put("n", "全部");
|
||||
kv.put("v", "-1");
|
||||
newTypeExtendKV.put(kv);
|
||||
for (int j = 0; j < years.length(); j++) {
|
||||
String year = years.getString(j).trim();
|
||||
if (year.isEmpty())
|
||||
continue;
|
||||
kv = new JSONObject();
|
||||
kv.put("n", year);
|
||||
kv.put("v", year);
|
||||
newTypeExtendKV.put(kv);
|
||||
}
|
||||
newTypeExtend.put("value", newTypeExtendKV);
|
||||
extendsAll.put(newTypeExtend);
|
||||
filterConfig.put(typeId, extendsAll);
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("class", classes);
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() {
|
||||
try {
|
||||
checkDomain();
|
||||
String url = staticDomain + "/static/" + appId + "/index/cloumn/1.json";
|
||||
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||
JSONObject jsonObject = new JSONObject(content).getJSONObject("data");
|
||||
JSONArray list = jsonObject.getJSONArray("list");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.length(); i++) {
|
||||
JSONArray videoList = list.getJSONObject(i).getJSONArray("videoList");
|
||||
for (int j = 0; j < videoList.length(); j++) {
|
||||
JSONObject vObj = videoList.getJSONObject(j);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("vodName"));
|
||||
v.put("vod_pic", fixUrl(vObj.getString("vodPicThumb")));
|
||||
v.put("vod_remarks", vObj.getString("lastName"));
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
checkDomain();
|
||||
JSONObject result = new JSONObject();
|
||||
|
||||
String url = apiDomain + "/videolibrary/v2/" + appId + "/" + tid;
|
||||
extend = extend == null ? new HashMap<>() : extend;
|
||||
if (!extend.containsKey("area")) {
|
||||
extend.put("area", "-1");
|
||||
}
|
||||
if (!extend.containsKey("type")) {
|
||||
extend.put("type", "-1");
|
||||
}
|
||||
if (!extend.containsKey("sort")) {
|
||||
extend.put("sort", "2");
|
||||
}
|
||||
if (!extend.containsKey("year")) {
|
||||
extend.put("year", "-1");
|
||||
}
|
||||
url += "/" + extend.get("area");
|
||||
url += "/" + extend.get("type");
|
||||
url += "/" + extend.get("sort");
|
||||
url += "/-1";
|
||||
url += "/" + extend.get("year");
|
||||
url += "/-1/" + pg + ".json";
|
||||
|
||||
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||
JSONObject jsonObject = new JSONObject(content).getJSONObject("data");
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("list");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("vodName"));
|
||||
v.put("vod_pic", fixUrl(vObj.getString("vodPicThumb")));
|
||||
v.put("vod_remarks", vObj.getString("lastName"));
|
||||
videos.put(v);
|
||||
}
|
||||
|
||||
int total = jsonObject.getInt("count");
|
||||
int limit = jsonObject.getInt("pageSize");
|
||||
int totalPg = total % limit == 0 ? (total / limit) : (total / limit + 1);
|
||||
result.put("page", jsonObject.getInt("pageIndex"));
|
||||
result.put("pagecount", totalPg);
|
||||
result.put("limit", limit);
|
||||
result.put("total", total);
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
checkDomain();
|
||||
JSONObject result = new JSONObject();
|
||||
String url = staticDomain + "/static/video/detail/" + ids.get(0) + ".json";
|
||||
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||
JSONObject jsonObject = new JSONObject(content).getJSONObject("data");
|
||||
JSONObject vodList = new JSONObject();
|
||||
vodList.put("vod_id", jsonObject.getString("id"));
|
||||
vodList.put("vod_name", jsonObject.getString("vodName"));
|
||||
vodList.put("vod_pic", fixUrl(jsonObject.getString("vodPic")));
|
||||
vodList.put("type_name", jsonObject.getString("typeName"));
|
||||
vodList.put("vod_year", jsonObject.getString("vodYear"));
|
||||
vodList.put("vod_area", jsonObject.getString("vodArea"));
|
||||
vodList.put("vod_remarks", "");
|
||||
vodList.put("vod_actor", jsonObject.getString("vodActor"));
|
||||
vodList.put("vod_director", "");
|
||||
vodList.put("vod_content", jsonObject.getString("vodBlurb"));
|
||||
|
||||
String vodPlayUrl = jsonObject.getString("vodPlayUrl");
|
||||
vodPlayUrl = rsa(vodPlayUrl.substring(0, 10) + vodPlayUrl.substring(16));
|
||||
|
||||
ArrayList<String> playFrom = new ArrayList<>();
|
||||
ArrayList<String> playList = new ArrayList<>();
|
||||
|
||||
JSONArray playSource = new JSONArray(vodPlayUrl);
|
||||
for (int i = 0; i < playSource.length(); i++) {
|
||||
JSONObject item = playSource.getJSONObject(i);
|
||||
String srcName = item.getString("name");
|
||||
boolean userProxy = srcName.equals("高速线路");
|
||||
ArrayList<String> urls = new ArrayList<>();
|
||||
JSONArray playUrls = item.getJSONArray("list");
|
||||
for (int j = 0; j < playUrls.length(); j++) {
|
||||
JSONObject urlObj = playUrls.getJSONObject(j);
|
||||
if (userProxy)
|
||||
urls.add(urlObj.getString("name") + "$" + Proxy.localProxyUrl() + "?do=kmys&type=m3u8&url=" + Base64.encodeToString(urlObj.getString("url").getBytes(Misc.CharsetUTF8), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP) + ".." + urlObj.getInt("isParse"));
|
||||
else
|
||||
urls.add(urlObj.getString("name") + "$" + urlObj.getString("url") + ".." + urlObj.getInt("isParse"));
|
||||
}
|
||||
if (urls.isEmpty())
|
||||
continue;
|
||||
playFrom.add(srcName);
|
||||
playList.add(TextUtils.join("#", urls));
|
||||
}
|
||||
|
||||
String vod_play_from = TextUtils.join("$$$", playFrom);
|
||||
String vod_play_url = TextUtils.join("$$$", playList);
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
String[] info = id.split("\\.\\.");
|
||||
String url = info[0];
|
||||
int isParse = Integer.parseInt(info[1]);
|
||||
if (isParse == 2) {
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", url);
|
||||
} else {
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", url);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
|
||||
if (quick)
|
||||
return "";
|
||||
try {
|
||||
checkDomain();
|
||||
JSONObject result = new JSONObject();
|
||||
String url = apiDomain + "/api/v2/index/search?pageIndex=1&wd=" + URLEncoder.encode(key) + "&limit=10&type=1";
|
||||
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||
JSONArray videos = new JSONArray();
|
||||
JSONObject jsonObject = new JSONObject(content).getJSONObject("data");
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("list");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
String title = vObj.getString("vodName");
|
||||
if (!title.contains(key))
|
||||
continue;
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", fixUrl(vObj.getString("vodPicThumb")));
|
||||
v.put("vod_remarks", vObj.getString("lastName"));
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
protected String fixUrl(String src) {
|
||||
try {
|
||||
if (src.startsWith("//")) {
|
||||
Uri parse = Uri.parse(staticDomain);
|
||||
src = parse.getScheme() + ":" + src;
|
||||
} else if (!src.contains("://")) {
|
||||
Uri parse = Uri.parse(staticDomain);
|
||||
if (!src.startsWith("/"))
|
||||
src = "/" + src;
|
||||
src = parse.getScheme() + "://" + parse.getHost() + src;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
String rsa(String in) {
|
||||
try {
|
||||
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VLHgbkFN0ebMaR4e0D\n" +
|
||||
"z6Z2mFexPBFKGqK0tuRhzu7XOrG92nKWfnublf2p1i22UN81whBLINjMttOuqW6\n" +
|
||||
"fM9DCnAPTelud1zCXWYWIsv5Z19inJSG8vytJ7xg1dnfuRSRUkx11IE7bm0T/sM\n" +
|
||||
"0sI4GgcktQJNSizyirHtuJjUUxxQabEhFkFeqQ5r+A69KjB5QkotCc4pG5lENyT\n" +
|
||||
"ARHGSsfaiJthaiH0yJ/8tUlyMgJ9H6/jbQg0wlLcEUzdfe2KuCPrTRzIzx4Cjm1\n" +
|
||||
"JogT6JV2byvXpzAMC3O48LDiekJdVztg2Cj7E0cGrOsGs+IK6F7TWsKD/cIELTF\n" +
|
||||
"hLz6dExQIDAQAB", Base64.DEFAULT)));
|
||||
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, pubKey);
|
||||
byte[] inData = Base64.decode(in, Base64.DEFAULT);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
if (inData.length <= 256) {
|
||||
outputStream.write(cipher.doFinal(inData));
|
||||
} else {
|
||||
for (int i = 0; i < inData.length; i += 256) {
|
||||
outputStream.write(cipher.doFinal(inData, i, 256));
|
||||
}
|
||||
}
|
||||
outputStream.flush();
|
||||
String result = new String(outputStream.toByteArray(), Misc.CharsetUTF8);
|
||||
outputStream.close();
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static HashMap<String, String> kmysPlayerHeaders = null;
|
||||
private static String signPlayerStr = "";
|
||||
private static final Pattern tsRex = Pattern.compile("(\\S+.ts)|(#EXT-X-KEY:\\S+\")(\\S+)(\")");
|
||||
|
||||
static String subUrl(String url) {
|
||||
if (url.startsWith("http://")) {
|
||||
return url.substring(0, url.substring(7).indexOf(47) + 7);
|
||||
}
|
||||
String tmp = url.startsWith("https://") ? url.substring(0, url.substring(8).indexOf(47) + 8) : "";
|
||||
return url.substring(tmp.length());
|
||||
}
|
||||
|
||||
static Object[] getVodContent(String m3u8) {
|
||||
Uri uri = Uri.parse(m3u8);
|
||||
String time = String.valueOf(System.currentTimeMillis());
|
||||
String key = Misc.MD5(subUrl(m3u8) + signPlayerStr + time, Misc.CharsetUTF8).toLowerCase();
|
||||
String realUrl = m3u8 + "?key=" + key + "&time=" + time;
|
||||
String m3u8Content = OkHttpUtil.string(realUrl, kmysPlayerHeaders);
|
||||
String tsUrl = m3u8.substring(0, m3u8.indexOf(uri.getLastPathSegment()));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int start = 0;
|
||||
Matcher matcher = tsRex.matcher(m3u8Content);
|
||||
while (matcher.find()) {
|
||||
sb.append(m3u8Content, start, matcher.start());
|
||||
if (matcher.group().contains("EXT-X-KEY")) {
|
||||
String keyRealUrl = Proxy.localProxyUrl() + "?do=kmys&type=key&url=" + Base64.encodeToString((tsUrl + matcher.group(3)).getBytes(Misc.CharsetUTF8), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
sb.append(matcher.group(2) + keyRealUrl + matcher.group(4));
|
||||
} else {
|
||||
String tsRealUrl = Proxy.localProxyUrl() + "?do=kmys&type=ts&url=" + Base64.encodeToString((tsUrl + matcher.group(1)).getBytes(Misc.CharsetUTF8), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
sb.append(tsRealUrl);
|
||||
}
|
||||
start = matcher.end();
|
||||
}
|
||||
sb.append(m3u8Content, start, m3u8Content.length());
|
||||
String type = "application/octet-stream";
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = type;
|
||||
ByteArrayInputStream baos = new ByteArrayInputStream(sb.toString().getBytes(Misc.CharsetUTF8));
|
||||
result[2] = baos;
|
||||
return result;
|
||||
}
|
||||
|
||||
static Object[] getKeyContent(String key) {
|
||||
String time = String.valueOf(System.currentTimeMillis());
|
||||
String md5 = Misc.MD5(subUrl(key) + signPlayerStr + time, Misc.CharsetUTF8).toLowerCase();
|
||||
String realUrl = key + "?key=" + md5 + "&time=" + time;
|
||||
String keyContent = OkHttpUtil.string(realUrl, kmysPlayerHeaders);
|
||||
String type = "application/octet-stream";
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = type;
|
||||
ByteArrayInputStream baos = new ByteArrayInputStream(keyContent.getBytes(Misc.CharsetUTF8));
|
||||
result[2] = baos;
|
||||
return result;
|
||||
}
|
||||
|
||||
static Object[] getTsContent(String ts) {
|
||||
String time = String.valueOf(System.currentTimeMillis());
|
||||
String key = Misc.MD5(subUrl(ts) + signPlayerStr + time, Misc.CharsetUTF8).toLowerCase();
|
||||
String realUrl = ts + "?key=" + key + "&time=" + time;
|
||||
OKCallBack.OKCallBackDefault callBack = new OKCallBack.OKCallBackDefault() {
|
||||
|
||||
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Response response) {
|
||||
}
|
||||
};
|
||||
OkHttpUtil.get(OkHttpUtil.defaultClient(), realUrl, null, kmysPlayerHeaders, callBack);
|
||||
if (callBack.getResult().code() == 200) {
|
||||
Headers headers = callBack.getResult().headers();
|
||||
String type = headers.get("Content-Type");
|
||||
if (type == null) {
|
||||
type = "application/octet-stream";
|
||||
}
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = type;
|
||||
result[2] = callBack.getResult().body().byteStream();
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object[] vod(Map<String, String> params) {
|
||||
String type = params.get("type");
|
||||
String url = params.get("url");
|
||||
url = new String(Base64.decode(url, Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP), Misc.CharsetUTF8);
|
||||
if (kmysPlayerHeaders == null) {
|
||||
kmysPlayerHeaders = new HashMap<>();
|
||||
kmysPlayerHeaders.put("User-Agent", "okhttp/3.14.7");
|
||||
kmysPlayerHeaders.put("Connection", "close");
|
||||
}
|
||||
if (type.equals("m3u8")) {
|
||||
return getVodContent(url);
|
||||
} else if (type.equals("key")) {
|
||||
return getKeyContent(url);
|
||||
} else if (type.equals("ts")) {
|
||||
return getTsContent(url);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void getkey(){
|
||||
if (signPlayerStr.isEmpty()){
|
||||
////https://video-api.kumaoys.cn/api/v2/b/83708861
|
||||
String url = "https://mtv.stvmts.com/api/v2/b/"+((int) (Math.random() * 100000000));
|
||||
HashMap hashMap = new HashMap();
|
||||
hashMap.put("versionNumber", "360");
|
||||
hashMap.put("versionName", "3.6.0");
|
||||
hashMap.put("device", "f6076f40ecda2adacbcefeaad22527ce1656685979546");
|
||||
//hashMap.put("appId", "5");
|
||||
hashMap.put("platformId", "7");
|
||||
hashMap.put("User-Agent", "okhttp/3.14.7");
|
||||
hashMap.put("Pragma", "Pragma:: no-cache");
|
||||
hashMap.put("Cache-Control", "no-cache");
|
||||
hashMap.put("Host", "mtv.stvmts.com");
|
||||
hashMap.put("Content-Type", "application/json; charser=utf-8");
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
int random = (int)(Math.random()*1.0E8d);
|
||||
int time = (int)(System.currentTimeMillis()/1000);
|
||||
String signBefore = "p=com.kumao.yingshi&t=" + time + "&r=" + random + "&s=36eff39894f62d333fd3f488cffbf364&pl=1";
|
||||
jsonObject.put("s",Misc.MD5(signBefore,Misc.CharsetUTF8));
|
||||
jsonObject.put("t",time);
|
||||
jsonObject.put("r",random);
|
||||
jsonObject.put("i",5);
|
||||
jsonObject.put("p",1);
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), url, jsonObject.toString(), hashMap, new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
try {
|
||||
|
||||
JSONObject jsonObject = new JSONObject(response).getJSONObject("data");
|
||||
String a = new String(Base64.decode(jsonObject.getString("a"),Base64.DEFAULT));
|
||||
String k = new String(Base64.decode(jsonObject.getString("k"),Base64.DEFAULT));
|
||||
String z = new String(Base64.decode(jsonObject.getString("z"),Base64.DEFAULT));
|
||||
|
||||
String sum=(k+z+a);
|
||||
byte[] byte_sum=Base64.decode(sum,Base64.DEFAULT);
|
||||
byte[] jiemi=decryptByPublicKey(byte_sum,"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCt/dLGQj1Iimj0LIUMUXgBGUjsfrm6o1/pZjXXVLL3py2vLktNtSoJU+69v1tUXZqiU9BqMHApVmMOtOnkL5J+ENdLIX3bXnNtfNJpYX4Iz8OBMqKdDch80gN8rLkTPReFkBGsMAndKpc0iMdgd6nts/gQ3wUBNJKpmOG35UateQIDAQAB");
|
||||
String data =new String(jiemi,Misc.CharsetUTF8);
|
||||
signPlayerStr = new JSONObject(data).optString("key");
|
||||
} catch (JSONException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(publicKey,Base64.DEFAULT);
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicK);
|
||||
int inputLen = encryptedData.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -450,7 +450,7 @@ public class Lib extends Spider {
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
String url = "https://shitu.paodekuaiweixinqun.com/search?q=site%3Alibvio.me%2Fdetail+" + URLEncoder.encode(key);
|
||||
String url = "https://google.1qi777.com/search?q=site%3Alibvio.me%2Fdetail+" + URLEncoder.encode(key);
|
||||
Document docs = Jsoup.parse(OkHttpUtil.string(url, sHeaders()));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
@@ -501,4 +501,4 @@ public class Lib extends Spider {
|
||||
}
|
||||
return src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
package com.github.catvod.parser;
|
||||
|
||||
import android.util.Base64;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.Misc;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class MixWeb {
|
||||
|
||||
/*
|
||||
"parses": [
|
||||
{
|
||||
"name": "聚合",
|
||||
"type": 3,
|
||||
"url": "Demo"
|
||||
},
|
||||
{
|
||||
"name": "解析",
|
||||
"type": 1,
|
||||
"url": "https://192.168.10.88/jx.php?url=",
|
||||
"ext": {
|
||||
"flag": [
|
||||
"qq",
|
||||
"iqiyi",
|
||||
"qiyi",
|
||||
"爱奇艺",
|
||||
"腾讯",
|
||||
"letv",
|
||||
"sohu",
|
||||
"tudou",
|
||||
"pptv",
|
||||
"mgtv",
|
||||
"wasu",
|
||||
"bilibili"
|
||||
]
|
||||
}
|
||||
}]
|
||||
*/
|
||||
|
||||
public static HashMap<String, ArrayList<String>> flagWebJx = new HashMap<>();
|
||||
|
||||
static HashMap<String, ArrayList<String>> configs = null;
|
||||
|
||||
public static JSONObject parse(LinkedHashMap<String, HashMap<String, String>> jx, String nameMe, String flag, String url) {
|
||||
try {
|
||||
if (configs == null) {
|
||||
configs = new HashMap<>();
|
||||
Iterator<String> keys = jx.keySet().iterator();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
HashMap<String, String> parseBean = jx.get(key);
|
||||
String type = parseBean.get("type");
|
||||
if (type.equals("0")) {
|
||||
try {
|
||||
//取出单个解析的flags列表
|
||||
JSONArray flags = new JSONObject(parseBean.get("ext")).getJSONArray("flag");
|
||||
for (int j = 0; j < flags.length(); j++) {
|
||||
//获取单个flags
|
||||
String flagKey = flags.getString(j);
|
||||
//取出configs中对应flags的解析
|
||||
ArrayList<String> flagJx = configs.get(flagKey);
|
||||
//如果configs中没有这个flags,则插入一个空的值
|
||||
if (flagJx == null) {
|
||||
flagJx = new ArrayList<>();
|
||||
configs.put(flagKey, flagJx);
|
||||
}
|
||||
//如果有就在flagJx中增加解析
|
||||
flagJx.add(key);
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 通过上面的配置获得解析列表
|
||||
ArrayList<String> webJx = new ArrayList<>();
|
||||
ArrayList<String> flagJx = configs.get(flag);
|
||||
//如果flagJx不为空
|
||||
if (flagJx != null && !flagJx.isEmpty()) {
|
||||
for (int i = 0; i < flagJx.size(); i++) {
|
||||
String key = flagJx.get(i);
|
||||
HashMap<String, String> parseBean = jx.get(key);
|
||||
String type = parseBean.get("type");
|
||||
if (type.equals("0")) {
|
||||
//将json解析放入webJx
|
||||
webJx.add(parseBean.get("url"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Iterator<String> keys = jx.keySet().iterator();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
HashMap<String, String> parseBean = jx.get(key);
|
||||
String type = parseBean.get("type");
|
||||
if (type.equals("0")) {
|
||||
webJx.add(parseBean.get("url"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!webJx.isEmpty()) {
|
||||
flagWebJx.put(flag, webJx);
|
||||
}
|
||||
|
||||
// json解析没有得到结果 用webview解析
|
||||
if (!webJx.isEmpty()) {
|
||||
JSONObject webResult = new JSONObject();
|
||||
webResult.put("url", "proxy://do=MixWeb&flag=" + flag + "&url=" + Base64.encodeToString(url.getBytes(), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP));
|
||||
webResult.put("parse", 1);
|
||||
webResult.put("ua", Misc.UaWinChrome);
|
||||
return webResult;
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
SpiderDebug.log(th);
|
||||
}
|
||||
return new JSONObject();
|
||||
}
|
||||
|
||||
|
||||
public static Object[] loadHtml(String flag, String url) {
|
||||
try {
|
||||
url = new String(Base64.decode(url, Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");
|
||||
String html = "\n" +
|
||||
"<!doctype html>\n" +
|
||||
"<html>\n" +
|
||||
"<head>\n" +
|
||||
"<title>解析</title>\n" +
|
||||
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n" +
|
||||
"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE10\" />\n" +
|
||||
"<meta name=\"renderer\" content=\"webkit|ie-comp|ie-stand\">\n" +
|
||||
"<meta name=\"viewport\" content=\"width=device-width\">\n" +
|
||||
"</head>\n" +
|
||||
"<body>\n" +
|
||||
"<script>\n" +
|
||||
"var apiArray=[#jxs#];\n" +
|
||||
"var urlPs=\"#url#\";\n" +
|
||||
"var iframeHtml=\"\";\n" +
|
||||
"for(var i=0;i<apiArray.length;i++){\n" +
|
||||
"var URL=apiArray[i]+urlPs;\n" +
|
||||
"iframeHtml=iframeHtml+\"<iframe sandbox='allow-scripts allow-same-origin allow-forms' frameborder='0' allowfullscreen='true' webkitallowfullscreen='true' mozallowfullscreen='true' src=\"+URL+\"></iframe>\";\n" +
|
||||
"}\n" +
|
||||
"document.write(iframeHtml);\n" +
|
||||
"</script>\n" +
|
||||
"</body>\n" +
|
||||
"</html>";
|
||||
|
||||
StringBuilder jxs = new StringBuilder();
|
||||
if (flagWebJx.containsKey(flag)) {
|
||||
ArrayList<String> jxUrls = flagWebJx.get(flag);
|
||||
for (int i = 0; i < jxUrls.size(); i++) {
|
||||
jxs.append("\"");
|
||||
jxs.append(jxUrls.get(i));
|
||||
jxs.append("\"");
|
||||
if (i < jxUrls.size() - 1) {
|
||||
jxs.append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
html = html.replace("#url#", url).replace("#jxs#", jxs.toString());
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = "text/html; charset=\"UTF-8\"";
|
||||
ByteArrayInputStream baos = new ByteArrayInputStream(html.toString().getBytes("UTF-8"));
|
||||
result[2] = baos;
|
||||
return result;
|
||||
} catch (Throwable th) {
|
||||
th.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user