diff --git a/app/src/main/java/com/github/catvod/api/QRCodeHandler.java b/app/src/main/java/com/github/catvod/api/QRCodeHandler.java index 93b8ab8f..e8f1801b 100644 --- a/app/src/main/java/com/github/catvod/api/QRCodeHandler.java +++ b/app/src/main/java/com/github/catvod/api/QRCodeHandler.java @@ -114,8 +114,8 @@ public class QRCodeHandler { put("query_token", queryToken); put("request_id", reqId); }}); - - showQRCode(qrCode); + Init.run(() -> showQRCode(qrCode)); + Init.execute(() -> startService()); /*Map result = new HashMap<>(); result.put("qrcode", "data:image/png;base64," + qrCode); diff --git a/app/src/main/java/com/github/catvod/api/UCApi.java b/app/src/main/java/com/github/catvod/api/UCApi.java index 87d3ab45..24acf1ac 100644 --- a/app/src/main/java/com/github/catvod/api/UCApi.java +++ b/app/src/main/java/com/github/catvod/api/UCApi.java @@ -58,81 +58,6 @@ public class UCApi { private String serviceTicket; private QRCodeHandler qrCodeHandler; - public Object[] proxyVideo(Map params) throws Exception { - String url = Util.base64Decode(params.get("url")); - SpiderDebug.log("proxy url :" + url); - SpiderDebug.log("proxy header :" + Util.base64Decode(params.get("header"))); - Map header = new Gson().fromJson(Util.base64Decode(params.get("header")), Map.class); - if (header == null) header = new HashMap<>(); - List arr = List.of("Range", "Accept", "Accept-Encoding", "Accept-Language", "Cookie", "Origin", "Referer", "Sec-Ch-Ua", "Sec-Ch-Ua-Mobile", "Sec-Ch-Ua-Platform", "Sec-Fetch-Dest", "Sec-Fetch-Mode", "Sec-Fetch-Site", "User-Agent"); - for (String key : params.keySet()) { - for (String s : arr) { - if (s.toLowerCase().equals(key.toLowerCase())) { - header.put(key, params.get(key)); - } - } - - } - if (Util.getExt(url).contains("m3u8")) { - return getM3u8(url, header); - } - return ProxyVideo.proxy(url, header); - } - - /** - * 代理m3u8 - * - * @param url - * @param header - * @return - */ - private Object[] getM3u8(String url, Map header) { - SpiderDebug.log("m3u8 url :" + url); - OkResult result = OkHttp.get(url, new HashMap<>(), header); - String[] m3u8Arr = result.getBody().split("\n"); - List listM3u8 = new ArrayList<>(); - - String site = url.substring(0, url.lastIndexOf("/")) + "/"; - int mediaId = 0; - for (String oneLine : m3u8Arr) { - String thisOne = oneLine; - - if (oneLine.contains(".ts")) { - mediaId++; - thisOne = proxyVideoUrl(site + thisOne, header); - SpiderDebug.log("m3u8 line " + mediaId + ":" + oneLine); - SpiderDebug.log("m3u8 proxyed line " + mediaId + " :" + thisOne); - - } - listM3u8.add(thisOne); - } - String m3u8Str = TextUtils.join("\n", listM3u8); - String contentType = result.getResp().get("Content-Type").get(0); - - Map respHeaders = new HashMap<>(); - // respHeaders.put("Access-Control-Allow-Origin","*"); - // respHeaders.put("Access-Control-Allow-Credentials","true"); - for (String key : result.getResp().keySet()) { - respHeaders.put(key, result.getResp().get(key).get(0)); - } - return new Object[]{result.getCode(), contentType, new ByteArrayInputStream(m3u8Str.getBytes(Charset.defaultCharset())), respHeaders}; - } - - private static class Loader { - static volatile UCApi INSTANCE = new UCApi(); - } - - public static UCApi get() { - return UCApi.Loader.INSTANCE; - } - - public void setCookie(String token) throws Exception { - if (StringUtils.isNoneBlank(token)) { - this.cookie = token; - initUserInfo(); - } - } - private Map getHeaders() { Map headers = new HashMap<>(); headers.put("User-Agent", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36"); @@ -151,11 +76,9 @@ public class UCApi { return headers; } - public void initUc(String cookie) throws Exception { - this.ckey = Util.MD5(cookie); - this.cookie = cookie; - this.isVip = getVip(); - } + /* cookieToken = qrCodeHandler.startUC_TOKENScan(); + SpiderDebug.log("扫码登录获取到的cookieToken: " + cookieToken);*/ + private UCApi() { Init.checkPermission(); @@ -165,6 +88,82 @@ public class UCApi { this.cookieToken = cache.getUser().getToken(); } + private static class Loader { + static volatile UCApi INSTANCE = new UCApi(); + } + + public static UCApi get() { + return UCApi.Loader.INSTANCE; + } + + //从配置中获取cookie + public void setCookie(String token) throws Exception { + if (StringUtils.isNoneBlank(token)) { + this.cookie = token; + initUserInfo(); + + } + } + + /** + * 初始化UC信息 + */ + private void initUserInfo() { + try { + SpiderDebug.log("uc initUserInfo..."); + + //extend没有cookie,从缓存中获取 + if (StringUtils.isAllBlank(cookie)) { + SpiderDebug.log("uc cookie from ext is empty..."); + cookie = cache.getUser().getCookie(); + } + //获取到cookie,初始化uc,并且把cookie缓存一次 + if (StringUtils.isNoneBlank(cookie) && cookie.contains("__pus")) { + SpiderDebug.log(" initUc ..."); + initUc(this.cookie); + cache.setUser(User.objectFrom(this.cookie)); + return; + } + + //没有cookie,也没有serviceTicket,抛出异常,提示用户重新登录 + if (StringUtils.isAllBlank(cookie) && StringUtils.isAllBlank(serviceTicket)) { + SpiderDebug.log("uccookie为空"); + throw new RuntimeException("uccookie为空"); + } + + String token = serviceTicket; + OkResult result = OkHttp.get("https://drive.uc.cn/account/info?st=" + token + "", new HashMap<>(), getWebHeaders()); + Map json = Json.parseSafe(result.getBody(), Map.class); + if (json.get("success").equals(Boolean.TRUE)) { + List cookies = result.getResp().get("set-Cookie"); + List cookieList = new ArrayList<>(); + for (String cookie : cookies) { + cookieList.add(cookie.split(";")[0]); + } + this.cookie += TextUtils.join(";", cookieList); + + cache.setUser(User.objectFrom(this.cookie)); + if (cache.getUser().getCookie().isEmpty()) throw new Exception(this.cookie); + initUc(this.cookie); + } + + } catch (Exception e) { + cache.getUser().clean(); + e.printStackTrace(); + stopService(); + startFlow(); + } finally { + while (cache.getUser().getCookie().isEmpty()) SystemClock.sleep(250); + } + } + + public void initUc(String cookie) throws Exception { + this.ckey = Util.MD5(cookie); + this.cookie = cookie; + this.isVip = getVip(); + } + + public File getCache() { return Path.tv("uc"); } @@ -230,6 +229,66 @@ public class UCApi { return String.format(Proxy.getUrl() + "?do=uc&type=video&url=%s&header=%s", Util.base64Encode(url.getBytes(Charset.defaultCharset())), Util.base64Encode(Json.toJson(header).getBytes(Charset.defaultCharset()))); } + public Object[] proxyVideo(Map params) throws Exception { + String url = Util.base64Decode(params.get("url")); + SpiderDebug.log("proxy url :" + url); + SpiderDebug.log("proxy header :" + Util.base64Decode(params.get("header"))); + Map header = new Gson().fromJson(Util.base64Decode(params.get("header")), Map.class); + if (header == null) header = new HashMap<>(); + List arr = List.of("Range", "Accept", "Accept-Encoding", "Accept-Language", "Cookie", "Origin", "Referer", "Sec-Ch-Ua", "Sec-Ch-Ua-Mobile", "Sec-Ch-Ua-Platform", "Sec-Fetch-Dest", "Sec-Fetch-Mode", "Sec-Fetch-Site", "User-Agent"); + for (String key : params.keySet()) { + for (String s : arr) { + if (s.toLowerCase().equals(key.toLowerCase())) { + header.put(key, params.get(key)); + } + } + + } + if (Util.getExt(url).contains("m3u8")) { + return getM3u8(url, header); + } + return ProxyVideo.proxy(url, header); + } + + /** + * 代理m3u8 + * + * @param url + * @param header + * @return + */ + private Object[] getM3u8(String url, Map header) { + SpiderDebug.log("m3u8 url :" + url); + OkResult result = OkHttp.get(url, new HashMap<>(), header); + String[] m3u8Arr = result.getBody().split("\n"); + List listM3u8 = new ArrayList<>(); + + String site = url.substring(0, url.lastIndexOf("/")) + "/"; + int mediaId = 0; + for (String oneLine : m3u8Arr) { + String thisOne = oneLine; + + if (oneLine.contains(".ts")) { + mediaId++; + thisOne = proxyVideoUrl(site + thisOne, header); + SpiderDebug.log("m3u8 line " + mediaId + ":" + oneLine); + SpiderDebug.log("m3u8 proxyed line " + mediaId + " :" + thisOne); + + } + listM3u8.add(thisOne); + } + String m3u8Str = TextUtils.join("\n", listM3u8); + String contentType = result.getResp().get("Content-Type").get(0); + + Map respHeaders = new HashMap<>(); + // respHeaders.put("Access-Control-Allow-Origin","*"); + // respHeaders.put("Access-Control-Allow-Credentials","true"); + for (String key : result.getResp().keySet()) { + respHeaders.put(key, result.getResp().get(key).get(0)); + } + return new Object[]{result.getCode(), contentType, new ByteArrayInputStream(m3u8Str.getBytes(Charset.defaultCharset())), respHeaders}; + } + /** * @param url * @param params get 参数 @@ -273,54 +332,6 @@ public class UCApi { return okResult.getBody(); } - private void initUserInfo() { - try { - SpiderDebug.log("uc initUserInfo..."); - - //extend没有cookie,从缓存中获取 - if (StringUtils.isAllBlank(cookie)) { - SpiderDebug.log("uc cookie from ext is empty..."); - cookie = cache.getUser().getCookie(); - } - //获取到cookie,初始化uc,并且把cookie缓存一次 - if (StringUtils.isNoneBlank(cookie) && cookie.contains("__pus")) { - SpiderDebug.log(" initUc ..."); - initUc(this.cookie); - cache.setUser(User.objectFrom(this.cookie)); - return; - } - - //没有cookie,也没有serviceTicket,抛出异常,提示用户重新登录 - if (StringUtils.isAllBlank(cookie) && StringUtils.isAllBlank(serviceTicket)) { - SpiderDebug.log("uccookie为空"); - throw new RuntimeException("uccookie为空"); - } - - String token = serviceTicket; - OkResult result = OkHttp.get("https://drive.uc.cn/account/info?st=" + token + "", new HashMap<>(), getWebHeaders()); - Map json = Json.parseSafe(result.getBody(), Map.class); - if (json.get("success").equals(Boolean.TRUE)) { - List cookies = result.getResp().get("set-Cookie"); - List cookieList = new ArrayList<>(); - for (String cookie : cookies) { - cookieList.add(cookie.split(";")[0]); - } - this.cookie += TextUtils.join(";", cookieList); - - cache.setUser(User.objectFrom(this.cookie)); - if (cache.getUser().getCookie().isEmpty()) throw new Exception(this.cookie); - initUc(this.cookie); - } - - } catch (Exception e) { - cache.getUser().clean(); - e.printStackTrace(); - stopService(); - startFlow(); - } finally { - while (cache.getUser().getCookie().isEmpty()) SystemClock.sleep(250); - } - } /** * 获取二维码登录的令牌 @@ -683,18 +694,17 @@ public class UCApi { } //token 为空,扫码登录 - if (StringUtils.isBlank(cookieToken)) { - cookieToken = qrCodeHandler.startUC_TOKENScan(); - SpiderDebug.log("扫码登录获取到的cookieToken: " + cookieToken); + if (StringUtils.isNoneBlank(cookieToken)) { + SpiderDebug.log("cookieToken不为空: " + cookieToken + ";开始下载"); + qrCodeHandler.download(cookieToken, this.saveFileIdCaches.get(fileId)); + } else { + Map down = Json.parseSafe(api("file/download?" + this.pr + "&uc_param_str=", Collections.emptyMap(), Map.of("fids", List.of(this.saveFileIdCaches.get(fileId))), 0, "POST"), Map.class); + if (down.get("data") != null) { + return ((List>) down.get("data")).get(0).get("download_url").toString(); + } } - SpiderDebug.log("cookieToken不为空: " + cookieToken + ";开始下载"); - qrCodeHandler.download(cookieToken, this.saveFileIdCaches.get(fileId)); - /* Map down = Json.parseSafe(api("file/download?" + this.pr + "&uc_param_str=", Collections.emptyMap(), Map.of("fids", List.of(this.saveFileIdCaches.get(fileId))), 0, "POST"), Map.class); - if (down.get("data") != null) { - return ((List>) down.get("data")).get(0).get("download_url").toString(); - }*/ return null; } diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index 1b583e2f..0101aa72 100644 Binary files a/jar/custom_spider.jar and b/jar/custom_spider.jar differ diff --git a/jar/custom_spider.jar.md5 b/jar/custom_spider.jar.md5 index f737f139..f10da4e3 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -3b08198a806ecc12e7211453f314fb37 +a00ec8ec69d7fbf02a7e3b80d1cd7b2f diff --git a/json/index.json b/json/index.json index 7e27bedc..927f0bd5 100644 --- a/json/index.json +++ b/json/index.json @@ -1,5 +1,5 @@ { - "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;3b08198a806ecc12e7211453f314fb37", + "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;a00ec8ec69d7fbf02a7e3b80d1cd7b2f", "lives": [ { diff --git a/json/index1.json b/json/index1.json index db6dac34..ad906926 100644 --- a/json/index1.json +++ b/json/index1.json @@ -1,5 +1,5 @@ { - "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;3b08198a806ecc12e7211453f314fb37", + "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;a00ec8ec69d7fbf02a7e3b80d1cd7b2f", "lives": [ { "name": "直播ipv6", diff --git a/json/index2.json b/json/index2.json index 3120dc68..667ee0ee 100644 --- a/json/index2.json +++ b/json/index2.json @@ -1,5 +1,5 @@ { - "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;3b08198a806ecc12e7211453f314fb37", + "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;a00ec8ec69d7fbf02a7e3b80d1cd7b2f", "lives": [ { "name": "直播ipv6", diff --git a/json/test.json b/json/test.json index 0f7db35d..18240b2e 100644 --- a/json/test.json +++ b/json/test.json @@ -1,5 +1,5 @@ { - "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;3b08198a806ecc12e7211453f314fb37", + "spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;a00ec8ec69d7fbf02a7e3b80d1cd7b2f", "lives": [ { "name": "直播",