Skip to content

Commit 49f14a7

Browse files
committed
Update to 1.2.0
1 parent 7a9b31e commit 49f14a7

File tree

7 files changed

+143
-125
lines changed

7 files changed

+143
-125
lines changed

README.md

+26-18
Original file line numberDiff line numberDiff line change
@@ -42,48 +42,50 @@
4242

4343
1. **[可跳过]** 使用 `mvn clean package` 命令进行编译。
4444

45-
2. 输入 `java -jar bili-download-1.1.9-jar-with-dependencies.jar`,进入程序。若您希望启用 debug 模式,请在参数中添加 `debug`
46-
,即输入 `java -jar bili-download-1.1.9-jar-with-dependencies.jar debug`,这将显示一些调试信息。
45+
2. 输入 `java -jar bili-download-1.2.0-jar-with-dependencies.jar`,进入程序。若您希望启用 debug 模式,请在参数中添加 `debug`
46+
,即输入 `java -jar bili-download-1.2.0-jar-with-dependencies.jar debug`,这将显示一些调试信息。
4747

4848
3. 输入一个 AV 号或 BV 号。
4949

50-
4. **[如果从未保存过 SESSDATA 或 cookie 已失效]** 输入所选登录方式的编号。1.1.9 版本不支持 TV 端二维码登录
50+
4. **[如果从未保存过 SESSDATA 或 TOKEN,或者在保存的登录凭据中存在无法凭之成功登录的]** 输入所选登录方式的编号。
5151

52-
5. **[如果选择了登录方式并选择 WEB 端二维码登录]** 打开标题为 `二维码登录` 的窗口,使用B站手机客户端扫码并确认登录,完成后关闭该窗口
52+
5. **[如果选择了登录方式并选择 WEB 端二维码登录或 TV 端二维码登录]** 打开标题为 `WEB 端二维码登录``TV 端二维码登录` 的窗口,使用B站手机客户端扫码并确认登录。程序每隔一秒验证一次扫码是否完毕
5353

5454
6. **[如果选择了登录方式并选择输入 SESSDATA 登录]** 输入 cookie 中 SESSDATA 的值。
5555

56-
7. **[如果选择了登录方式]** 输入 `Y``N` 决定是否保存 SESSDATA。
56+
7. **[如果选择了登录方式并登录成功]** 输入 `Y``N` 决定是否保存 SESSDATA 或 TOKEN
5757

58-
8. 等待程序获取稿件信息。程序会返回稿件的标题、UP主、时长、播放数、弹幕数、获赞数、投币数以及收藏数。若该视频有多个分P,则会一并返回每个分P的 CID、时长与标题
58+
8. **[如果选择了登录方式]** 输入 `Y``N` 决定是否继续登录
5959

60-
9. **[如果稿件有多个分P]** 输入所需分P的编号
60+
9. 等待程序获取稿件信息。程序会返回稿件的标题、UP主、时长、播放数、弹幕数、获赞数、投币数以及收藏数。若该视频有多个分P,则会一并返回每个分P的 CID、时长与标题
6161

62-
10. 等待程序获取清晰度信息
62+
10. **[如果稿件有多个分P]** 输入所需分P的编号
6363

64-
11. 输入所需清晰度的编号
64+
11. 等待程序获取清晰度信息
6565

66-
12. **[如果从未保存过保存路径或保存的路径不存在]** 输入保存路径
66+
12. 输入所需清晰度的编号
6767

68-
13. **[如果手动输入了保存路径且该路径不存在]** 输入 `Y``N` 决定是否新建目录
68+
13. **[如果从未保存过保存路径或保存的路径不存在]** 输入保存路径
6969

70-
14. **[如果手动输入了保存路径]** 输入 `Y``N` 决定是否保存该保存路径
70+
14. **[如果手动输入了保存路径且该路径不存在]** 输入 `Y``N` 决定是否新建目录
7171

72-
15. 输入所选下载选项的编号
72+
15. **[如果手动输入了保存路径]** 输入 `Y``N` 决定是否保存该保存路径
7373

74-
16. **[如果选择 `视频+音频` 下载选项,且从未保存过 FFmpeg 路径或路径不存在]** 输入 `ffmpeg.exe` 所处目录的路径。若填 `#` 则程序将不再进行音视频合并操作
74+
16. 输入所选下载选项的编号
7575

76-
17. **[如果手动输入了 FFmpeg 路径]** 输入 `Y``N` 决定是否保存 FFmpeg 路径
76+
17. **[如果选择 `视频+音频` 下载选项,且从未保存过 FFmpeg 路径或路径不存在]** 输入 `ffmpeg.exe` 所处目录的路径。若填 `#` 则程序将不再进行音视频合并操作
7777

78-
18. 等待下载完毕。下载完成后,若需合并则会生成合并文件并删除源文件。
78+
18. **[如果手动输入了 FFmpeg 路径]** 输入 `Y``N` 决定是否保存 FFmpeg 路径。
79+
80+
19. 等待下载完毕。下载完成后,若需合并则会生成合并文件并删除源文件。
7981

8082
---
8183

8284
# 补充
8385

8486
1. 输入 AV 号或 BV 号时,须带有 `av``BV` 前缀。
8587

86-
2. 如需下载 1080P+ 及更佳清晰度的视频,请确保您的账号已购买大会员
88+
2. 如需下载 1080P+ 及更佳清晰度的视频,请确保您的账号已购买大会员或电视大会员
8789

8890
3. 获取视频的清晰度信息时会访问 TV 端 API 与 WEB 端 API。若通过 TV 端 API 可获取到无水印版本,则所得清晰度会优先排列在结果中,并添加 `无水印` 标记。否则,将只保留通过 WEB 端 API
8991
所得的清晰度。注意,由于有无水印是根据 TV 端 API 提供的 `accept_watermark` 判断的,通过 WEB 端 API 获取的清晰度将一律不标记 `无水印`。这意味着没有 `无水印` 标记的清晰度不一定有水印。
@@ -96,12 +98,18 @@
9698

9799
7. **[优化项]** 程序目前只支持单线程下载,可考虑添加多线程下载功能。如果程序的下载速度过慢,请自行访问下载地址进行下载。
98100

99-
8. 本程序仍然存在诸如不支持 4K 与 1080P+ 清晰度的无水印下载、下载速度慢等问题,欢迎大家多多投递 pull request。
101+
8. 本程序仍然存在诸如下载速度慢等问题,欢迎大家多多投递 issue 与 pull request。
100102

101103
---
102104

103105
# ChangeLog
104106

107+
## 1.2.0
108+
109+
### 添加了 TV 端二维码登录功能
110+
111+
目前有三种登录方式可选:`WEB 端二维码登录``TV 端二维码登录``输入 SESSDATA 登录`。若希望双端皆处于登录状态,在登录某端后继续登录另一端即可。
112+
105113
## 1.1.9
106114

107115
### 添加了 WEB 端二维码登录功能

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>me.naptie</groupId>
88
<artifactId>bili-download</artifactId>
9-
<version>1.1.9</version>
9+
<version>1.2.0</version>
1010
<build>
1111
<plugins>
1212
<plugin>

src/main/java/me/naptie/bilidownload/Main.java

+22-49
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private static String getNumber() {
7575
}
7676

7777
private static String[] login() throws IOException {
78-
boolean loginSuccess = false;
78+
boolean webSuccess = false, tvSuccess = false;
7979
String sessData = "#", accessToken = "", cookie = "#";
8080
if (config.exists()) {
8181
ConfigManager.init(config);
@@ -88,23 +88,22 @@ private static String[] login() throws IOException {
8888
JSONObject login = HttpManager.readJsonFromUrl("https://api.bilibili.com/x/web-interface/nav", cookie, false);
8989
if (login.getIntValue("code") == 0)
9090
if (login.getJSONObject("data").getBoolean("isLogin")) {
91-
if (debug)
92-
System.out.println("检测到配置文件,已自动填充 SESSDATA\nID:" + login.getJSONObject("data").getString("uname") + "\nUID:" + login.getJSONObject("data").getIntValue("mid"));
93-
loginSuccess = true;
91+
System.out.println("成功使用保存的 SESSDATA 登录\nID:" + login.getJSONObject("data").getString("uname") + "\nUID:" + login.getJSONObject("data").getIntValue("mid"));
92+
webSuccess = true;
9493
}
9594
}
9695
if (map.containsKey("access-token")) {
9796
accessToken = (String) map.get("access-token");
9897
String params = "access_key=" + accessToken + "&appkey=4409e2ce8ffd12b8&ts=" + System.currentTimeMillis();
9998
JSONObject login = HttpManager.readJsonFromUrl("https://app.bilibili.com/x/v2/account/myinfo?" + params + "&sign=" + SignUtil.generate(params), "#", true);
10099
if (login.getIntValue("code") == 0) {
101-
if (debug)
102-
System.out.println("检测到配置文件,已自动填充 token\nID:" + login.getJSONObject("data").getString("name") + "\nUID:" + login.getJSONObject("data").getIntValue("mid"));
103-
loginSuccess = true;
100+
System.out.println("成功使用保存的 TOKEN 登录\nID:" + login.getJSONObject("data").getString("name") + "\nUID:" + login.getJSONObject("data").getIntValue("mid"));
101+
tvSuccess = true;
104102
}
105103
}
106104
}
107-
do {
105+
boolean loginSuccess = webSuccess && tvSuccess;
106+
while (!loginSuccess) {
108107
System.out.println("\n登录方式:\n 1. WEB 端二维码登录\n 2. TV 端二维码登录\n 3. 输入 SESSDATA 登录\n 4. 跳过登录\n请选择登录方式(输入 1~4 之间的整数):");
109108
int method = inputInt();
110109
if (method < 1) {
@@ -117,45 +116,34 @@ private static String[] login() throws IOException {
117116
}
118117
if (method == 1) {
119118
LoginManager.showQRCodeFromWeb();
120-
while (true)
121-
if (!LoginManager.sessData.equalsIgnoreCase("*Not_Yet_Prepared*"))
122-
break;
123119
sessData = LoginManager.sessData;
124120
if (sessData.isEmpty()) {
125121
System.out.println("登录失败");
126-
if (hint) System.out.println("请决定是否继续登录(输入“Y”或“N”):");
127-
if (input().equalsIgnoreCase("Y"))
128-
continue;
129122
}
130123
} else if (method == 2) {
131124
LoginManager.showQRCodeFromTV();
132-
while (true)
133-
if (!LoginManager.accessToken.equalsIgnoreCase("*Not_Yet_Prepared*"))
134-
break;
135125
accessToken = LoginManager.accessToken;
136126
if (accessToken.isEmpty()) {
137127
System.out.println("登录失败");
138-
if (hint) System.out.println("请决定是否继续登录(输入“Y”或“N”):");
139-
if (input().equalsIgnoreCase("Y"))
140-
continue;
141128
}
142129
} else if (method == 3) {
143130
if (hint) System.out.println("\n请输入 Cookie 中 SESSDATA 的值:");
144131
sessData = input();
145132
} else {
146133
break;
147134
}
148-
if (sessData.equals("#")) {
149-
cookie = "#";
150-
break;
151-
} else if (method != 2) {
135+
if (method != 2) {
136+
if (sessData.equals("#")) {
137+
cookie = "#";
138+
break;
139+
}
152140
cookie = "SESSDATA=" + sessData + "; Path=/; Domain=bilibili.com;";
153141
JSONObject login = HttpManager.readJsonFromUrl("https://api.bilibili.com/x/web-interface/nav", cookie, false);
154142
if (login.getIntValue("code") == 0)
155143
if (login.getJSONObject("data").getBoolean("isLogin")) {
156144
loginSuccess = true;
157145
System.out.println("登录成功" + (debug ? "\nID:" + login.getJSONObject("data").getString("uname") + "\nUID:" + login.getJSONObject("data").getIntValue("mid") : ""));
158-
if (hint) System.out.println("请决定是否保存该 SESSDATA(输入“Y”“N”):");
146+
if (hint) System.out.println("请决定是否保存该 SESSDATA(输入“Y”代表是,输入“N”代表否):");
159147
if (input().equalsIgnoreCase("Y")) {
160148
if (!config.exists()) config.createNewFile();
161149
ConfigManager.init(config);
@@ -166,55 +154,40 @@ private static String[] login() throws IOException {
166154
ConfigManager.dump(map);
167155
if (hint) System.out.println("已保存 SESSDATA");
168156
}
169-
if (hint) System.out.println("请决定是否继续登录(输入“Y”“N”):");
157+
if (hint) System.out.println("请决定是否继续登录(输入“Y”代表是,输入“N”代表否):");
170158
if (input().equalsIgnoreCase("Y"))
171159
loginSuccess = false;
172160
} else {
173161
System.out.println("登录失败");
174-
if (loginSuccess) {
175-
if (hint) System.out.println("请决定是否继续登录(输入“Y”或“N”):");
176-
if (input().equalsIgnoreCase("Y"))
177-
loginSuccess = false;
178-
}
179162
}
180163
else {
181164
System.out.println("登录失败");
182-
if (loginSuccess) {
183-
if (hint) System.out.println("请决定是否继续登录(输入“Y”或“N”):");
184-
if (input().equalsIgnoreCase("Y"))
185-
loginSuccess = false;
186-
}
187165
}
188166
} else {
189167
String params = "access_key=" + accessToken + "&appkey=4409e2ce8ffd12b8&ts=" + System.currentTimeMillis();
190168
JSONObject login = HttpManager.readJsonFromUrl("https://app.bilibili.com/x/v2/account/myinfo?" + params + "&sign=" + SignUtil.generate(params), "#", true);
191169
if (login.getIntValue("code") == 0) {
192170
loginSuccess = true;
193171
System.out.println("登录成功" + (debug ? "\nID:" + login.getJSONObject("data").getString("name") + "\nUID:" + login.getJSONObject("data").getIntValue("mid") : ""));
194-
if (hint) System.out.println("请决定是否保存该 token(输入“Y”“N”):");
172+
if (hint) System.out.println("请决定是否保存该 TOKEN(输入“Y”代表是,输入“N”代表否):");
195173
if (input().equalsIgnoreCase("Y")) {
196174
if (!config.exists()) config.createNewFile();
197175
ConfigManager.init(config);
198176
Map<String, Object> map = ConfigManager.get();
199177
if (map == null)
200178
map = new LinkedHashMap<>();
201-
map.put("access-token", sessData);
179+
map.put("access-token", accessToken);
202180
ConfigManager.dump(map);
203-
if (hint) System.out.println("已保存 token");
181+
if (hint) System.out.println("已保存 TOKEN");
204182
}
205-
if (hint) System.out.println("请决定是否继续登录(输入“Y”“N”):");
183+
if (hint) System.out.println("请决定是否继续登录(输入“Y”代表是,输入“N”代表否):");
206184
if (input().equalsIgnoreCase("Y"))
207185
loginSuccess = false;
208186
} else {
209187
System.out.println("登录失败");
210-
if (loginSuccess) {
211-
if (hint) System.out.println("请决定是否继续登录(输入“Y”或“N”):");
212-
if (input().equalsIgnoreCase("Y"))
213-
loginSuccess = false;
214-
}
215188
}
216189
}
217-
} while (!loginSuccess);
190+
}
218191
return new String[]{cookie, accessToken};
219192
}
220193

@@ -334,7 +307,7 @@ private static String[] getPath(String name) throws IOException {
334307
savePath = input();
335308
File file = new File(savePath);
336309
if (!file.exists()) {
337-
if (hint) System.out.println("该目录不存在,请决定是否创建该目录(输入“Y”“N”):");
310+
if (hint) System.out.println("该目录不存在,请决定是否创建该目录(输入“Y”代表是,输入“N”代表否):");
338311
if (input().equalsIgnoreCase("Y")) {
339312
pathSuccess = file.mkdirs();
340313
if (!pathSuccess) System.out.println("创建目录失败");
@@ -343,7 +316,7 @@ private static String[] getPath(String name) throws IOException {
343316
pathSuccess = true;
344317
}
345318
if (pathSuccess) {
346-
if (hint) System.out.println("请决定是否保存该保存路径(输入“Y”“N”):");
319+
if (hint) System.out.println("请决定是否保存该保存路径(输入“Y”代表是,输入“N”代表否):");
347320
if (input().equalsIgnoreCase("Y")) {
348321
if (!config.exists()) config.createNewFile();
349322
ConfigManager.init(config);
@@ -401,7 +374,7 @@ private static void download(Object[] details, String[] path) throws IOException
401374
ffmpeg = ffmpegPath.endsWith("ffmpeg.exe") ? new File(ffmpegPath) : new File(ffmpegPath, "ffmpeg.exe");
402375
ffmpegSuccess = ffmpeg.exists() ? 1 : 0;
403376
if (ffmpegSuccess == 1) {
404-
if (hint) System.out.println("请决定是否保存 FFmpeg 路径(输入“Y”“N”):");
377+
if (hint) System.out.println("请决定是否保存 FFmpeg 路径(输入“Y”代表是,输入“N”代表否):");
405378
if (input().equalsIgnoreCase("Y")) {
406379
if (!config.exists()) config.createNewFile();
407380
ConfigManager.init(config);

src/main/java/me/naptie/bilidownload/objects/Frame.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ public Frame(String title, String image, Dimension size, boolean tv) {
1414
this.add(panel);
1515
this.addWindowListener(new WindowAdapter() {
1616
public void windowClosing(WindowEvent e) {
17-
if (LoginManager.sessData.equalsIgnoreCase("*Not_Yet_Prepared*")) {
17+
if (LoginManager.sessData.equalsIgnoreCase("*SessData_Not_Yet_Prepared*")) {
1818
LoginManager.loginWeb();
1919
}
20-
if (tv && LoginManager.accessToken.equalsIgnoreCase("*Not_Yet_Prepared*")) {
20+
if (tv && LoginManager.accessToken.equalsIgnoreCase("*Token_Not_Yet_Prepared*")) {
2121
LoginManager.loginTV();
2222
}
2323
dispose();
@@ -26,6 +26,8 @@ public void windowClosing(WindowEvent e) {
2626
this.pack();
2727
this.setVisible(true);
2828
this.setResizable(false);
29+
this.setLocationRelativeTo(null);
30+
this.setAlwaysOnTop(true);
2931
}
3032

3133
}

src/main/java/me/naptie/bilidownload/objects/Panel.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
public class Panel extends java.awt.Panel {
88

9-
private final Image screenImage = new BufferedImage(600, 600, 2);
9+
private final Image screenImage = new BufferedImage(500, 500, 2);
1010

1111
private final Graphics2D screenGraphic = (Graphics2D) screenImage.getGraphics();
1212

src/main/java/me/naptie/bilidownload/utils/HttpManager.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ public static HttpURLConnection readUrl(String url, String cookie, boolean post,
1818
if (Main.debug) System.out.println("正在访问 " + url + ",使用 UA“" + userAgent + "”");
1919
HttpURLConnection request = (HttpURLConnection) (new URL(url)).openConnection();
2020
request.setRequestProperty("User-Agent", userAgent);
21-
if (!cookie.equals("#"))
21+
if (!cookie.equals("#")) {
2222
request.setRequestProperty("Cookie", cookie);
23+
}
2324
System.setProperty("http.agent", userAgent);
2425
request.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
2526
request.setRequestProperty("Accept", "*/*");
26-
if (post)
27+
if (post) {
2728
request.setRequestMethod("POST");
29+
}
2830
request.connect();
2931
return request;
3032
}

0 commit comments

Comments
 (0)