Skip to content
This repository was archived by the owner on Jan 28, 2026. It is now read-only.

Commit b44328f

Browse files
authored
feat: auto select best line (#44)
* feat: auto select best line * docs: update docs
1 parent ee29afd commit b44328f

4 files changed

Lines changed: 55 additions & 25 deletions

File tree

README-en.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ graph TD
9999
- Supports various custom parameters for uploading
100100
- Supports uploading videos with YAML configuration and parsing
101101
- Displays logs and upload progress
102+
- Supports **automatic speed test and selection of the best route**
102103
- `bilitool append` appends videos to existing videos (multi-part)
103104
- `bilitool download` downloads videos
104105
- Supports downloading with `bvid` and `avid` identifiers

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,31 @@ graph TD
9090

9191
## Major features
9292

93-
- `bilitool login` 记忆存储登录状态
93+
- `bilitool login` **记忆存储登录状态**
9494
- 支持导出 `cookies.json` 用于其他项目
9595
- `bilitool logout` 退出登录
96-
- 退出登录同时注销 cookies,保护隐私防止泄露
96+
- 退出登录同时注销 cookies,**保护隐私防止泄露**
9797
- `bilitool check` 检查登录状态
9898
- `bilitool upload` 上传视频
9999
- 支持多种自定义参数上传
100100
- 支持上传视频的 yaml 配置与解析
101101
- 显示日志与上传进度
102-
- `bilitool append` 追加视频到已有的视频(分p投稿)
102+
- 支持**自动测速并且选择最佳线路**
103+
- `bilitool append` 追加视频到已有的视频(**分p投稿**)
103104
- `bilitool download` 下载视频
104105
- 支持 `bvid``avid` 两种编号下载
105106
- 支持下载弹幕
106107
- 支持下载多种画质
107-
- 支持下载多 p 视频
108+
- **支持下载多 p 视频**
108109
- 显示日志与下载进度
109-
- `bilitool list` 查询本账号过往投稿视频状态
110+
- `bilitool list` **查询本账号过往投稿视频状态**
110111
- 支持查询多种状态的视频
111112
- 若视频审核未通过,同时会显示原因
112113
- `bilitool convert` 查询转换视频编号
113114
- 支持 `bvid``avid` 两种编号互转
114115
- `bilitool show` 显示视频详细信息
115116
- 支持查看视频基本信息以及互动状态数据
116-
- `bilitool ip` 显示请求 IP 地址
117+
- `bilitool ip` **显示请求 IP 地址**
117118
- 支持查询指定 IP 地址
118119

119120
> 以上命令添加 `-h``--help` 参数可以查看命令帮助信息。

bilitool/controller/upload_controller.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def package_upload_metadata(line, copyright, tid, title, desc, tag, source, cove
3030

3131
def upload_video(self, file):
3232
"""upload and publish video on bilibili"""
33+
upos_url, cdn, probe_version = self.bili_uploader.probe()
3334
file = Path(file)
3435
assert file.exists(), f'The file {file} does not exist'
3536
filename = file.name
@@ -40,15 +41,15 @@ def upload_video(self, file):
4041

4142
# upload video
4243
self.logger.info('Start preuploading the video')
43-
pre_upload_response = self.bili_uploader.preupload(filename=filename, filesize=filesize)
44+
pre_upload_response = self.bili_uploader.preupload(filename=filename, filesize=filesize, cdn=cdn, probe_version=probe_version)
4445
upos_uri = pre_upload_response['upos_uri'].split('//')[-1]
4546
auth = pre_upload_response['auth']
4647
biz_id = pre_upload_response['biz_id']
4748
chunk_size = pre_upload_response['chunk_size']
4849
chunks = ceil(filesize/chunk_size)
4950

5051
self.logger.info('Start uploading the video')
51-
upload_video_id_response = self.bili_uploader.get_upload_video_id(upos_uri=upos_uri, auth=auth)
52+
upload_video_id_response = self.bili_uploader.get_upload_video_id(upos_uri=upos_uri, auth=auth, upos_url=upos_url)
5253
upload_id = upload_video_id_response['upload_id']
5354
key = upload_video_id_response['key']
5455

@@ -63,13 +64,14 @@ def upload_video(self, file):
6364
fileio=fileio,
6465
filesize=filesize,
6566
chunk_size=chunk_size,
66-
chunks=chunks
67+
chunks=chunks,
68+
upos_url=upos_url
6769
)
6870
fileio.close()
6971

7072
# notify the all chunks have been uploaded
7173
self.bili_uploader.finish_upload(upos_uri=upos_uri, auth=auth, filename=filename,
72-
upload_id=upload_id, biz_id=biz_id, chunks=chunks)
74+
upload_id=upload_id, biz_id=biz_id, chunks=chunks, upos_url=upos_url)
7375
return bilibili_filename
7476

7577
def publish_video(self, file):

bilitool/upload/bili_upload.py

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@
1212
from bilitool.utils.parse_cookies import parse_cookies
1313
from bilitool.model.model import Model
1414
import hashlib
15-
16-
# you can test your best cdn line https://member.bilibili.com/preupload?r=ping
17-
# cdn_lines = {
18-
# 'qn': 'upos-sz-upcdnqn.bilivideo.com',
19-
# 'bda2': 'upos-sz-upcdnbda2.bilivideo.com',
20-
# }
15+
import time
2116

2217
class BiliUploader(object):
2318
def __init__(self, logger):
@@ -28,7 +23,38 @@ def __init__(self, logger):
2823
self.session.cookies = requests.utils.cookiejar_from_dict(self.config["cookies"])
2924
self.headers = Model().get_headers_with_cookies_and_refer()
3025

31-
def preupload(self, *, filename, filesize):
26+
def probe(self):
27+
ret = requests.get('https://member.bilibili.com/preupload?r=probe', headers=self.headers, timeout=5).json()
28+
print(f"线路:{ret['lines']}")
29+
data, auto_os = None, None
30+
min_cost = 0
31+
if ret['probe'].get('get'):
32+
method = 'get'
33+
else:
34+
method = 'post'
35+
data = bytes(int(1024 * 0.1 * 1024))
36+
for line in ret['lines']:
37+
start = time.perf_counter()
38+
test = requests.request(method, f"https:{line['probe_url']}", data=data, timeout=30)
39+
cost = time.perf_counter() - start
40+
print(line['query'], cost)
41+
if test.status_code != 200:
42+
return
43+
if not min_cost or min_cost > cost:
44+
auto_os = line
45+
min_cost = cost
46+
auto_os['cost'] = min_cost
47+
self.logger.info(f"the best cdn line is:{auto_os}")
48+
upos_url = auto_os['probe_url'].rstrip('OK')
49+
self.logger.info(f"the upos_url is:{upos_url}")
50+
query_params = dict(param.split('=') for param in auto_os['query'].split('&'))
51+
cdn = query_params.get('upcdn')
52+
self.logger.info(f"the cdn is:{cdn}")
53+
probe_version = query_params.get('probe_version')
54+
self.logger.info(f"the probe_version is:{probe_version}")
55+
return upos_url, cdn, probe_version
56+
57+
def preupload(self, *, filename, filesize, cdn, probe_version):
3258
"""The preupload process to get `upos_uri` and `auth` information.
3359
Parameters
3460
----------
@@ -60,8 +86,8 @@ def preupload(self, *, filename, filesize):
6086
'ssl': 0,
6187
'version': '2.8.9',
6288
'build': '2080900',
63-
'upcdn': 'bda2',
64-
'probe_version': '20200810'
89+
'upcdn': cdn,
90+
'probe_version': probe_version
6591
}
6692
res_json = self.session.get(
6793
url,
@@ -73,7 +99,7 @@ def preupload(self, *, filename, filesize):
7399
# print(res_json)
74100
return res_json
75101

76-
def get_upload_video_id(self, *, upos_uri, auth):
102+
def get_upload_video_id(self, *, upos_uri, auth, upos_url):
77103
"""Get the `upload_id` of video.
78104
79105
Parameters
@@ -87,14 +113,14 @@ def get_upload_video_id(self, *, upos_uri, auth):
87113
- upload_id: str
88114
the id of the video to be uploaded
89115
"""
90-
url = f'https://upos-sz-upcdnbda2.bilivideo.com/{upos_uri}?uploads&output=json'
116+
url = f'https:{upos_url}{upos_uri}?uploads&output=json'
91117
res_json = self.session.post(url, headers={'X-Upos-Auth': auth}).json()
92118
assert res_json['OK'] == 1
93119
self.logger.info('Completed upload_id obtaining phase')
94120
# print(res_json)
95121
return res_json
96122

97-
def upload_video_in_chunks(self, *, upos_uri, auth, upload_id, fileio, filesize, chunk_size, chunks):
123+
def upload_video_in_chunks(self, *, upos_uri, auth, upload_id, fileio, filesize, chunk_size, chunks, upos_url):
98124
"""Upload the video in chunks.
99125
100126
Parameters
@@ -114,7 +140,7 @@ def upload_video_in_chunks(self, *, upos_uri, auth, upload_id, fileio, filesize,
114140
- chunks: int
115141
the number of chunks to be uploaded
116142
"""
117-
url = f'https://upos-sz-upcdnbda2.bilivideo.com/{upos_uri}'
143+
url = f'https:{upos_url}{upos_uri}'
118144
params = {
119145
'partNumber': None, # start from 1
120146
'uploadId': upload_id,
@@ -142,7 +168,7 @@ def upload_video_in_chunks(self, *, upos_uri, auth, upload_id, fileio, filesize,
142168
pbar.update(len(batchbytes))
143169
# print(res)
144170

145-
def finish_upload(self, *, upos_uri, auth, filename, upload_id, biz_id, chunks):
171+
def finish_upload(self, *, upos_uri, auth, filename, upload_id, biz_id, chunks, upos_url):
146172
"""Notify the all chunks have been uploaded.
147173
148174
Parameters
@@ -160,7 +186,7 @@ def finish_upload(self, *, upos_uri, auth, filename, upload_id, biz_id, chunks):
160186
- chunks: int
161187
the number of chunks to be uploaded
162188
"""
163-
url = f'https://upos-sz-upcdnbda2.bilivideo.com/{upos_uri}'
189+
url = f'https:{upos_url}{upos_uri}'
164190
params = {
165191
'output': 'json',
166192
'name': filename,

0 commit comments

Comments
 (0)