Bumping version

This commit is contained in:
ForgQi committed 2024-03-22 23:56:44 +08:00
1 parent f11dbc59a7
commit 231b6d57df
3 files changed
+134 -137

No files matched your search

+1 -1
View File
@@ -2,7 +2,7 @@ import logging
import platform
import sys
__version__ = "0.4.44"
__version__ = "0.4.45"
LOG_CONF = {
'version': 1,
+1 -2
View File
@@ -53,9 +53,8 @@ class Config(UserDict):
for k, v in self['streamers'].items():
us = UploadStreamers(**UploadStreamers.filter_parameters(
{"template_name": k, "tags": v.pop('tags', ['biliup']), ** v}))
# us.save()
db.add(us)
# db.flush(us)
db.flush()
url = v.pop('url')
urls = url if isinstance(url, list) else [url] # 兼容 url 输入字符串和列表
for url in urls:
+132 -134
View File
@@ -15,10 +15,8 @@ class Bililive(DownloadBase):
self.live_time = 0
self.bilibili_danmaku = config.get('bilibili_danmaku', False)
self.fake_headers['referer'] = url
self.fake_headers['cookie'] = (
load_cookies(config.get('user', {}).get('bili_cookie_file')) or
config.get('user', {}).get('bili_cookie')
)
if config.get('user', {}).get('bili_cookie'):
self.fake_headers['cookie'] = config.get('user', {}).get('bili_cookie')
def check_stream(self, is_check=False):
@@ -28,13 +26,14 @@ class Bililive(DownloadBase):
plugin_msg = f"Bililive - {room_id}"
with requests.Session() as s:
s.headers = self.fake_headers.copy()
s.headers.update(self.fake_headers.copy())
load_cookies(s, config.get('user', {}).get('bili_cookie_file'))
# 获取直播状态与房间标题
info_by_room_url = f"{OFFICIAL_API}/xlive/web-room/v1/index/getInfoByRoom?room_id={room_id}"
try:
room_info = s.get(info_by_room_url, timeout=5).json()
except Exception as e:
logger.error(f"{plugin_msg}: {e}")
except Exception:
logger.exception(f"{plugin_msg}")
return False
if room_info['code'] != 0:
logger.error(f"{plugin_msg}: {room_info}")
@@ -52,137 +51,135 @@ class Bililive(DownloadBase):
else:
is_new_live = False
if is_check:
user_data = do_login(s).get('data', {})
_res = do_login(s)
user_data = _res.get('data', {})
is_login = user_data.get('isLogin', False)
if not is_login:
# logger.warning(f"{plugin_msg}: 登录态校验失败")
logger.debug(user_data)
logger.info("登录态校验失败: " + _res)
else:
logger.info(f"用户名:{user_data['uname']}, mid:{user_data['mid']}, isLogin:{is_login}")
return True
protocol = config.get('bili_protocol', 'stream')
perf_cdn = config.get('bili_perfCDN')
cdn_fallback = config.get('bili_cdn_fallback', True)
force_source = config.get('bili_force_source', False)
ov05_ip = config.get('bili_force_ov05_ip')
main_api = config.get('bili_liveapi', OFFICIAL_API).rstrip('/')
fallback_api = config.get('bili_fallback_api', OFFICIAL_API).rstrip('/')
protocol = config.get('bili_protocol', 'stream')
perf_cdn = config.get('bili_perfCDN')
cdn_fallback = config.get('bili_cdn_fallback', True)
force_source = config.get('bili_force_source', False)
ov05_ip = config.get('bili_force_ov05_ip')
main_api = config.get('bili_liveapi', OFFICIAL_API).rstrip('/')
fallback_api = config.get('bili_fallback_api', OFFICIAL_API).rstrip('/')
params = {
'room_id': room_id,
'protocol': '0,1',# 0: http_stream, 1: http_hls
'format': '0,1,2',# 0: flv, 1: ts, 2: fmp4
'codec': '0', # 0: avc, 1: hevc, 2: av1
'qn': qualityNumber,
'platform': 'html5', # web, html5, android, ios
# 'ptype': '8',
'dolby': '5',
# 'panorama': '1' # 全景(不支持 html5)
}
streamname_regexp = r"(live_\d+_\w+_\w+_?\w+?)" # 匹配 streamName
params = {
'room_id': room_id,
'protocol': '0,1',# 0: http_stream, 1: http_hls
'format': '0,1,2',# 0: flv, 1: ts, 2: fmp4
'codec': '0', # 0: avc, 1: hevc, 2: av1
'qn': qualityNumber,
'platform': 'html5', # web, html5, android, ios
# 'ptype': '8',
'dolby': '5',
# 'panorama': '1' # 全景(不支持 html5)
}
streamname_regexp = r"(live_\d+_\w+_\w+_?\w+?)" # 匹配 streamName
s = requests.Session()
s.headers = self.fake_headers
if self.raw_stream_url is not None \
and qualityNumber >= 10000 \
and not is_new_live:
# 同一个 streamName 即可复用,与其他参数无关,目前没有报告说链接会超时失效。
# 前面拿不到 streamName,目前使用开播时间判断
health, url = super().check_url_healthy(s, self.raw_stream_url)
if health:
logger.debug(f"{plugin_msg}: 复用 {url}")
s.close()
return True
else:
self.raw_stream_url = None
try:
play_info = get_play_info(s, main_api, params)
if play_info is None or check_areablock(play_info['data']['playurl_info']['playurl']):
logger.debug(f"{plugin_msg}: {main_api} 返回 {play_info}")
play_info = get_play_info(s, fallback_api, params)
if play_info is None or check_areablock(play_info['data']['playurl_info']['playurl']):
logger.debug(f"{plugin_msg}: {fallback_api} 返回 {play_info}")
return False
except Exception as e:
logger.error(f"{plugin_msg}: {e}")
return False
if play_info['code'] != 0:
logger.error(f"{plugin_msg}: {play_info}")
return False
playurl_info = play_info['data']['playurl_info']['playurl']
streams = playurl_info['stream']
stream = streams[1] if protocol.startswith('hls') and len(streams) > 1 else streams[0]
stream_format = stream['format'][0]
if protocol == "hls_fmp4":
if len(stream['format']) > 1:
stream_format = stream['format'][1]
elif int(time.time()) - live_start_time <= 60: # 60s 宽容等待 fmp4
return False
elif stream_format['format_name'] == 'ts':
stream_format = streams[0]['format'][0]
stream_info = stream_format['codec'][0]
stream_url = {
'base_url': stream_info['base_url'],
}
if perf_cdn is not None:
perf_cdn_list = perf_cdn.split(',')
for url_info in stream_info['url_info']:
if 'host' in stream_url:
break
for cdn in perf_cdn_list:
if cdn in url_info['extra']:
stream_url['host'] = url_info['host']
stream_url['extra'] = url_info['extra']
logger.debug(f"Found {stream_url['host']}")
break
if len(stream_url) < 3:
stream_url['host'] = stream_info['url_info'][-1]['host']
stream_url['extra'] = stream_info['url_info'][-1]['extra']
# 移除 streamName 内画质标签
streamName = match1(stream_url['base_url'], streamname_regexp)
if streamName is not None and force_source and qualityNumber >= 10000:
new_base_url = stream_url['base_url'].replace(f"_{streamName.split('_')[-1]}", '')
if super().check_url_healthy(s, f"{stream_url['host']}{new_base_url}{stream_url['extra']}"):
stream_url['base_url'] = new_base_url
logger.debug(stream_url['base_url'])
self.raw_stream_url = f"{stream_url['host']}{stream_url['base_url']}{stream_url['extra']}"
if ov05_ip and "ov-gotcha05" in stream_url['host']:
self.raw_stream_url = oversea_expand(s, self.raw_stream_url, ov05_ip)
url_health, url = super().check_url_healthy(s, self.raw_stream_url)
if not url_health:
if cdn_fallback:
i = len(stream_info['url_info'])
while i:
i -= 1
try:
self.raw_stream_url = "{}{}{}".format(stream_info['url_info'][i]['host'], stream_url['base_url'], stream_info['url_info'][i]['extra'])
url_health, url = super().check_url_healthy(s, self.raw_stream_url)
if url_health:
self.raw_stream_url = url
break
except Exception as e:
logger.debug(e)
continue
finally:
logger.debug(f"{i} - {self.raw_stream_url}")
if self.raw_stream_url is not None \
and qualityNumber >= 10000 \
and not is_new_live:
# 同一个 streamName 即可复用,与其他参数无关,目前没有报告说链接会超时失效。
# 前面拿不到 streamName,目前使用开播时间判断
health, url = super().check_url_healthy(s, self.raw_stream_url)
if health:
logger.debug(f"{plugin_msg}: 复用 {url}")
return True
else:
logger.debug(play_info)
self.raw_stream_url = None
return False
else:
self.raw_stream_url = url
s.close()
return True
try:
play_info = get_play_info(s, main_api, params)
if play_info is None or check_areablock(play_info['data']['playurl_info']['playurl']):
logger.debug(f"{plugin_msg}: {main_api} 返回 {play_info}")
play_info = get_play_info(s, fallback_api, params)
if play_info is None or check_areablock(play_info['data']['playurl_info']['playurl']):
logger.debug(f"{plugin_msg}: {fallback_api} 返回 {play_info}")
return False
except Exception:
logger.exception(f"{plugin_msg}")
return False
if play_info['code'] != 0:
logger.error(f"{plugin_msg}: {play_info}")
return False
playurl_info = play_info['data']['playurl_info']['playurl']
streams = playurl_info['stream']
stream = streams[1] if protocol.startswith('hls') and len(streams) > 1 else streams[0]
stream_format = stream['format'][0]
if protocol == "hls_fmp4":
if len(stream['format']) > 1:
stream_format = stream['format'][1]
elif int(time.time()) - live_start_time <= 60: # 60s 宽容等待 fmp4
return False
elif stream_format['format_name'] == 'ts':
stream_format = streams[0]['format'][0]
stream_info = stream_format['codec'][0]
stream_url = {
'base_url': stream_info['base_url'],
}
if perf_cdn is not None:
perf_cdn_list = perf_cdn.split(',')
for url_info in stream_info['url_info']:
if 'host' in stream_url:
break
for cdn in perf_cdn_list:
if cdn in url_info['extra']:
stream_url['host'] = url_info['host']
stream_url['extra'] = url_info['extra']
logger.debug(f"Found {stream_url['host']}")
break
if len(stream_url) < 3:
stream_url['host'] = stream_info['url_info'][-1]['host']
stream_url['extra'] = stream_info['url_info'][-1]['extra']
# 移除 streamName 内画质标签
streamName = match1(stream_url['base_url'], streamname_regexp)
if streamName is not None and force_source and qualityNumber >= 10000:
new_base_url = stream_url['base_url'].replace(f"_{streamName.split('_')[-1]}", '')
if super().check_url_healthy(s, f"{stream_url['host']}{new_base_url}{stream_url['extra']}"):
stream_url['base_url'] = new_base_url
logger.debug(stream_url['base_url'])
self.raw_stream_url = f"{stream_url['host']}{stream_url['base_url']}{stream_url['extra']}"
if ov05_ip and "ov-gotcha05" in stream_url['host']:
self.raw_stream_url = oversea_expand(s, self.raw_stream_url, ov05_ip)
url_health, url = super().check_url_healthy(s, self.raw_stream_url)
if not url_health:
if cdn_fallback:
i = len(stream_info['url_info'])
while i:
i -= 1
try:
self.raw_stream_url = "{}{}{}".format(stream_info['url_info'][i]['host'], stream_url['base_url'], stream_info['url_info'][i]['extra'])
url_health, url = super().check_url_healthy(s, self.raw_stream_url)
if url_health:
self.raw_stream_url = url
break
except Exception as e:
logger.debug(e)
continue
finally:
logger.debug(f"{i} - {self.raw_stream_url}")
else:
logger.debug(play_info)
self.raw_stream_url = None
return False
else:
self.raw_stream_url = url
return True
def danmaku_download_start(self, filename):
if self.bilibili_danmaku:
@@ -216,8 +213,8 @@ def check_areablock(data):
def do_login(s):
try:
return s.get('https://api.bilibili.com/x/web-interface/nav', timeout=5).json()
except Exception as e:
logger.error('Bililive: ' + e)
except Exception:
logger.exception('Bililive do_login')
return {}
def oversea_expand(s, url, ov05_ip):
@@ -227,15 +224,16 @@ def oversea_expand(s, url, ov05_ip):
logger.debug(f'将ov-gotcha05的节点ip替换为了{ov05_ip}')
return re.sub(r".*(?=/d1--ov-gotcha05)", f"http://{ov05_ip}", r.url, 1)
def load_cookies(filename):
def load_cookies(session, filename):
if filename is not None:
try:
cookies = ""
# cookies = ""
with open(filename, encoding='utf-8') as stream:
s = json.load(stream)
for i in s["cookie_info"]["cookies"]:
cookies += "{}={};".format(i['name'], i['value'])
return cookies
except Exception as e:
logger.exception(e)
return None
session.cookies.set(i['name'], i['value'])
# cookies += "{}={};".format(i['name'], i['value'])
return True
except Exception:
logger.exception("load_cookies error")
return False