diff --git a/app/src/main/java/com/github/catvod/api/YunDrive.java b/app/src/main/java/com/github/catvod/api/YunDrive.java index d3a14770..9865fe20 100644 --- a/app/src/main/java/com/github/catvod/api/YunDrive.java +++ b/app/src/main/java/com/github/catvod/api/YunDrive.java @@ -1,25 +1,34 @@ package com.github.catvod.api; +import com.github.catvod.crawler.SpiderDebug; import com.github.catvod.net.OkHttp; import com.github.catvod.net.OkResult; import com.github.catvod.utils.Json; +import com.github.catvod.utils.Util; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import org.apache.commons.codec.binary.Base64; - -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; +import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.nio.charset.Charset; import java.security.GeneralSecurityException; import java.security.SecureRandom; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + public class YunDrive { private final Pattern regex = Pattern.compile("https://yun\\.139\\.com/shareweb/#/w/i/([^&]+)"); private final SecretKeySpec secretKey; @@ -76,6 +85,14 @@ public class YunDrive { matcher = Pattern.compile("https://caiyun\\.139\\.com/m/i\\?([^&]+)").matcher(url); finded = matcher.find(); } + if (!finded) { + matcher = Pattern.compile("https://yun.139.com/shareweb/#/w/i/([\\w-]+)").matcher(url); + finded = matcher.find(); + } + if (!finded) { + matcher = Pattern.compile("https://caiyun.139.com/w/i/([\\w-]+)").matcher(url); + finded = matcher.find(); + } if (finded) linkID = matcher.group(1); return linkID; @@ -169,7 +186,7 @@ public class YunDrive { for (JsonElement element : response.getAsJsonArray("coLst")) { JsonObject entry = element.getAsJsonObject(); if (entry.get("coType").getAsInt() == 3) { - items.add(Map.of("name", entry.get("coName").getAsString(), "contentId", entry.get("coID").getAsString(), "linkID", linkID)); + items.add(Map.of("name", entry.get("coName").getAsString(), "contentId", entry.get("coID").getAsString(), "linkID", linkID, "path", entry.get("path").getAsString())); } } } else if (response.has("caLst")) { @@ -195,8 +212,66 @@ public class YunDrive { break; } } - return m3u8.split("playlist.m3u8")[0]+resultUrl; + return m3u8.split("playlist.m3u8")[0] + resultUrl; } + public String get4kVideoInfo(String fid, String linkID) throws Exception { + String auth = YunTokenHandler.get().getToken(); + SpiderDebug.log("auth:" + auth); + String phone = StringUtils.split(Util.base64Decode(auth), ":")[1]; + SpiderDebug.log("phone:" + phone); + + // 构建 JSON 请求体 + Map requestBody = new HashMap<>(); + Map dlFromOutLinkReqV3 = new HashMap<>(); + Map commonAccountInfo = new HashMap<>(); + + dlFromOutLinkReqV3.put("linkID", linkID); + dlFromOutLinkReqV3.put("account", phone); + + Map coIDLst = new HashMap<>(); + coIDLst.put("item", Collections.singletonList(fid)); + dlFromOutLinkReqV3.put("coIDLst", coIDLst); + + commonAccountInfo.put("account", phone); + commonAccountInfo.put("accountType", 1); + + requestBody.put("dlFromOutLinkReqV3", dlFromOutLinkReqV3); + requestBody.put("commonAccountInfo", commonAccountInfo); + + /* { + "dlFromOutLinkReqV3" : { + "linkID" : "105CpbaJQFYc6", + "account" : "18896781601", + "coIDLst" : { + "item" : [ "DFTOdJkuAEwA1011ZpAcj1pl039202404112124392cb/Fkco6TgMKlnJwKbVul0ZKeYT5p2hIioVy" ] + } + }, + "commonAccountInfo" : { + "account" : "18896781601", + "accountType" : 1 + } + }*/ + + + // 构建请求 + Map header = new HashMap<>(); + + header.put("X-Deviceinfo", "||3|12.27.0|safari|13.1.2|1||macos 10.15.6|1324X381|zh-cn|||"); + header.put("hcy-cool-flag", "1"); + header.put("Authorization", "Basic " + auth); + header.put("Content-Type", "application/json"); + + + OkResult okResult = OkHttp.post(baseUrl + "dlFromOutLinkV3", encrypt(Json.toJson(requestBody)), header); + JsonObject resultJson = Json.safeObject(decrypt(okResult.getBody())); + if (resultJson.get("resultCode").getAsInt() == 0) { + return resultJson.getAsJsonObject("data").get("redrUrl").getAsString(); + + } + + // 解析 JSON 响应 + return null; + } } diff --git a/app/src/main/java/com/github/catvod/api/YunTokenHandler.java b/app/src/main/java/com/github/catvod/api/YunTokenHandler.java new file mode 100644 index 00000000..82233bdb --- /dev/null +++ b/app/src/main/java/com/github/catvod/api/YunTokenHandler.java @@ -0,0 +1,36 @@ +package com.github.catvod.api; + + +import com.github.catvod.bean.yun.Cache; +import com.github.catvod.bean.yun.User; +import com.github.catvod.utils.Path; + +import java.io.File; + +public class YunTokenHandler { + + private final Cache cache; + + public File getCache() { + return Path.tv("yun139"); + } + + private YunTokenHandler() { + cache = Cache.objectFrom(Path.read(getCache())); + } + + private static class Loader { + static volatile YunTokenHandler INSTANCE = new YunTokenHandler(); + } + + public static YunTokenHandler get() { + return YunTokenHandler.Loader.INSTANCE; + } + + + public String getToken() { + User user = cache.getUser(); + return user.getCookie(); + //return "cGM6MTg4OTY3ODE2MDE6eTM1Tjd1dG58MXxSQ1N8MTc1NDQ2OTgwNzEyOXxzMlN0T1VEV3lOVmF5V3pNbGFfM2tJbVp1ZmlqSHBqaEhTSzVyNHZqVXNRLmlhV3loSUxHNDFkMUI5N1BqXzhWN0dtVWtKLnBTclhpNGpZU1EuTGZWMTV3MVFoZmNpcEVoZkxUV2tvYjB0bkFTYV9RTUhhaHhveWx6YkdmcEhQdjNCS1lrbnp1LkxaWDdKOE40YkNNRjkzT3piNmx2Y0d3TWdVUkl5b18ubVUt"; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/bean/yun/Cache.java b/app/src/main/java/com/github/catvod/bean/yun/Cache.java new file mode 100644 index 00000000..24e73d75 --- /dev/null +++ b/app/src/main/java/com/github/catvod/bean/yun/Cache.java @@ -0,0 +1,39 @@ +package com.github.catvod.bean.yun; + + +import com.github.catvod.api.YunTokenHandler; +import com.github.catvod.spider.Init; +import com.github.catvod.utils.Path; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; + +public class Cache { + + @SerializedName("user") + private User user; + + + public static Cache objectFrom(String str) { + Cache item = new Gson().fromJson(str, Cache.class); + return item == null ? new Cache() : item; + } + + public User getUser() { + return user == null ? new User("") : user; + } + + public void setUser(User user) { + this.user = user; + this.save(); + } + + + public void save() { + Init.execute(() -> Path.write(YunTokenHandler.get().getCache(), toString())); + } + + @Override + public String toString() { + return new Gson().toJson(this); + } +} diff --git a/app/src/main/java/com/github/catvod/bean/yun/User.java b/app/src/main/java/com/github/catvod/bean/yun/User.java new file mode 100644 index 00000000..ee79d743 --- /dev/null +++ b/app/src/main/java/com/github/catvod/bean/yun/User.java @@ -0,0 +1,30 @@ +package com.github.catvod.bean.yun; + +import com.google.gson.annotations.SerializedName; + +public class User { + public User(String cookie) { + this.cookie = cookie; + } + + @SerializedName("cookie") + private String cookie; + + public String getCookie() { + return cookie; + } + + public void setCookie(String cookie) { + this.cookie = cookie; + } + + public static User objectFrom(String cookie) { + return new User(cookie); + } + + + public void clean() { + this.cookie = ""; + + } +} diff --git a/app/src/main/java/com/github/catvod/spider/YiDongYun.java b/app/src/main/java/com/github/catvod/spider/YiDongYun.java index 8c2c6a65..286ce7d0 100644 --- a/app/src/main/java/com/github/catvod/spider/YiDongYun.java +++ b/app/src/main/java/com/github/catvod/spider/YiDongYun.java @@ -2,11 +2,13 @@ package com.github.catvod.spider; import android.content.Context; import android.text.TextUtils; + import com.github.catvod.api.YunDrive; import com.github.catvod.bean.Result; import com.github.catvod.bean.Vod; import com.github.catvod.crawler.Spider; import com.github.catvod.crawler.SpiderDebug; + import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -49,7 +51,20 @@ public class YiDongYun extends Spider { } } - builder.append("移动", list); + builder.append("移动(极速)", list); + List list2 = new ArrayList<>(); + + for (String s : result.keySet()) { + vodName = s; + for (Map stringStringMap : result.get(s)) { + Vod.VodPlayBuilder.PlayUrl playUrl = new Vod.VodPlayBuilder.PlayUrl(); + playUrl.url = stringStringMap.get("path") + "++" + stringStringMap.get("linkID"); + playUrl.name = stringStringMap.get("name"); + list2.add(playUrl); + } + + } + builder.append("移动(原画)", list2); Vod.VodPlayBuilder.BuildResult buildResult = builder.build(); Vod vod = new Vod(); vod.setVodId(ids.get(0)); @@ -65,9 +80,17 @@ public class YiDongYun extends Spider { @Override public String playerContent(String flag, String id, List vipFlags) throws Exception { - String contentId = id.split("\\+\\+")[0]; - String linkID = id.split("\\+\\+")[1]; - String playContent = YunDrive.get().fetchPlayUrl(contentId, linkID); + String playContent = ""; + if (flag.contains("原画")) { + String contentId = id.split("\\+\\+")[0]; + String linkID = id.split("\\+\\+")[1]; + playContent = YunDrive.get().get4kVideoInfo(contentId, linkID); + + } else { + String contentId = id.split("\\+\\+")[0]; + String linkID = id.split("\\+\\+")[1]; + playContent = YunDrive.get().fetchPlayUrl(contentId, linkID); + } SpiderDebug.log("playContent:" + playContent); return Result.get().url(playContent).octet().string(); } @@ -83,7 +106,10 @@ public class YiDongYun extends Spider { List playFrom = new ArrayList<>(); int i = 0; for (String id : ids) { - playFrom.add("移动" + i++); + i++; + playFrom.add("移动(极速)" + i); + playFrom.add("移动(原画)" + i); + } diff --git a/app/src/test/java/YiDongYunTest.java b/app/src/test/java/YiDongYunTest.java index 672f67b3..973ddd4e 100644 --- a/app/src/test/java/YiDongYunTest.java +++ b/app/src/test/java/YiDongYunTest.java @@ -41,7 +41,7 @@ public class YiDongYunTest { @org.junit.Test public void detailContent() throws Exception { - String content = spider.detailContent(Arrays.asList("https://yun.139.com/shareweb/#/w/i/165CkRwb9G885")); + String content = spider.detailContent(Arrays.asList("https://caiyun.139.com/w/i/2nQQVZWCR24yf")); System.out.println("detailContent--" + content); JsonObject map = Json.safeObject(content); Gson gson = new GsonBuilder().setPrettyPrinting().create(); @@ -49,10 +49,15 @@ public class YiDongYunTest { Assert.assertFalse(map.getAsJsonArray("list").isEmpty()); } + /** + * "vod_play_from": "移动(极速)$$$移动(原画)", + * "vod_play_url": "01.mp4$FtgoS0iBwhPFnG-daRU5HJKQ2yBYj8I3x++2nQQVZWCR24yf#02.mp4$FiPG4ttnS-78swp-1sTFG4prNYnLaUvK_++2nQQVZWCR24yf$$$01.mp4$FtB-r8kHUbJFKbzW_r9tJt6YjcTZCVGWR/FtgoS0iBwhPFnG-daRU5HJKQ2yBYj8I3x++2nQQVZWCR24yf#02.mp4$FtB-r8kHUbJFKbzW_r9tJt6YjcTZCVGWR/FiPG4ttnS-78swp-1sTFG4prNYnLaUvK_++2nQQVZWCR24yf" + * @throws Exception + */ @org.junit.Test public void playerContent() throws Exception { - String content = spider.playerContent("普画","41ea9a50cbdd4e50b019bcd78687ebc1++22fc6fa8350d22e0eaecc49035368e81++38c5e16d71f7++WFcYTmRhjJpKTui56aleYdzBZi9R203GERBVzYNxDxI=",new ArrayList<>()); + String content = spider.playerContent("移动(原画)","FtB-r8kHUbJFKbzW_r9tJt6YjcTZCVGWR/FiPG4ttnS-78swp-1sTFG4prNYnLaUvK_++2nQQVZWCR24yf",new ArrayList<>()); System.out.println("playerContent--" + content); JsonObject map = Json.safeObject(content); Gson gson = new GsonBuilder().setPrettyPrinting().create(); diff --git a/app/src/test/java/com/github/catvod/api/YunDriveTest.java b/app/src/test/java/com/github/catvod/api/YunDriveTest.java index 0aff6443..14b15745 100644 --- a/app/src/test/java/com/github/catvod/api/YunDriveTest.java +++ b/app/src/test/java/com/github/catvod/api/YunDriveTest.java @@ -1,6 +1,7 @@ package com.github.catvod.api; import com.github.catvod.bean.tianyi.ShareData; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,14 +28,32 @@ public class YunDriveTest { System.out.println(result); for (String s : result.keySet()) { for (Map stringStringMap : result.get(s)) { - String playUrl = yunDrive.fetchPlayUrl(stringStringMap.get("contentId"),""); - System.out.println(stringStringMap.get("name")+":"+playUrl); + String playUrl = yunDrive.fetchPlayUrl(stringStringMap.get("contentId"), ""); + System.out.println(stringStringMap.get("name") + ":" + playUrl); } } + } + + @Test + public void download() throws Exception { + + Map>> result = yunDrive.processShareData("https://caiyun.139.com/w/i/2nQQVZWCR24yf"); + System.out.println(result); + for (String s : result.keySet()) { + for (Map stringStringMap : result.get(s)) { + String playUrl = yunDrive.fetchPlayUrl(stringStringMap.get("contentId"), stringStringMap.get("linkID")); + String url2 = yunDrive.get4kVideoInfo(stringStringMap.get("linkID"), stringStringMap.get("path")); + System.out.println(stringStringMap.get("name") + ":" + playUrl); + System.out.println(stringStringMap.get("url2") + ":" + url2); + } + } + //; + + } @@ -48,4 +67,5 @@ public class YunDriveTest { } + } \ No newline at end of file