diff --git a/biliup/engine/download.py b/biliup/engine/download.py index 715a47f..81ff4c5 100644 --- a/biliup/engine/download.py +++ b/biliup/engine/download.py @@ -146,7 +146,7 @@ class DownloadBase: else: filename = f'{self.fname}%Y-%m-%dT%H_%M_%S' filename = get_valid_filename(filename) - return f'{(time.strftime(filename).encode("unicode-escape").decode()).encode().decode("unicode-escape")}' + return time.strftime(filename.encode("unicode-escape").decode()).encode().decode("unicode-escape") def close(self): pass diff --git a/biliup/plugins/bilibili.py b/biliup/plugins/bilibili.py index bc2e1cc..a03174f 100644 --- a/biliup/plugins/bilibili.py +++ b/biliup/plugins/bilibili.py @@ -13,8 +13,8 @@ class Bilibili(DownloadBase): super().__init__(fname, url, suffix) self.fake_headers['Referer'] = 'https://live.bilibili.com' if config.get('user', {}).get('bili_cookie'): - self.fake_headers['cookie'] = config.get('user', {}).get('bili_cookie') - self.customAPI_use_cookie = config.get('user', {}).get('customAPI_use_cookie', False) + self.fake_headers['cookie'] = config.get('user', {}).get('bili_cookie') + self.customAPI_use_cookie = config.get('user', {}).get('customAPI_use_cookie') self.bili_cdn_fallback = config.get('bili_cdn_fallback', True) def check_stream(self): @@ -30,73 +30,72 @@ class Bilibili(DownloadBase): 'dolby': '5', 'panorama': '1' } - officialApiHost = "https://api.live.bilibili.com" protocol = config.get('bili_protocol', 'stream') - perfCDN = config.get('bili_perfCDN', '') - forceScoure = config.get('bili_forceScoure', False) - customApiHost = (lambda a : a if a.startswith(('http://', 'https://')) else 'http://'+a)(config.get('bili_liveapi', officialApiHost).rstrip('/')) - s = requests.Session() - s.headers = self.fake_headers.copy() + perf_cdn = config.get('bili_perfCDN') + force_source = config.get('bili_force_source') + official_api_host = "https://api.live.bilibili.com" - with s: + with requests.Session() as s: + s.headers = self.fake_headers.copy() # 获取直播状态与房间标题 - infoByRoomUrl = f"{officialApiHost}/xlive/web-room/v1/index/getInfoByRoom?room_id={params['room_id']}" + info_by_room_url = f"{official_api_host}/xlive/web-room/v1/index/getInfoByRoom?room_id={params['room_id']}" try: - roomInfo = s.get(infoByRoomUrl, timeout=5).json() - except requests.exceptions.ConnectionError as ce: - logger.error(ce) - logger.error(f"在连接到 {infoByRoomUrl} 时出现错误") + room_info = s.get(info_by_room_url, timeout=5).json() + except requests.exceptions.ConnectionError: + logger.error(f"在连接到 {info_by_room_url} 时出现错误") return False - if roomInfo['code'] != 0 or roomInfo['data']['room_info']['live_status'] != 1: - logger.debug(roomInfo['message']) + if room_info['code'] != 0 or room_info['data']['room_info']['live_status'] != 1: + logger.debug(room_info['message']) return False - params['room_id'] = roomInfo['data']['room_info']['room_id'] - self.room_title = roomInfo['data']['room_info']['title'] + params['room_id'] = room_info['data']['room_info']['room_id'] + 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 False: - roomPlayInfoUrl = officialApiHost - else: - roomPlayInfoUrl = customApiHost - roomPlayInfoUrl += '/xlive/web-room/v2/index/getRoomPlayInfo' - - # 尝试获取直播流 - try: - playInfo = s.get(roomPlayInfoUrl, params=params, timeout=5).json() - except requests.exceptions.ConnectionError as ce: - logger.error(ce) - logger.error(f"{customApiHost}连接失败,尝试回退至官方Api") - roomPlayInfoUrl = f"{officialApiHost}/xlive/web-room/v2/index/getRoomPlayInfo" - playInfo = s.get(roomPlayInfoUrl, params=params, timeout=5).json() - if playInfo['code'] != 0: - logger.debug(playInfo['message']) + 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: + logger.debug(play_info['message']) return False - streams = playInfo['data']['playurl_info']['playurl']['stream'] + streams = play_info['data']['playurl_info']['playurl']['stream'] stream = streams[1] if "hls" in protocol else streams[0] - ### 直播开启后需要约 2Min 缓冲时间以提供 Hevc 编码 与 fmp4 封装,故仅使用 Avc 编码 + # 直播开启后需要约 2Min 缓冲时间以提供 Hevc 编码 与 fmp4 封装,故仅使用 Avc 编码 stream_info = stream['format'][0]['codec'][0] - self.raw_stream_url = stream_info['url_info'][0]['host']+stream_info['base_url']+stream_info['url_info'][0]['extra'] + self.raw_stream_url = stream_info['url_info'][0]['host'] + stream_info['base_url'] \ + + stream_info['url_info'][0]['extra'] for url_info in stream_info['url_info']: # 跳过p2pCDN if 'mcdn' in url_info['host']: continue # 匹配PerfCDN - if perfCDN and perfCDN in url_info['extra']: - if forceScoure is True and "cn-gotcha01" in perfCDN: - stream_info['base_url'] = re.sub(r'\_bluray(?=.*m3u8)', "", stream_info['base_url']) - self.raw_stream_url = url_info['host']+stream_info['base_url']+url_info['extra'] - logger.debug(f"获取到{url_info['host']}节点,找到了prefCDN") + if perf_cdn and perf_cdn in url_info['extra']: + if force_source is True and "cn-gotcha01" in perf_cdn: + stream_info['base_url'] = re.sub(r'_bluray(?=.*m3u8)', "", stream_info['base_url']) + self.raw_stream_url = url_info['host'] + stream_info['base_url'] + url_info['extra'] + logger.debug(f"获取到{url_info['host']}节点,找到了prefCDN") break - self.raw_stream_url = url_info['host']+stream_info['base_url']+url_info['extra'] - index = 0 - if self.bili_cdn_fallback is True: - # 检查直播流是否可用 - while s.head(self.raw_stream_url, stream=True).status_code == 404: - # 以顺序尝试回退 - if stream_info['url_info'][index]['host'] in self.raw_stream_url: - index+=1 - try: - url_info = stream_info['url_info'][index] - self.raw_stream_url = url_info['host']+stream_info['base_url']+url_info['extra'] - except Exception: # 如之后的节点无可用直播流,回退到 flv 的首个链接 - logger.debug(f"顺序回退尝试失败,回退到 flv 的首个链接{stream_info['url_info'][0]['host']}尝试下载") + 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 + + +def get_play_info(s, custom_api, official_api_host, params): + if custom_api: + custom_api_host = \ + (lambda a: a if a.startswith(('http://', 'https://')) else 'http://' + a)(config.get('bili_liveapi') + .rstrip('/')) + # 尝试获取直播流 + try: + return s.get(custom_api_host + '/xlive/web-room/v2/index/getRoomPlayInfo', params=params, + timeout=5).json() + except requests.exceptions.ConnectionError: + logger.error(f"{custom_api_host}连接失败,尝试回退至官方Api") + return s.get(official_api_host + '/xlive/web-room/v2/index/getRoomPlayInfo', params=params, timeout=5).json() diff --git a/biliup/uploader.py b/biliup/uploader.py index 5e86957..2f00a52 100644 --- a/biliup/uploader.py +++ b/biliup/uploader.py @@ -28,7 +28,6 @@ def upload(data): data["format_title"] = custom_fmtstr(context.get('title', f'%Y.%m.%d{index}'), date, room_title, streamers) if context.get('description'): context['description'] = custom_fmtstr(context.get('description'), date, room_title, streamers) - print(context['description']) threshold = config.get('filtering_threshold') if threshold: data['threshold'] = threshold