diff --git a/.github/release.info b/.github/release.info
index f3512882..f7c7080c 100644
--- a/.github/release.info
+++ b/.github/release.info
@@ -1,5 +1,9 @@
-* 修复`V6.24`引入的一个bug,该bug导致jar包路径存在空格或者中文时,程序不能正确运行。
-* 优化: 出现报错弹窗时,输出更详细的异常信息
+* 修复: [issues 146](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/146),[issues 147](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/147) 解决api更换导致的UP主所有视频无法查询的问题
+* 修复: [issues 149](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/149), 作品信息页面尝试兼容mac下的UI布局
+* 优化: [issues 140](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/140) 卸载脚本增加更多提示
+* 优化: [issues 141](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/141) 增加配置`bilibili.alert.qualityUnexpected`,可以开启/关闭对非期望的低画质清晰度视频的判断
+* 优化: [issues 145](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/145) 增加相关配置,可以针对不同分辨率设置不同的视频编码优先级
+* 优化: 现在可以直接在程序代码中刷新cookie,而不必再打开浏览器
如果你是Win64用户,且没有java环境,请下载附件`*.win_x64_jre11.release.zip`
\ No newline at end of file
diff --git a/.github/workflows/upload-manually.yml b/.github/workflows/upload-manually.yml
index 86c2da61..7e99dfdb 100644
--- a/.github/workflows/upload-manually.yml
+++ b/.github/workflows/upload-manually.yml
@@ -108,7 +108,7 @@ jobs:
RAILWAY_AUTH: ${{ secrets.RAILWAY_AUTH }}
if: ${{ always() && env.RAILWAY_AUTH != '' && github.event.inputs.railwayFFmpeg == 'true'}}
run: |
- wget https://git.nicelee.top/nICEnnnnnnnLee/BilibiliDown/releases/download/V4.5/ffmpeg_N-108857-g00b03331a0-20221027.exe
+ wget https://github.com/nICEnnnnnnnLee/BilibiliDown/releases/download/V4.5/ffmpeg_N-108857-g00b03331a0-20221027.exe
curl -X POST "https://bili.up.railway.app/upload" \
--cookie "auth=$RAILWAY_AUTH" \
-F "file=@ffmpeg_N-108857-g00b03331a0-20221027.exe;type=application/octet-stream"
diff --git a/README.md b/README.md
index 62899512..7f78fd4a 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ Bilibili 视频下载器,用于下载B站视频。
* 使用[zxing](https://github.com/zxing/zxing)库生成链接二维码图片[![](https://img.shields.io/badge/license-Apache%202-green.svg)](https://raw.githubusercontent.com/zxing/zxing/master/LICENSE)
* 以外部库的方式调用[ffmpeg](http://www.ffmpeg.org)进行转码(短片段flv未使用ffmpeg,仅多flv合并及m4s转换mp4格式需要用到)[![](https://img.shields.io/badge/license-depends-orange.svg)](http://www.ffmpeg.org/legal.html)
* geetest验证码实现参考了[geetest-validator](https://github.com/kuresaru/geetest-validator)[![](https://img.shields.io/badge/license-unknown-gray.svg)](https://github.com/kuresaru/geetest-validator)
+* cookie刷新代码的wasm逆向实现参考了[SocialSisterYi/bilibili-API-collect#524](https://github.com/SocialSisterYi/bilibili-API-collect/issues/524#issuecomment-1537519232)[![](https://img.shields.io/badge/license-CC%20BY%20NC%204.0-green.svg)](https://github.com/SocialSisterYi/bilibili-API-collect/issues/524#issuecomment-1537519232)
## :smile:其它
* **下载地址**:
diff --git a/UPDATE.md b/UPDATE.md
index 537b95fa..5d5dc891 100644
--- a/UPDATE.md
+++ b/UPDATE.md
@@ -1,4 +1,12 @@
## UPDATE
+* V6.26 `2023-06-06`
+ * 修复: [issues 146](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/146),[issues 147](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/147) 解决api更换导致的UP主所有视频无法查询的问题
+ * 修复: [issues 149](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/149), 作品信息页面尝试兼容mac下的UI布局
+ * 优化: [issues 140](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/140) 卸载脚本增加更多提示
+ * 优化: [issues 141](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/141) 增加配置`bilibili.alert.qualityUnexpected`,可以开启/关闭对非期望的低画质清晰度视频的判断
+ * 优化: [issues 145](https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/145) 增加相关配置,可以针对不同分辨率设置不同的视频编码优先级
+ * 优化: 现在可以直接在程序代码中刷新cookie,而不必再打开浏览器
+
* V6.25 `2023-03-23`
* 修复`V6.24`引入的一个bug,该bug导致jar包路径存在空格或者中文时,程序不能正确运行。
* 优化: 出现报错弹窗时,输出更详细的异常信息
diff --git a/release/uninstall.bat b/release/uninstall.bat
index f6394742..0911a89b 100644
--- a/release/uninstall.bat
+++ b/release/uninstall.bat
@@ -1,4 +1,6 @@
@echo off
+echo ĿļΪ %~dp0
+echo ýűɾļµļ
set/p option=ж밴yȷ:
if "%option%"=="y" echo y &goto :unistall
if "%option%"=="Y" echo Y &goto :unistall
diff --git a/src/nicelee/bilibili/parsers/impl/AbstractBaseParser.java b/src/nicelee/bilibili/parsers/impl/AbstractBaseParser.java
index 5e754421..268a9f2c 100644
--- a/src/nicelee/bilibili/parsers/impl/AbstractBaseParser.java
+++ b/src/nicelee/bilibili/parsers/impl/AbstractBaseParser.java
@@ -323,7 +323,7 @@ String getVideoLinkByFormat(String bvId, String cid, int qn, int downloadFormat)
int linkQN = jObj.getInt("quality");
paramSetter.setRealQN(linkQN);
System.out.println("查询质量为:" + qn + "的链接, 得到质量为:" + linkQN + "的链接");
- if(linkQN < 64 && qn > linkQN && Global.isLogin) {
+ if(Global.alertIfQualityUnexpected && linkQN < 64 && qn > linkQN && Global.isLogin) {
throw new QualityTooLowException(bvId + " : " + cid + " - 查询质量为:" + qn + "的链接, 得到质量为:" + linkQN + "的链接");
}
try {
@@ -468,8 +468,11 @@ protected String parseType1(JSONObject jObj, int linkQN, HashMap
System.out.println("API返回质量为:" + linkQN + "的链接, 实际上只有质量为:" + paramSetter.getRealQN() + "的链接");
qnVideos.add(v);
}
+ // 根据清晰度选择合适的编码优先级
+ Integer rQN = Integer.valueOf(paramSetter.getRealQN());
+ int[] videoCodecPriority = Global.videoCodecPriorityMap.getOrDefault(rQN, Global.videoCodecPriority);
// 根据需求选择编码合适的视频
- JSONObject video = findMediaByPriList(qnVideos, Global.videoCodecPriority, 0);
+ JSONObject video = findMediaByPriList(qnVideos, videoCodecPriority, 0);
// 选择可以连通的链接
String videoLink = getUrlOfMedia(video, Global.checkDashUrl, headerForValidCheck);
link.append(videoLink).append("#");
diff --git a/src/nicelee/bilibili/parsers/impl/EPParser.java b/src/nicelee/bilibili/parsers/impl/EPParser.java
index d7a3e62f..eadd053f 100644
--- a/src/nicelee/bilibili/parsers/impl/EPParser.java
+++ b/src/nicelee/bilibili/parsers/impl/EPParser.java
@@ -2,6 +2,7 @@
import java.util.regex.Pattern;
+import org.json.JSONArray;
import org.json.JSONObject;
import nicelee.bilibili.annotations.Bilibili;
@@ -40,23 +41,28 @@ public VideoInfo result(String input, int videoFormat, boolean getVideoLink) {
}
/**
- * 已知epId, 求bvId 目前没有抓到api哦... 暂时从网页里面爬
- *
+ * @see https://www.bilibili.com/bangumi/media/md134912
+ * https://api.bilibili.com/pgc/view/web/season?ep_id=250435
* @input HttpRequestUtil util
*/
private String EpIdToBvId(String epId) {
HttpHeaders headers = new HttpHeaders();
- String url = "https://www.bilibili.com/bangumi/play/" + epId;
- String html = util.getContent(url, headers.getCommonHeaders("www.bilibili.com"));
+ String epIdNumber = epId.replace("ep", "");
+ String url = "https://api.bilibili.com/pgc/view/web/season?ep_id=" + epIdNumber;
+ String json = util.getContent(url, headers.getCommonHeaders("www.bilibili.com"));
- int begin = html.indexOf("window.__INITIAL_STATE__=");
- int end = html.indexOf(";(function()", begin);
- String json = html.substring(begin + 25, end);
Logger.println(json);
- JSONObject jObj = new JSONObject(json);
- String bvid = jObj.getJSONObject("epInfo").getString("bvid");
- Logger.println("bvId为: " + bvid);
- return bvid;
+ JSONObject jObj = new JSONObject(json).getJSONObject("result");
+ JSONArray array = jObj.getJSONArray("episodes");
+ for (int i = 0; i < array.length(); i++) {
+ JSONObject ep = array.getJSONObject(i);
+ if(epIdNumber.equals(ep.optString("id"))) {
+ String bvid = ep.getString("bvid");
+ Logger.println("bvId为: " + bvid);
+ return bvid;
+ }
+ }
+ throw new RuntimeException("No epId found in the page");
}
}
diff --git a/src/nicelee/bilibili/parsers/impl/MdParser.java b/src/nicelee/bilibili/parsers/impl/MdParser.java
index a5e9246d..af7148a6 100644
--- a/src/nicelee/bilibili/parsers/impl/MdParser.java
+++ b/src/nicelee/bilibili/parsers/impl/MdParser.java
@@ -40,23 +40,22 @@ public VideoInfo result(String input, int videoFormat, boolean getVideoLink) {
}
/**
- * 已知MdId, 求SsId 目前没有抓到api哦... 暂时从网页里面爬
- *
+ * @see https://www.bilibili.com/bangumi/media/md134912
+ * https://api.bilibili.com/pgc/review/user?media_id=134912
+ * https://api.bilibili.com/pgc/web/season/section?season_id=25617
* @input HttpRequestUtil util
* @param mdId
* @return
*/
private String MdIdToSsId(String mdId) {
HttpHeaders headers = new HttpHeaders();
- String url = "https://www.bilibili.com/bangumi/media/" + mdId;
- String html = util.getContent(url, headers.getCommonHeaders("www.bilibili.com"));
-
- int begin = html.indexOf("window.__INITIAL_STATE__=");
- int end = html.indexOf(";(function()", begin);
- String json = html.substring(begin + 25, end);
- System.out.println(json);
- JSONObject jObj = new JSONObject(json);
- int ssId = jObj.getJSONObject("mediaInfo").getJSONObject("param").getInt("season_id");
+ String mdIdNumber = mdId.replace("md", "");
+ String url = "https://api.bilibili.com/pgc/review/user?media_id=" + mdIdNumber;
+ String result = util.getContent(url, headers.getCommonHeaders("www.bilibili.com"));
+
+ System.out.println(result);
+ JSONObject jObj = new JSONObject(result);
+ int ssId = jObj.getJSONObject("result").getJSONObject("media").getInt("season_id");
System.out.println("ssId为: " + ssId);
return "ss" + ssId;
}
diff --git a/src/nicelee/bilibili/parsers/impl/SSParser.java b/src/nicelee/bilibili/parsers/impl/SSParser.java
index aef7a6f3..ae788481 100644
--- a/src/nicelee/bilibili/parsers/impl/SSParser.java
+++ b/src/nicelee/bilibili/parsers/impl/SSParser.java
@@ -12,7 +12,7 @@
import nicelee.bilibili.util.HttpHeaders;
import nicelee.bilibili.util.Logger;
-//@Bilibili(name = "ss")
+//@Bilibili(name = "SSParser")
public class SSParser extends AbstractBaseParser {
private final static Pattern pattern = Pattern.compile("(?!/cheese/play/ss[0-9]+)ss[0-9]+");
@@ -44,7 +44,9 @@ public VideoInfo result(String input, int videoFormat, boolean getVideoLink) {
}
/**
- *
+ * @see https://www.bilibili.com/bangumi/media/md134912
+ * https://api.bilibili.com/pgc/review/user?media_id=139252&ts=...
+ * https://api.bilibili.com/pgc/view/web/season?ep_id=250479
* @input HttpRequestUtil util
* @param ssId
* @param isGetLink
@@ -54,23 +56,21 @@ protected VideoInfo getSSDetail(String ssId, int videoFormat, boolean isGetLink)
VideoInfo viInfo = new VideoInfo();
viInfo.setVideoId(ssId);
+ String ssIdNumber = ssId.replace("ss", "");
HttpHeaders headers = new HttpHeaders();
- String url = "https://www.bilibili.com/bangumi/play/" + ssId;
- String html = util.getContent(url, headers.getCommonHeaders("www.bilibili.com"));
+ String url = "https://api.bilibili.com/pgc/view/web/season?season_id=" + ssIdNumber;
+ String json = util.getContent(url, headers.getCommonHeaders("www.bilibili.com"));
- int begin = html.indexOf("window.__INITIAL_STATE__=");
- int end = html.indexOf(";(function()", begin);
- String json = html.substring(begin + 25, end);
Logger.println(url);
Logger.println(json);
- JSONObject jObj = new JSONObject(json);
- viInfo.setVideoName(jObj.getJSONObject("mediaInfo").getString("title"));
- viInfo.setBrief(jObj.getJSONObject("mediaInfo").getString("evaluate"));
+ JSONObject jObj = new JSONObject(json).getJSONObject("result");
+ viInfo.setVideoName(jObj.getString("title"));
+ viInfo.setBrief(jObj.getString("evaluate"));
viInfo.setAuthor("番剧");
viInfo.setAuthorId("番剧");
- viInfo.setVideoPreview("https:" + jObj.getJSONObject("mediaInfo").getString("cover"));
+ viInfo.setVideoPreview(jObj.getString("cover"));
- JSONArray array = jObj.getJSONArray("epList");
+ JSONArray array = jObj.getJSONArray("episodes");
LinkedHashMap clipMap = new LinkedHashMap();
ClipInfo lastClip = null;
int[] qnListDefault = null;
@@ -84,8 +84,8 @@ protected VideoInfo getSSDetail(String ssId, int videoFormat, boolean isGetLink)
clip.setAvId(clipObj.getString("bvid"));
clip.setcId(clipObj.getLong("cid"));
//clip.setPage(Integer.parseInt(clipObj.getString("index")));
- clip.setRemark(clipObj.getInt("i") + 1);
- clip.setPicPreview("https:" +clipObj.getString("cover"));
+ clip.setRemark(i + 1);
+ clip.setPicPreview(clipObj.getString("cover"));
//如果和前面avid一致,那么是前者page + 1, 否则为 1
if(i > 0 && array.getJSONObject(i-1).getString("bvid").equals(clipObj.getString("bvid"))) {
clip.setPage(lastClip.getPage() + 1);
@@ -93,7 +93,7 @@ protected VideoInfo getSSDetail(String ssId, int videoFormat, boolean isGetLink)
clip.setPage(1);
}
//clip.setTitle(clipObj.getString("index_title"));
- clip.setTitle(clipObj.getString("longTitle"));
+ clip.setTitle(clipObj.getString("long_title"));
clip.setUpName(viInfo.getVideoName());
clip.setUpId(ssId);
diff --git a/src/nicelee/bilibili/parsers/impl/URL4UPAllMedialistParser.java b/src/nicelee/bilibili/parsers/impl/URL4UPAllMedialistParser.java
index c5d4663b..4d183d1d 100644
--- a/src/nicelee/bilibili/parsers/impl/URL4UPAllMedialistParser.java
+++ b/src/nicelee/bilibili/parsers/impl/URL4UPAllMedialistParser.java
@@ -8,6 +8,7 @@
import org.json.JSONArray;
import org.json.JSONObject;
+import nicelee.bilibili.API;
import nicelee.bilibili.annotations.Bilibili;
import nicelee.bilibili.enums.VideoQualityEnum;
import nicelee.bilibili.model.ClipInfo;
@@ -154,8 +155,10 @@ protected boolean query(int page, int min, int max, Object... obj) {
}
}
int lastPageNumber = (page - 1) * API_PMAX + 1;
- String urlFormat = "https://api.bilibili.com/x/space/arc/search?mid=%s&ps=%d&tid=%s&pn=%d&keyword=&order=%s&jsonp=jsonp";
+ // String urlFormat = "https://api.bilibili.com/x/space/arc/search?mid=%s&ps=%d&tid=%s&pn=%d&keyword=&order=%s&jsonp=jsonp";
+ String urlFormat = "https://api.bilibili.com/x/space/wbi/arc/search?mid=%s&ps=%d&tid=%s&special_type=&pn=%d&keyword=&order=%s&platform=web"; // &web_location=1550101&order_avoided=true
String url = String.format(urlFormat, spaceID, 1, params.get("tid"), lastPageNumber, sortFieldParam);
+ url = API.encWbi(url);
String json = util.getContent(url, headers, HttpCookies.globalCookiesWithFingerprint());
Logger.println(url);
Logger.println(json);
diff --git a/src/nicelee/bilibili/parsers/impl/URL4UPAllParser.java b/src/nicelee/bilibili/parsers/impl/URL4UPAllParser.java
index ba298bfb..80009bf6 100644
--- a/src/nicelee/bilibili/parsers/impl/URL4UPAllParser.java
+++ b/src/nicelee/bilibili/parsers/impl/URL4UPAllParser.java
@@ -1,5 +1,6 @@
package nicelee.bilibili.parsers.impl;
+import java.net.URLDecoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.regex.Matcher;
@@ -8,6 +9,7 @@
import org.json.JSONArray;
import org.json.JSONObject;
+import nicelee.bilibili.API;
import nicelee.bilibili.annotations.Bilibili;
import nicelee.bilibili.model.ClipInfo;
import nicelee.bilibili.model.VideoInfo;
@@ -84,8 +86,11 @@ protected boolean query(int page, int min, int max, Object... obj) {
boolean getVideoLink = (boolean) obj[1];
try {
//String urlFormat = "https://space.bilibili.com/ajax/member/getSubmitVideos?mid=%s&pagesize=%d&tid=0&page=%d&keyword=&order=pubdate";
- String urlFormat = "https://api.bilibili.com/x/space/arc/search?mid=%s&ps=%d&tid=%s&pn=%d&keyword=%s&order=%s&jsonp=jsonp";
- String url = String.format(urlFormat, spaceID, API_PMAX, params.get("tid"), page, params.get("keyword"), params.get("order"));
+ //String urlFormat = "https://api.bilibili.com/x/space/arc/search?mid=%s&ps=%d&tid=%s&pn=%d&keyword=%s&order=%s&jsonp=jsonp";
+ String urlFormat = "https://api.bilibili.com/x/space/wbi/arc/search?mid=%s&ps=%d&tid=%s&pn=%d&keyword=%s&order=%s&platform=web"; // &web_location=1550101&order_avoided=true
+ String keyword = URLDecoder.decode(params.get("keyword"), "UTF-8");
+ String url = String.format(urlFormat, spaceID, API_PMAX, params.get("tid"), page, keyword, params.get("order"));
+ url = API.encWbi(url);
String json = util.getContent(url, new HttpHeaders().getCommonHeaders("api.bilibili.com"), HttpCookies.globalCookiesWithFingerprint());
Logger.println(url);
Logger.println(json);
diff --git a/src/nicelee/ui/Global.java b/src/nicelee/ui/Global.java
index 76f34a2e..74accb69 100644
--- a/src/nicelee/ui/Global.java
+++ b/src/nicelee/ui/Global.java
@@ -24,7 +24,7 @@
public class Global {
// 界面显示相关
- @Config(key = "bilibili.version", defaultValue = "v6.25", warning = false)
+ @Config(key = "bilibili.version", defaultValue = "v6.26", warning = false)
public static String version; // 一般情况下,我们不会设置这个标签,这个用于测试
@Config(key = "bilibili.theme", note = "界面主题", defaultValue = "true", eq_true = "default", valids = { "default", "system" })
public static boolean themeDefault;
@@ -62,8 +62,10 @@ public class Global {
public static int downloadFormat = MP4; // 优先下载格式,如不存在该类型的源,那么将默认转为下载另一种格式
@Config(key = "bilibili.dash.download.mode", defaultValue = "0", valids = { "0", "1", "2" }, note = "DASH下载模式: 0-下载音视频,1-仅视频,2-仅音频")
public static DownloadModeEnum downloadMode = DownloadModeEnum.All;
- @Config(key = "bilibili.dash.video.codec.priority", defaultValue = "7, 12, 13", note = "视频编码优先级,AV1:13,HEVC:12,AVC:7,随意-1")
+ @Config(key = "bilibili.dash.video.codec.priority", defaultValue = "7, 12, 13", note = "视频编码优先级(默认),AV1:13,HEVC:12,AVC:7,随意-1")
public static int[] videoCodecPriority = {7, 12, 13};
+ @Config(key = "bilibili.dash.video.codec.priority.map", defaultValue = "80:7, 12, 13| 64:7, 12, 13", note = "视频编码优先级(区分清晰度),AV1:13,HEVC:12,AVC:7,随意-1")
+ public static HashMap videoCodecPriorityMap;
@Config(key = "bilibili.dash.audio.quality.priority", defaultValue = "30280, 30232, 30216, -1, 30251, 30250",
note = "音频编码优先级,30216:64K, 30232:132K, 30280:192K, 随意-1")
public static int[] audioQualityPriority = {30280, 30232, 30216, -1};
@@ -111,6 +113,8 @@ public class Global {
@Config(key = "bilibili.download.batch.config.name.pattern", note = "一键下载配置名称的匹配正则表达式", defaultValue = "^batchDownload.*\\.config$")
public static Pattern batchDownloadConfigNamePattern;
// 登录相关
+ @Config(key = "bilibili.login.cookie.refresh.runWASMinBrowser", defaultValue = "false", valids = { "true", "false" })
+ public static boolean runWASMinBrowser;
@Config(key = "bilibili.server.port", note = "http server监听端口,用于极验校验", defaultValue = "8787")
public static int serverPort = 8787;
@Config(key = "bilibili.user.userName", defaultValue = "", warning = false)
@@ -163,6 +167,8 @@ public class Global {
public static String menu_qn; // 菜单批量下载时, 优先下载清晰度 详见VideoQualityEnum
@Config(key = "bilibili.tab.download.qn", note = "标签页下载时的优先清晰度", defaultValue = "1080P")
public static String tab_qn; // 标签页批量下载时, 优先下载清晰度 详见VideoQualityEnum
+ @Config(key = "bilibili.alert.qualityUnexpected", note = "当遇到不期望的480P视频时是否抛出异常", defaultValue = "true", valids = { "true", "false" })
+ public static boolean alertIfQualityUnexpected;
// 字幕弹幕相关
@Config(key = "bilibili.cc.lang", note = "CC字幕优先语种", defaultValue = "zh-CN")
public static String cc_lang; // 字幕优先语种,如zh-CN等, 详见 release/wiki/langs.txt
@@ -301,6 +307,21 @@ private static void setValue(Field field, String value, boolean isDefaultValue,
valueStrs[i] = valueStrs[i].trim();
}
field.set(null, valueStrs);
+ }else if (field.getType().equals(HashMap.class)) { // HashMap
+ // 80:7, 12, 13| 64:7, 12, 13
+ String[] patterns = value.split("\\|");
+ HashMap m = new HashMap();
+ for(String pattern: patterns) {
+ String[] pair = pattern.split(":");
+ Integer key = Integer.parseInt(pair[0].trim());
+ String[] valueStrs = pair[1].split(",");
+ int[] values = new int[valueStrs.length];
+ for(int i=0; i> 4;
+ int right = b & 0x0f;
+ resultChars[i * 2] = chars[left];
+ resultChars[i * 2 + 1] = chars[right];
+ }
+ String outStr = new String(resultChars);
+ return outStr;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
@Override
public void run() {
// 判断有没有refresh_token
@@ -57,32 +100,52 @@ public void run() {
JSONObject csrfInfoObj = new JSONObject(csrfInfo).getJSONObject("data");
boolean needRefresh = csrfInfoObj.getBoolean("refresh");
if (!needRefresh) {
- JOptionPane.showMessageDialog(null, "当前cookie无需刷新");
- return;
+ JOptionPane.showMessageDialog(null, "当前cookie无需刷新");
+ return;
}
- // 打开server,等待返回 refresh_csrf
- new Thread(new Runnable() {
- @Override
- public void run() {
- socketServer = new SocketServer(Global.serverPort);
- socketServer.startServer();
+ if (Global.runWASMinBrowser) {
+ // 打开server,等待返回 refresh_csrf
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ socketServer = new SocketServer(Global.serverPort);
+ socketServer.startServer();
+ }
+ }, "Cookie 刷新server").start();
+ String browseUrl = String.format("http://localhost:%d/cookieRefresh/index.html?timestamp=%d",
+ Global.serverPort, csrfInfoObj.optLong("timestamp"));
+ goUrlOrShowTips(browseUrl);
+ try {// 等待3min
+ synchronized (this) {
+ this.wait(180000);
+ }
+ } catch (Exception e) {
}
- }, "Cookie 刷新server").start();
- String browseUrl = String.format("http://localhost:%d/cookieRefresh/index.html?timestamp=%d", Global.serverPort,
- csrfInfoObj.optLong("timestamp"));
- goUrlOrShowTips(browseUrl);
- try {// 等待3min
- synchronized(this) {
- this.wait(180000);
+ // 关闭server,判断情况
+ shutDownServerAsyncDelay();
+ if (getRefreshCsrf() == null) {
+ Logger.println("没有收到浏览器传来的refreshCsrf参数");
+ JOptionPane.showMessageDialog(null, "没有收到浏览器传来的refreshCsrf参数");
+ return;
+ }
+ } else {
+ try {
+ // 生成 correspond路径
+ String refresh_timestamp = "refresh_" + csrfInfoObj.optString("timestamp");
+ Logger.println(refresh_timestamp);
+ String path = "https://www.bilibili.com/correspond/1/" + encrypt(refresh_timestamp);
+ // 获取 refresh_csrf
+ String html = util.getContent(path, headers.getCommonHeaders(), HttpCookies.getGlobalCookies());
+ Pattern p = Pattern.compile("(.+?)
");
+ Matcher m = p.matcher(html);
+ m.find();
+ refreshCsrf = m.group(1).trim();
+ Logger.println(refreshCsrf);
+ } catch (Exception e) {
+ e.printStackTrace();
+ JOptionPane.showMessageDialog(null, "刷新cookie出现错误");
+ return;
}
- } catch (Exception e) {
- }
- // 关闭server,判断情况
- shutDownServerAsyncDelay();
- if (getRefreshCsrf() == null) {
- Logger.println("没有收到浏览器传来的refreshCsrf参数");
- JOptionPane.showMessageDialog(null, "没有收到浏览器传来的refreshCsrf参数");
- return;
}
// 调用刷新Cookie的API
INeedLogin inl = new INeedLogin();
diff --git a/src/resources/app.config b/src/resources/app.config
index dcfb51e4..0e99f113 100644
--- a/src/resources/app.config
+++ b/src/resources/app.config
@@ -56,7 +56,17 @@ bilibili.dash.download.mode = 0
# 7 AVC编码
# 12 HEVC编码
# 13 AV1编码
+## 下面的配置表示默认的编码优先级
bilibili.dash.video.codec.priority = 7, 12, 13
+## 下面的配置表示根据清晰度区分的编码优先级,如果没有找到则使用默认的
+# 127 超高清
+# 125 真彩 HDR
+# 120 超清4K
+# 116 高清1080P60
+# 112 高清1080P+
+# 80 高清1080P
+bilibili.dash.video.codec.priority.map = 32:7, 12, 13| 16:7, 12, 13
+
##### 音频的优先质量, 越往前优先级越高
### 启用 杜比全景声 和 Hi-Res无损 的时候,需要注意ffmpeg的版本是否支持
### 对于Windows用户,程序`V6.19`程序版本及之后理论上可行
@@ -188,6 +198,10 @@ bilibili.alert.isAlertIfDownloded = true
# 批量下载时,最大提示框弹出数
bilibili.alert.maxAlertPrompt = 5
+
+# 当遇到不期望的480P视频时是否抛出异常
+## https://github.com/nICEnnnnnnnLee/BilibiliDown/issues/141
+bilibili.alert.qualityUnexpected = true
#######################################################################################################
# 同时支持HTTP + HTTPS 代理
#proxyHost = 127.0.0.1
@@ -225,6 +239,9 @@ bilibili.download.batch.config.name.pattern = ^batchDownload.*\.config$
#######################################################################################################
## 登录设置
+# 刷新cookie时,借用浏览器环境运行wasm,而不是直接使用代码
+bilibili.login.cookie.refresh.runWASMinBrowser = false
+
# 登录方式
# qr 扫描QR二维码
# pwd 使用用户名密码登录