Skip to content

Commit 2cb10dc

Browse files
committed
feat: videos with multiple episodes
Signed-off-by: jingfelix <[email protected]>
1 parent 93259fd commit 2cb10dc

File tree

4 files changed

+58
-48
lines changed

4 files changed

+58
-48
lines changed

main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from src.bilifm import app
2+
3+
if __name__ == "__main__":
4+
app()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="bilifm",
8-
version="0.1.6",
8+
version="0.1.7",
99
author="Felix Jing",
1010
author_email="[email protected]",
1111
description="Download Bilibili videos as audios.",

src/bilifm/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import typer
22

3-
from bilifm.audio import Audio
4-
from bilifm.user import User
5-
from bilifm.fav import Fav
3+
from .audio import Audio
4+
from .user import User
5+
from .fav import Fav
66

77
app = typer.Typer()
88

src/bilifm/audio.py

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88

99
class Audio:
1010
bvid = ""
11-
cid = ""
1211
title = ""
1312
playUrl = "http://api.bilibili.com/x/player/playurl"
14-
baseUrl = ""
13+
part_list = []
1514

1615
def __init__(self, bvid: str) -> None:
1716
if bvid is None:
@@ -25,17 +24,8 @@ def __init__(self, bvid: str) -> None:
2524
self.__get_cid_title(bvid)
2625
else:
2726
# AV号
28-
self.__get_cid_title(bvid[:12], int(bvid[13:]))
27+
self.__get_cid_title(bvid[:12])
2928

30-
params = {
31-
"fnval": 16,
32-
"bvid": self.bvid,
33-
"cid": self.cid,
34-
}
35-
36-
self.baseUrl = requests.get(self.playUrl, params=params).json()["data"]["dash"][
37-
"audio"
38-
][0]["baseUrl"]
3929

4030
def download(self):
4131
headers = {
@@ -51,35 +41,46 @@ def download(self):
5141

5242
start_time = time.time()
5343
try:
54-
response = requests.get(url=self.baseUrl, headers=headers, stream=True)
55-
56-
total_size = int(response.headers.get("content-length", 0))
57-
temp_size = 0
58-
59-
# 如果文件已存在,则跳过下载
60-
if os.path.exists(self.title + ".mp3"):
61-
typer.echo(f"{self.title} already exists, skip for now")
62-
return
63-
64-
with open(self.title + ".mp3", "wb") as f:
65-
for chunk in response.iter_content(chunk_size=1024):
66-
if chunk:
67-
f.write(chunk)
68-
f.flush()
69-
70-
temp_size += len(chunk)
71-
done = int(50 * temp_size / total_size)
72-
sys.stdout.write(
73-
"\r[%s%s] %s/%s %s"
74-
% (
75-
"#" * done,
76-
"-" * (50 - done),
77-
temp_size,
78-
total_size,
79-
self.title,
44+
for cid, part in zip(self.cid_list, self.part_list):
45+
baseUrl = requests.get(
46+
self.playUrl,
47+
params={
48+
"fnval": 16,
49+
"bvid": self.bvid,
50+
"cid": cid,
51+
},
52+
).json()["data"]["dash"]["audio"][0]["baseUrl"]
53+
54+
response = requests.get(url=baseUrl, headers=headers, stream=True)
55+
56+
total_size = int(response.headers.get("content-length", 0))
57+
temp_size = 0
58+
59+
# 如果文件已存在,则跳过下载
60+
file_path = f"{self.title}-{part}.mp3"
61+
if os.path.exists(file_path):
62+
typer.echo(f"{self.title} already exists, skip for now")
63+
return
64+
65+
with open(file_path, "wb") as f:
66+
for chunk in response.iter_content(chunk_size=1024):
67+
if chunk:
68+
f.write(chunk)
69+
f.flush()
70+
71+
temp_size += len(chunk)
72+
done = int(50 * temp_size / total_size)
73+
sys.stdout.write(
74+
"\r[%s%s] %s/%s %s"
75+
% (
76+
"#" * done,
77+
"-" * (50 - done),
78+
temp_size,
79+
total_size,
80+
self.title,
81+
)
8082
)
81-
)
82-
sys.stdout.flush()
83+
sys.stdout.flush()
8384

8485
except Exception as e:
8586
typer.echo("Download failed")
@@ -92,24 +93,29 @@ def download(self):
9293
" " + str(round(end_time - start_time, 2)) + " seconds download finish\n"
9394
)
9495

95-
def __get_cid_title(self, bvid: str, p: int = 1):
96+
def __get_cid_title(self, bvid: str):
9697
url = "https://api.bilibili.com/x/web-interface/view?bvid={bvid}".format(
9798
bvid=bvid
9899
)
99100
try:
100101
response = requests.get(url)
101102
data = response.json().get("data")
102-
self.title = data.get("title")
103+
self.title = self.__title_process(data.get("title"))
103104

104105
# 这里是否也应该也使用get方法?
105-
self.cid = str(data["pages"][p - 1]["cid"])
106+
self.cid_list = [str(page["cid"]) for page in data["pages"]]
107+
self.part_list = [self.__title_process(str(page["part"])) for page in data["pages"]]
106108

107109
except ValueError as e:
108110
raise e
109111

110112
except Exception as e:
111113
raise e
112114

115+
116+
def __title_process(self, title: str):
113117
replaceList = ["?", "\\", "*", "|", "<", ">", ":", "/", " "]
114118
for ch in replaceList:
115-
self.title = self.title.replace(ch, "-")
119+
title = title.replace(ch, "-")
120+
121+
return title

0 commit comments

Comments
 (0)