一系列bug修复与优化 (#384)
* 修复优选CDN与直播流不生效的问题 * 优化streamlink下载参数 * Update __init__.py * Update CHANGELOG.md * 完善依赖列表 * Update CHANGELOG.md
This commit is contained in:
1 parent
aadaf7f53a
commit
8a7ee5fbfc
5 files changed
+69
-69
No files matched your search
@@ -5,6 +5,12 @@
|
||||
- 🔧已修复的问题
|
||||
- ⚠️需要手动操作的更新信息
|
||||
|
||||
## 0.4.12
|
||||
- 更新时间:2023.03.17
|
||||
- 🔧修复优选CDN与直播流不生效的问题。[@haha114514](https://github.com/haha114514)
|
||||
- 🔧优化streamlink下载参数。[@haha114514](https://github.com/haha114514)
|
||||
- 🔧完善依赖列表,将最低的yt-dlp版本要求升级到2023.3.3,解决2022年版本已无法解析YouTube视频的问题。并且将streamlink最低要求版本升级到5.3.0,提升hls流录制稳定性。[@haha114514](https://github.com/haha114514)
|
||||
|
||||
## 0.4.11
|
||||
- 更新时间:2023.03.07
|
||||
- 🔧修复上一版本的封面上传问题。[@haha114514](https://github.com/haha114514)
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
__version__ = "0.4.11"
|
||||
__version__ = "0.4.12"
|
||||
|
||||
LOG_CONF = {
|
||||
'version': 1,
|
||||
|
||||
@@ -78,8 +78,8 @@ class DownloadBase:
|
||||
else:
|
||||
self.ffmpeg_download(fmtname)
|
||||
|
||||
def streamlink_download(self, filename):
|
||||
streamlink_input_args = ['--stream-segment-threads', '10']
|
||||
def streamlink_download(self, filename): #streamlink+ffmpeg混合下载模式,适用于下载hls流
|
||||
streamlink_input_args = ['--stream-segment-threads', '5']
|
||||
streamlink_cmd = ['streamlink', *streamlink_input_args, self.raw_stream_url, 'best', '-O']
|
||||
ffmpeg_input_args = ['-reconnect_streamed', '1', '-reconnect_delay_max', '20', '-rw_timeout', '20000000']
|
||||
ffmpeg_cmd = ['ffmpeg', '-re', '-i', 'pipe:0', '-y',*ffmpeg_input_args, *self.default_output_args, *self.opt_args, '-c', 'copy', '-f', self.suffix]
|
||||
@@ -93,7 +93,7 @@ class DownloadBase:
|
||||
ffmpeg_proc = subprocess.Popen(ffmpeg_cmd, stdin=streamlink_proc.stdout, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
try:
|
||||
with ffmpeg_proc.stdout as stdout:
|
||||
for line in iter(stdout.readline, b''): # b'\n'-separated lines
|
||||
for line in iter(stdout.readline, b''):
|
||||
decode_line = line.decode(errors='ignore')
|
||||
print(decode_line, end='', file=sys.stderr)
|
||||
logger.debug(decode_line.rstrip())
|
||||
|
||||
+57
-63
@@ -60,7 +60,7 @@ class Bilibili(DownloadBase):
|
||||
live_start_time = room_info['data']['room_info']['live_start_time']
|
||||
uname = room_info['data']['anchor_info']['base_info']['uname']
|
||||
room_title = room_info['data']['room_info']['title']
|
||||
if self.use_live_cover is True: # 获取直播封面并保存到cover目录下
|
||||
if self.use_live_cover is True: # 获取直播封面并保存到cover目录下
|
||||
try:
|
||||
self.live_cover_path = get_live_cover(uname, room_id, room_title, live_start_time, cover_url)
|
||||
except:
|
||||
@@ -69,7 +69,7 @@ class Bilibili(DownloadBase):
|
||||
self.room_title = room_info['data']['room_info']['title']
|
||||
custom_api = config.get('bili_liveapi') is not None
|
||||
# 当 Cookie 存在,并且自定义APi使用Cookie开关关闭时,仅使用官方 Api
|
||||
if config.get('user', {}).get('bili_cookie') and self.customAPI_use_cookie is not True:
|
||||
if config.get('user', {}).get('bili_cookie') and self.customAPI_use_cookie is not True:
|
||||
custom_api = False
|
||||
play_info = get_play_info(s, custom_api, official_api_host, params)
|
||||
if play_info['code'] != 0:
|
||||
@@ -78,78 +78,72 @@ class Bilibili(DownloadBase):
|
||||
streams = play_info['data']['playurl_info']['playurl']['stream']
|
||||
live_start_time = room_info['data']['room_info']['live_start_time']
|
||||
if protocol == "stream":
|
||||
stream = streams[0]
|
||||
stream = streams[0]
|
||||
stream_info = stream['format'][0]['codec'][0]
|
||||
elif protocol == "hls_ts" or "hls":
|
||||
stream = streams[1]
|
||||
elif protocol == "hls_ts" or protocol == "hls":
|
||||
stream = streams[1]
|
||||
stream_info = stream['format'][0]['codec'][0]
|
||||
elif protocol == "hls_fmp4":
|
||||
try:
|
||||
stream = streams[1]
|
||||
stream_info = stream['format'][1]['codec'][0]
|
||||
logger.error(f"获取到{uname}房间的fmp4流")
|
||||
stream = streams[1]
|
||||
stream_info = stream['format'][1]['codec'][0]
|
||||
logger.debug(f"获取到{uname}房间的fmp4流")
|
||||
except:
|
||||
now_timestamp = int(time.time())
|
||||
if now_timestamp - live_start_time <= 45: #等待45s,如果还没有fmp4流就回退到flv流
|
||||
if now_timestamp - live_start_time <= 45: # 等待45s,如果还没有fmp4流就回退到flv流
|
||||
return False
|
||||
else:
|
||||
stream = streams[0]
|
||||
stream_info = stream['format'][0]['codec'][0]
|
||||
logger.error(f"获取{uname}房间fmp4流失败,回退到flv流")
|
||||
self.raw_stream_url = stream_info['url_info'][0]['host'] + stream_info['base_url'] \
|
||||
+ stream_info['url_info'][0]['extra']
|
||||
find = False
|
||||
for url_info in stream_info['url_info']:
|
||||
# 跳过p2pCDN
|
||||
if 'mcdn' in url_info['host']:
|
||||
continue
|
||||
# 哔哩哔哩直播强制原画(仅限HLS_ts流的 cn-gotcha01 CDN). 并且仅当主播有二压的时候才自动去掉m3u8的_bluray前缀,避免stream-gears的疯狂分段bug
|
||||
if force_source is True and "cn-gotcha01" in url_info['extra'] and "_bluray.m3u8" in stream_info['base_url']:
|
||||
stream_info['base_url'] = re.sub(r'_bluray(?=.*m3u8)', "", stream_info['base_url'])
|
||||
find = True
|
||||
# 强制替换cn-gotcha01的节点为指定节点 注意:只有大陆ip才能获取到cn-gotcha01的节点。
|
||||
if force_cn01_domain and "cn-gotcha01" in perf_cdn:
|
||||
i = 0
|
||||
while i < 6: # 测试随机到的节点是否可用
|
||||
random_choice = random.choice(force_cn01_domain.split(","))
|
||||
i += 1
|
||||
try: # 发起 HEAD 请求,并获取响应状态码
|
||||
status_code = s.get(f"https://{random_choice}{stream_info['base_url']}{url_info['extra']}",
|
||||
stream=True).status_code
|
||||
if status_code == 200: # 如果响应状态码是 200,跳出循环
|
||||
break
|
||||
except requests.exceptions.ConnectionError: # 如果发生连接异常,继续下一次循环
|
||||
logger.debug(f"随机到的域名 {random_choice} 无法访问,尝试重新发起随机。")
|
||||
continue
|
||||
else:
|
||||
logger.error(f"强制替换hls流的cn-gotcha01的节点为指定节点失败啦")
|
||||
return False
|
||||
logger.debug(f"随机到的域名 {random_choice} 返回了 200 状态码。")
|
||||
url_info['host'] = "https://" + random_choice
|
||||
find = True
|
||||
# 强制替换ov05 302redirect之后的真实地址为指定的域名或ip达到自选ov05节点的目的
|
||||
if force_ov05_ip and "ov-gotcha05" in url_info['host']:
|
||||
response = requests.get(url_info['host'] + stream_info['base_url'] + url_info['extra'])
|
||||
self.raw_stream_url = re.sub(r"https://([a-z0-9]+)\.ourdvsss\.com", f"http://{force_ov05_ip}",
|
||||
response.url)
|
||||
logger.debug(f"将ov-gotcha05的节点ip替换为了{force_ov05_ip}")
|
||||
break
|
||||
# 匹配PerfCDN
|
||||
stream = streams[0]
|
||||
stream_info = stream['format'][0]['codec'][0]
|
||||
logger.debug(f"获取{uname}房间fmp4流失败,回退到flv流")
|
||||
found_perf_cdn = False #优选CDN节点
|
||||
for url_info in stream_info['url_info']:
|
||||
if perf_cdn and perf_cdn in url_info['extra']:
|
||||
find = True
|
||||
logger.debug(f"获取到{url_info['host']}节点,找到了prefCDN")
|
||||
self.raw_stream_url = url_info['host'] + stream_info['base_url'] + url_info['extra']
|
||||
if find:
|
||||
found_perf_cdn = True
|
||||
logger.debug(f"找到了perfCDN{url_info['extra']}")
|
||||
break
|
||||
if self.bili_cdn_fallback is False:
|
||||
return True
|
||||
stream_info['url_info'].reverse()
|
||||
# 检查直播流是否可用以倒叙尝试回退
|
||||
for stream_url in stream_info['url_info']:
|
||||
self.raw_stream_url = stream_url['host'] + stream_info['base_url'] + stream_url['extra']
|
||||
if s.get(self.raw_stream_url, stream=True).status_code == 404:
|
||||
if not found_perf_cdn: #没找到优选CDN就回到第一个节点
|
||||
url_info['host'] = stream_info['url_info'][0]['host']
|
||||
url_info['extra'] = stream_info['url_info'][0]['extra']
|
||||
logger.debug(f"没找到perfCDN哦")
|
||||
# 哔哩哔哩直播强制原画(仅限HLS_ts流的 cn-gotcha01 CDN). 并且仅当主播有二压的时候才自动去掉m3u8的_bluray前缀,避免stream-gears的疯狂分段bug
|
||||
if force_source is True and "cn-gotcha01" in url_info['extra'] and "_bluray.m3u8" in stream_info['base_url']:
|
||||
stream_info['base_url'] = re.sub(r'_bluray(?=.*m3u8)', "", stream_info['base_url'])
|
||||
# 强制替换cn-gotcha01的节点为指定节点 注意:只有大陆ip才能获取到cn-gotcha01的节点。
|
||||
if force_cn01_domain and "cn-gotcha01" in url_info['extra']:
|
||||
i = 0
|
||||
while i < 6: # 测试随机到的节点是否可用
|
||||
random_choice = random.choice(force_cn01_domain.split(","))
|
||||
i += 1
|
||||
try: # 发起 GET 请求,并获取响应状态码
|
||||
status_code = s.get(f"https://{random_choice}{stream_info['base_url']}{url_info['extra']}",
|
||||
stream=True).status_code
|
||||
if status_code == 200: # 如果响应状态码是 200,跳出循环
|
||||
break
|
||||
except requests.exceptions.ConnectionError: # 如果发生连接异常,继续下一次循环
|
||||
logger.debug(f"随机到的域名 {random_choice} 无法访问,尝试重新发起随机。")
|
||||
continue
|
||||
break
|
||||
else:
|
||||
logger.error(f"强制替换hls流的cn-gotcha01的节点为指定节点失败啦")
|
||||
return False
|
||||
logger.debug(f"随机到的域名 {random_choice} 返回了 200 状态码。")
|
||||
url_info['host'] = "https://" + random_choice
|
||||
# 强制替换ov05 302redirect之后的真实地址为指定的域名或ip达到自选ov05节点的目的
|
||||
if force_ov05_ip and "ov-gotcha05" in url_info['host']:
|
||||
response = requests.get(url_info['host'] + stream_info['base_url'] + url_info['extra'])
|
||||
self.raw_stream_url = re.sub(r"https://([a-z0-9]+)\.ourdvsss\.com", f"http://{force_ov05_ip}",
|
||||
response.url)
|
||||
logger.debug(f"将ov-gotcha05的节点ip替换为了{force_ov05_ip}")
|
||||
self.raw_stream_url = url_info['host'] + stream_info['base_url'] + url_info['extra']
|
||||
if self.bili_cdn_fallback is False:
|
||||
return True
|
||||
stream_info['url_info'].reverse()
|
||||
# 检查直播流是否可用以倒叙尝试回退
|
||||
for stream_url in stream_info['url_info']:
|
||||
self.raw_stream_url = stream_url['host'] + stream_info['base_url'] + stream_url['extra']
|
||||
if s.get(self.raw_stream_url, stream=True).status_code == 404:
|
||||
continue
|
||||
break
|
||||
return True
|
||||
|
||||
async def danmaku_download_start(self, filename):
|
||||
|
||||
+2
-2
@@ -14,12 +14,12 @@ dependencies = [
|
||||
"stream-gears >= 0.1.15",
|
||||
"psutil >= 5.4.6",
|
||||
"aiofiles >= 22.1.0",
|
||||
"yt_dlp >= 2022.3.8.2",
|
||||
"yt_dlp >= 2023.3.3",
|
||||
"Pillow >= 5.2.0",
|
||||
"aiohttp[speedups]",
|
||||
"Requests >= 2.20.0",
|
||||
"PyYAML >= 4.2b1",
|
||||
"streamlink >= 0.14.2",
|
||||
"streamlink >= 5.3.0",
|
||||
"ykdl >= 1.8.0",
|
||||
"rsa >= 4.6",
|
||||
'importlib-resources; python_version<"3.9"',
|
||||
|
||||
Reference in new issue
Block a user