Update ali and clean config

This commit is contained in:
FongMi 2023-03-17 18:42:21 +08:00
parent d39d455d39
commit 428a86eea5
8 changed files with 44 additions and 227 deletions

View File

@ -11,7 +11,6 @@ android {
minSdk 17 minSdk 17
targetSdk 29 targetSdk 29
ndk { abiFilters "armeabi-v7a" } ndk { abiFilters "armeabi-v7a" }
buildConfigField("String", "APP_ID", "\"${appId}\"")
buildConfigField("String", "CLIENT_ID", "\"${clientId}\"") buildConfigField("String", "CLIENT_ID", "\"${clientId}\"")
} }
@ -37,7 +36,6 @@ android {
dependencies { dependencies {
//Debug For HTTP/3 //Debug For HTTP/3
debugImplementation 'org.chromium.net:cronet-embedded:101.4951.41' debugImplementation 'org.chromium.net:cronet-embedded:101.4951.41'
implementation 'com.starkbank.ellipticcurve:starkbank-ecdsa:1.0.2'
implementation 'com.google.net.cronet:cronet-okhttp:0.1.0' implementation 'com.google.net.cronet:cronet-okhttp:0.1.0'
implementation 'androidx.annotation:annotation:1.5.0' implementation 'androidx.annotation:annotation:1.5.0'
implementation 'com.squareup.okhttp3:okhttp:3.12.13' implementation 'com.squareup.okhttp3:okhttp:3.12.13'

View File

@ -4,7 +4,6 @@ import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.net.UrlQuerySanitizer;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@ -26,9 +25,6 @@ import com.github.catvod.utils.Prefers;
import com.github.catvod.utils.QRCode; import com.github.catvod.utils.QRCode;
import com.github.catvod.utils.Trans; import com.github.catvod.utils.Trans;
import com.github.catvod.utils.Utils; import com.github.catvod.utils.Utils;
import com.starkbank.ellipticcurve.Ecdsa;
import com.starkbank.ellipticcurve.PrivateKey;
import com.starkbank.ellipticcurve.utils.BinaryAscii;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
@ -43,13 +39,11 @@ import java.util.Map;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class API { public class API {
private final Map<String, String> quality;
private ScheduledExecutorService service; private ScheduledExecutorService service;
private Map<String, String> mediaId2Url;
private final ReentrantLock lock;
private AlertDialog dialog; private AlertDialog dialog;
private String shareToken; private String shareToken;
private final Auth auth; private final Auth auth;
@ -64,8 +58,14 @@ public class API {
} }
private API() { private API() {
this.lock = new ReentrantLock(true); auth = Auth.objectFrom(Prefers.getString("aliyundrive"));
this.auth = Auth.objectFrom(Prefers.getString("aliyundrive")); quality = new HashMap<>();
quality.put("4K", "UHD");
quality.put("2k", "QHD");
quality.put("超清", "FHD");
quality.put("高清", "HD");
quality.put("標清", "SD");
quality.put("流暢", "LD");
} }
public void setRefreshToken(String token) { public void setRefreshToken(String token) {
@ -98,13 +98,6 @@ public class API {
return headers; return headers;
} }
private HashMap<String, String> getHeaderSign() {
HashMap<String, String> headers = getHeaderAuth();
headers.put("x-device-id", auth.getDeviceId());
headers.put("x-signature", auth.getSignature());
return headers;
}
private String post(String url, JSONObject body) { private String post(String url, JSONObject body) {
url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url; url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url;
return OkHttp.postJson(url, body.toString(), getHeader()); return OkHttp.postJson(url, body.toString(), getHeader());
@ -123,25 +116,16 @@ public class API {
} }
private String oauth(String url, String json, boolean retry) { private String oauth(String url, String json, boolean retry) {
url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url; url = url.startsWith("https") ? url : "https://open.aliyundrive.com/adrive/v1.0/" + url;
String result = OkHttp.postJson(url, json, getHeaderOpen()); String result = OkHttp.postJson(url, json, getHeaderOpen());
Log.e("oauth", result); Log.e("oauth", result);
if (retry && checkOpen(result)) return oauth(url, json, false); if (retry && checkOpen(result)) return oauth(url, json, false);
return result; return result;
} }
private String sign(String url, String json, boolean retry) {
url = url.startsWith("https") ? url : "https://api.aliyundrive.com/" + url;
String result = OkHttp.postJson(url, json, getHeaderSign());
Log.e("sign", result);
if (retry && checkAuth(result)) return sign(url, json, false);
return result;
}
private boolean checkAuth(String result) { private boolean checkAuth(String result) {
if (result.contains("AccessTokenInvalid")) return refreshAccessToken(); if (result.contains("AccessTokenInvalid")) return refreshAccessToken();
if (result.contains("ShareLinkTokenInvalid") || result.contains("InvalidParameterNotMatch")) return refreshShareToken(); if (result.contains("ShareLinkTokenInvalid") || result.contains("InvalidParameterNotMatch")) return refreshShareToken();
if (result.contains("UserDeviceOffline") || result.contains("UserDeviceIllegality") || result.contains("DeviceSessionSignatureInvalid")) return refreshSignature();
return false; return false;
} }
@ -154,10 +138,6 @@ public class API {
if (auth.getAccessToken().isEmpty()) refreshAccessToken(); if (auth.getAccessToken().isEmpty()) refreshAccessToken();
} }
private void checkSignature() {
if (auth.getSignature().isEmpty()) refreshSignature();
}
private boolean refreshAccessToken() { private boolean refreshAccessToken() {
try { try {
SpiderDebug.log("refreshAccessToken..."); SpiderDebug.log("refreshAccessToken...");
@ -169,7 +149,6 @@ public class API {
JSONObject object = new JSONObject(post("https://auth.aliyundrive.com/v2/account/token", body)); JSONObject object = new JSONObject(post("https://auth.aliyundrive.com/v2/account/token", body));
Log.e("DDD", object.toString()); Log.e("DDD", object.toString());
auth.setUserId(object.getString("user_id")); auth.setUserId(object.getString("user_id"));
auth.setDeviceId(object.getString("device_id"));
auth.setDriveId(object.getString("default_drive_id")); auth.setDriveId(object.getString("default_drive_id"));
auth.setRefreshToken(object.getString("refresh_token")); auth.setRefreshToken(object.getString("refresh_token"));
auth.setAccessToken(object.getString("token_type") + " " + object.getString("access_token")); auth.setAccessToken(object.getString("token_type") + " " + object.getString("access_token"));
@ -240,31 +219,6 @@ public class API {
} }
} }
private boolean refreshSignature() {
try {
SpiderDebug.log("refreshSignature...");
PrivateKey privateKey = new PrivateKey();
String pubKey = "04" + BinaryAscii.hexFromBinary(privateKey.publicKey().toByteString().getBytes());
String message = BuildConfig.APP_ID + ":" + auth.getDeviceId() + ":" + auth.getUserId() + ":" + 0;
String signature = BinaryAscii.hexFromBinary(Ecdsa.sign(message, privateKey).toDer().getBytes());
auth.setSignature(signature.substring(signature.length() - 128) + "01");
JSONObject body = new JSONObject();
body.put("deviceName", "samsung");
body.put("modelName", "SM-G9810");
body.put("nonce", 0);
body.put("pubKey", pubKey);
body.put("refreshToken", auth.getRefreshToken());
JSONObject object = new JSONObject(sign("users/v1/users/device/create_session", body.toString(), false));
if (!object.getBoolean("success")) throw new Exception(object.toString());
auth.save();
return true;
} catch (Exception e) {
auth.setSignature("");
SpiderDebug.log(e);
return false;
}
}
public Vod getVod(String url, String fileId) throws Exception { public Vod getVod(String url, String fileId) throws Exception {
JSONObject body = new JSONObject(); JSONObject body = new JSONObject();
body.put("share_id", shareId); body.put("share_id", shareId);
@ -360,27 +314,47 @@ public class API {
return sub; return sub;
} }
public String getPreviewUrl(String fileId, String flag) {
return Proxy.getUrl() + "?do=ali&type=m3u8&file_id=" + fileId + "&flag=" + getPreviewQuality(flag);
}
public String getDownloadUrl(String fileId) { public String getDownloadUrl(String fileId) {
try { try {
fileId = copy(fileId); String tempId = copy(fileId);
return TextUtils.isEmpty(fileId) ? "" : open(fileId); JSONObject body = new JSONObject();
body.put("file_id", tempId);
body.put("drive_id", auth.getDriveId());
String url = new JSONObject(oauth("openFile/getDownloadUrl", body.toString(), true)).getString("url");
Init.execute(() -> delete(tempId));
return url;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return ""; return "";
} }
} }
private String open(String fileId) throws Exception { public String getPreviewUrl(String fileId, String flag) {
JSONObject body = new JSONObject(); try {
body.put("file_id", fileId); String tempId = copy(fileId);
body.put("drive_id", auth.getDriveId()); JSONObject body = new JSONObject();
String url = new JSONObject(oauth("https://open.aliyundrive.com/adrive/v1.0/openFile/getDownloadUrl", body.toString(), true)).getString("url"); body.put("file_id", tempId);
Init.execute(() -> delete(fileId)); body.put("drive_id", auth.getDriveId());
return url; body.put("category", "live_transcoding");
body.put("url_expire_sec", "14400");
String json = oauth("openFile/getVideoPreviewPlayInfo", body.toString(), true);
JSONArray taskList = new JSONObject(json).getJSONObject("video_preview_play_info").getJSONArray("live_transcoding_task_list");
Init.execute(() -> delete(tempId));
return getPreviewQuality(taskList, flag);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
private String getPreviewQuality(JSONArray taskList, String flag) throws Exception {
for (int i = 0; i < taskList.length(); ++i) {
JSONObject task = taskList.getJSONObject(i);
if (task.getString("template_id").equals(quality.get(flag))) {
return task.getString("url");
}
}
return taskList.getJSONObject(0).getString("url");
} }
private String copy(String fileId) throws Exception { private String copy(String fileId) throws Exception {
@ -406,95 +380,6 @@ public class API {
return result; return result;
} }
public Object[] proxyM3U8(Map<String, String> params) {
String fileId = params.get("file_id");
String flag = params.get("flag");
Object[] result = new Object[3];
result[0] = 200;
result[1] = "application/vnd.apple.mpegurl";
result[2] = new ByteArrayInputStream(refreshM3U8(fileId, flag).getBytes());
return result;
}
public Object[] proxyMedia(Map<String, String> params) {
try {
String fileId = params.get("file_id");
String mediaId = params.get("media_id");
String flag = params.get("flag");
lock.lock();
String mediaUrl = mediaId2Url.get(mediaId);
long expires = Long.parseLong(new UrlQuerySanitizer(mediaUrl).getValue("x-oss-expires"));
long current = System.currentTimeMillis() / 1000;
if (expires - current <= 60) {
refreshM3U8(fileId, flag);
mediaUrl = mediaId2Url.get(mediaId);
}
lock.unlock();
Object[] result = new Object[3];
result[0] = 200;
result[1] = "video/MP2T";
result[2] = OkHttp.newCall(mediaUrl, getHeader()).body().byteStream();
return result;
} catch (Exception e) {
return null;
}
}
private String refreshM3U8(String fileId, String flag) {
try {
checkSignature();
JSONObject body = new JSONObject();
body.put("file_id", fileId);
body.put("share_id", shareId);
body.put("template_id", "");
body.put("category", "live_transcoding");
String json = sign("v2/file/get_share_link_video_preview_play_info", body.toString(), true);
JSONArray taskList = new JSONObject(json).getJSONObject("video_preview_play_info").getJSONArray("live_transcoding_task_list");
Map<String, List<String>> respHeaders = new HashMap<>();
OkHttp.stringNoRedirect(getPreviewQuality(taskList, flag), getHeader(), respHeaders);
String location = OkHttp.getRedirectLocation(respHeaders);
String m3u8 = OkHttp.string(location, getHeader());
String mediaUrlPrefix = location.substring(0, location.lastIndexOf("/")) + "/";
List<String> lines = new ArrayList<>();
int mediaId = 0;
mediaId2Url = new HashMap<>();
for (String line : m3u8.split("\n")) {
if (line.contains("x-oss-expires")) {
mediaId += 1;
mediaId2Url.put(String.valueOf(mediaId), mediaUrlPrefix + line);
line = Proxy.getUrl() + "?do=ali&type=media" + "&file_id=" + fileId + "&media_id=" + mediaId + "&flag=" + flag;
}
lines.add(line);
}
return TextUtils.join("\n", lines);
} catch (Exception e) {
return "";
}
}
private String getPreviewQuality(String flag) {
switch (flag) {
case "2K":
return "QHD";
case "超清":
return "FHD";
case "高清":
return "HD";
default:
return "";
}
}
private String getPreviewQuality(JSONArray taskList, String flag) throws Exception {
for (int i = 0; i < taskList.length(); ++i) {
JSONObject task = taskList.getJSONObject(i);
if (task.getString("template_id").equals(flag)) {
return task.getString("url");
}
}
return taskList.getJSONObject(0).getString("url");
}
private void getQRCode() { private void getQRCode() {
Data data = Data.objectFrom(OkHttp.string("https://passport.aliyundrive.com/newlogin/qrcode/generate.do?appName=aliyun_drive&fromSite=52&appName=aliyun_drive&appEntrance=web&isMobile=false&lang=zh_CN&returnUrl=&bizParams=&_bx-v=2.2.3")).getContent().getData(); Data data = Data.objectFrom(OkHttp.string("https://passport.aliyundrive.com/newlogin/qrcode/generate.do?appName=aliyun_drive&fromSite=52&appName=aliyun_drive&appEntrance=web&isMobile=false&lang=zh_CN&returnUrl=&bizParams=&_bx-v=2.2.3")).getContent().getData();
Init.run(() -> showQRCode(data)); Init.run(() -> showQRCode(data));

View File

@ -16,10 +16,6 @@ public class Auth {
private String accessToken; private String accessToken;
@SerializedName("accessTokenOpen") @SerializedName("accessTokenOpen")
private String accessTokenOpen; private String accessTokenOpen;
@SerializedName("signature")
private String signature;
@SerializedName("deviceId")
private String deviceId;
@SerializedName("userId") @SerializedName("userId")
private String userId; private String userId;
@SerializedName("driveId") @SerializedName("driveId")
@ -62,22 +58,6 @@ public class Auth {
this.accessTokenOpen = accessTokenOpen; this.accessTokenOpen = accessTokenOpen;
} }
public String getSignature() {
return TextUtils.isEmpty(signature) ? "" : signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getDriveId() { public String getDriveId() {
return TextUtils.isEmpty(driveId) ? "" : driveId; return TextUtils.isEmpty(driveId) ? "" : driveId;
} }
@ -103,7 +83,6 @@ public class Auth {
setAccessTokenOpen(""); setAccessTokenOpen("");
setRefreshToken(""); setRefreshToken("");
setAccessToken(""); setAccessToken("");
setSignature("");
} }
public void save() { public void save() {

View File

@ -45,8 +45,6 @@ public class Ali extends Spider {
public static Object[] vod(Map<String, String> params) { public static Object[] vod(Map<String, String> params) {
String type = params.get("type"); String type = params.get("type");
if (type.equals("sub")) return API.get().proxySub(params); if (type.equals("sub")) return API.get().proxySub(params);
if (type.equals("m3u8")) return API.get().proxyM3U8(params);
if (type.equals("media")) return API.get().proxyMedia(params);
return null; return null;
} }
} }

View File

@ -1,42 +0,0 @@
package com.github.catvod.spider;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.github.catvod.crawler.Spider;
public class Live extends Spider {
private int delay;
@Override
public void init(Context context, String extend) {
super.init(context, extend);
this.delay = delay(extend);
}
@Override
public String homeVideoContent() {
Init.run(this::openLive, delay);
return "";
}
private int delay(String extend) {
try {
return TextUtils.isEmpty(extend) ? 0 : Integer.parseInt(extend);
} catch (Throwable ignored) {
return 0;
}
}
private void openLive() {
try {
Activity activity = Init.getActivity();
activity.startActivity(new Intent().setComponent(new ComponentName(activity, "com.fongmi.android.tv.ui.activity.LiveActivity")));
} catch (Throwable ignored) {
}
}
}

View File

@ -19,5 +19,4 @@ android.useAndroidX=true
# resources declared in the library itself and none from the library's dependencies, # resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library # thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true android.nonTransitiveRClass=true
appId=5dde4e1bdf9e4966b387ba58f4b3fdc3
clientId=76917ccccd4441c39457a04f6084fb2f clientId=76917ccccd4441c39457a04f6084fb2f

Binary file not shown.

View File

@ -1 +1 @@
ed850893fd0c94513677e7b98cc741a8 524ae0e7a345b594779e26ede32e09dd