diff --git a/app/src/main/java/com/github/catvod/spider/Bili.java b/app/src/main/java/com/github/catvod/spider/Bili.java index 4109b341..92e3a383 100644 --- a/app/src/main/java/com/github/catvod/spider/Bili.java +++ b/app/src/main/java/com/github/catvod/spider/Bili.java @@ -1,17 +1,26 @@ package com.github.catvod.spider; +import android.annotation.TargetApi; import android.content.Context; +import android.os.Build; import android.text.TextUtils; +import android.view.Gravity; +import android.webkit.CookieManager; +import android.widget.FrameLayout; +import android.widget.ImageView; 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.Prefers; +import com.github.catvod.utils.QRCode; import com.github.catvod.utils.Utils; import com.github.catvod.utils.Trans; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import org.jsoup.Jsoup; @@ -19,6 +28,10 @@ import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** * @author ColaMint & FongMi @@ -26,40 +39,47 @@ import java.util.List; public class Bili extends Spider { private static final String url = "https://www.bilibili.com"; - private HashMap header; private JSONObject ext; - private String extend; + private ScheduledExecutorService service; + private ImageView view; + private static boolean login; + private static String finalUrl = ""; + private static boolean FirstTime = false; + private static String cookie = ""; - private String getCookie(String cookie) { - if (TextUtils.isEmpty(cookie)) return "buvid3=84B0395D-C9F2-C490-E92E-A09AB48FE26E71636infoc"; - if (cookie.startsWith("http")) return OkHttp.string(cookie).replace("\n", ""); - return cookie; + private void getCookie() { + cookie = Prefers.getString("BiliCookie", ""); + HashMap> respHeaderMap = new HashMap<>(); + OkHttp.string(url, getHeaders(), respHeaderMap); + if (cookie.isEmpty()) { + for (String kk : Objects.requireNonNull(respHeaderMap.get("set-cookie"))) { + cookie += kk.split(";")[0] + ";"; + } + } } - private void setHeader() throws Exception { - header.put("cookie", getCookie(ext.getString("cookie"))); - header.put("User-Agent", Utils.CHROME); - header.put("Referer", url); - } - - private void fetchExt() { - String result = OkHttp.string(extend); - if (!TextUtils.isEmpty(result)) extend = result; - } - - private void fetchRule() throws Exception { - if (header.containsKey("cookie") && header.get("cookie").length() > 0) return; - if (extend.startsWith("http")) fetchExt(); - ext = new JSONObject(extend); - setHeader(); + private static HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Utils.CHROME); + headers.put("Referer", url); + if (!cookie.isEmpty()) headers.put("cookie", cookie); + return headers; } @Override public void init(Context context, String extend) { try { - this.extend = extend; - this.header = new HashMap<>(); - fetchRule(); + if (extend.startsWith("http")) { + extend = OkHttp.string(extend); + } + ext = new JSONObject(extend); + if (ext.optString("cookie").length() > 0) { + cookie = ext.optString("cookie"); + } else { + getCookie(); + } + String content = OkHttp.string("https://api.bilibili.com/x/web-interface/nav", getHeaders()); + login = new JSONObject(content).getJSONObject("data").getBoolean("isLogin"); } catch (Exception e) { e.printStackTrace(); } @@ -67,13 +87,11 @@ public class Bili extends Spider { @Override public String homeContent(boolean filter) throws Exception { - fetchRule(); return Result.string(Class.arrayFrom(ext.getJSONArray("classes").toString()), ext.getJSONObject("filter")); } @Override public String homeVideoContent() throws Exception { - fetchRule(); return categoryContent("窗 白噪音", "1", true, new HashMap<>()); } @@ -82,7 +100,7 @@ public class Bili extends Spider { String duration = extend.containsKey("duration") ? extend.get("duration") : "0"; if (extend.containsKey("tid")) tid = tid + " " + extend.get("tid"); String url = "https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=" + URLEncoder.encode(tid) + "&duration=" + duration + "&page=" + pg; - JSONObject resp = new JSONObject(OkHttp.string(url, header)); + JSONObject resp = new JSONObject(OkHttp.string(url, getHeaders())); JSONArray result = resp.getJSONObject("data").getJSONArray("result"); List list = new ArrayList<>(); for (int i = 0; i < result.length(); ++i) { @@ -102,10 +120,10 @@ public class Bili extends Spider { public String detailContent(List ids) throws Exception { String bvid = ids.get(0); String bvid2aidUrl = "https://api.bilibili.com/x/web-interface/archive/stat?bvid=" + bvid; - JSONObject bvid2aidResp = new JSONObject(OkHttp.string(bvid2aidUrl, header)); + JSONObject bvid2aidResp = new JSONObject(OkHttp.string(bvid2aidUrl, getHeaders())); String aid = bvid2aidResp.getJSONObject("data").getLong("aid") + ""; String detailUrl = "https://api.bilibili.com/x/web-interface/view?aid=" + aid; - JSONObject detailResp = new JSONObject(OkHttp.string(detailUrl, header)); + JSONObject detailResp = new JSONObject(OkHttp.string(detailUrl, getHeaders())); JSONObject detailData = detailResp.getJSONObject("data"); List playlist = new ArrayList<>(); JSONArray pages = detailData.getJSONArray("pages"); @@ -133,12 +151,77 @@ public class Bili extends Spider { @Override public String playerContent(String flag, String id, List vipFlags) throws Exception { + if (!login && !FirstTime) { + FirstTime = true; + checkService(); + getQRCode(); + } String[] ids = id.split("\\+"); String aid = ids[0]; String cid = ids[1]; String url = "https://api.bilibili.com/x/player/playurl?avid=" + aid + "&cid=" + cid + "&qn=120&fourk=1"; - JSONObject resp = new JSONObject(OkHttp.string(url, header)); + JSONObject resp = new JSONObject(OkHttp.string(url, getHeaders())); url = resp.getJSONObject("data").getJSONArray("durl").getJSONObject(0).getString("url"); - return Result.get().url(url).header(header).string(); + return Result.get().url(url).header(getHeaders()).string(); + } + + private void checkService() { + if (service != null) service.shutdownNow(); + if (view != null) Init.run(() -> Utils.removeView(view)); + } + + private void getQRCode() throws JSONException { + JSONObject data = new JSONObject(OkHttp.string("https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-mini", null)); + String qrcode = data.getJSONObject("data").getString("url"); + Init.run(() -> showCode(qrcode)); + service = Executors.newScheduledThreadPool(1); + service.scheduleAtFixedRate(() -> { + try { + String qr = data.getJSONObject("data").getString("qrcode_key"); + String url = "https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=" + qr + "&source=main_mini"; + String content = OkHttp.string(url, getHeaders()); + finalUrl = new JSONObject(content).getJSONObject("data").getString("url"); + } catch (JSONException e) { + e.printStackTrace(); + } + if (!finalUrl.isEmpty()) setCookie(finalUrl); + }, 1, 1, TimeUnit.SECONDS); + } + + private void setCookie(String value) { + finalUrl = value; + loadWebView(); + Init.show("请重新进入播放页"); + checkService(); + } + + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void loadWebView() { + CookieManager cookieManager = CookieManager.getInstance(); + cookieManager.flush(); + cookieManager.removeAllCookies(null); + cookieManager.removeSessionCookies(null); + HashMap> respHeaderMap = new HashMap<>(); + OkHttp.stringNoRedirect(finalUrl, getHeaders(), respHeaderMap); + cookie = ""; + for (String kk : Objects.requireNonNull(respHeaderMap.get("set-cookie"))) { + cookie += kk.split(";")[0] + ";"; + } + Prefers.put("BiliCookie", cookie); + } + + private void showCode(String text) { + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); + params.gravity = Gravity.CENTER; + Utils.addView(view = create(text), params); + Init.show("请使用 BiliBili App 扫描二维码"); + } + + private ImageView create(String value) { + ImageView view = new ImageView(Init.context()); + view.setScaleType(ImageView.ScaleType.CENTER_CROP); + view.setImageBitmap(QRCode.getBitmap(value, 250, 2)); + return view; } }