From c86f3a76f356608158a51645dced8a224d231f75 Mon Sep 17 00:00:00 2001 From: ihmily <961532186@qq.com> Date: Sun, 21 Jul 2024 16:11:13 +0800 Subject: [PATCH] feat: optimize bilibili live stream fetch --- main.py | 85 +++++++++++++++++-------------------------------------- spider.py | 63 ++++++++++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 82 deletions(-) diff --git a/main.py b/main.py index ae73156..ac1046a 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ Author: Hmily GitHub: https://github.com/ihmily Date: 2023-07-17 23:52:05 -Update: 2024-07-15 22:55:29 +Update: 2024-07-20 20:41:12 Copyright (c) 2023-2024 by Hmily, All Rights Reserved. Function: Record live stream video. """ @@ -38,6 +38,7 @@ from spider import ( get_douyu_stream_data, get_yy_stream_data, get_bilibili_stream_data, + get_bilibili_room_info, get_xhs_stream_url, get_bigo_stream_url, get_blued_stream_url, @@ -539,66 +540,32 @@ def get_yy_stream_url(json_data: dict) -> Dict[str, Any]: @trace_error_decorator def get_bilibili_stream_url(json_data: dict, video_quality: str) -> Dict[str, Any]: - if "is_live" in json_data and not json_data['anchor_name']: - return json_data - - anchor_name = json_data['anchor_name'] - playurl_info = json_data['stream_data']['playurl_info'] - result = { - "anchor_name": anchor_name, - "is_live": False, - } - if playurl_info: - # 其中qn=30000为杜比 20000为4K 10000为原画 400蓝光 250超清 150高清 80流畅 - quality_list = {'10000': 'bluray', '400': '4000', '250': '2500', '150': '1500', '80': '800'} - format_list = playurl_info['playurl']['stream'][1]['format'] - current_qn = format_list[0]['codec'][0]['current_qn'] - if int(current_qn) != 10000 and len(format_list) > 1: - stream_data = format_list[1]['codec'][0] - else: - stream_data = format_list[0]['codec'][0] - accept_qn_list = stream_data['accept_qn'] - qn_count = len(accept_qn_list) - if 10000 not in accept_qn_list: - new_accept_qn_list = [10000] + accept_qn_list - else: - new_accept_qn_list = [i for i in accept_qn_list] - while len(new_accept_qn_list) < 5: - new_accept_qn_list.append(new_accept_qn_list[-1]) - - video_quality_options = { - "原画": 0, - "蓝光": 1, - "超清": 2, - "高清": 3, - "标清": 4, - "流畅": 4 + anchor_name = json_data["anchor_name"] + if not json_data["live_status"]: + return { + "anchor_name": anchor_name, + "is_live": False } - select_quality = new_accept_qn_list[video_quality_options[video_quality]] - select_quality = quality_list[str(select_quality)] - base_url = stream_data['base_url'] - host = stream_data['url_info'][0]['host'] - extra = stream_data['url_info'][0]['extra'] - if int(current_qn) != 10000 and qn_count > 1: - if (qn_count == 2 and 10000 not in accept_qn_list) or qn_count > 2: - live_key = base_url.split('/')[3] - live_key_list = live_key.split('_') - if len(live_key_list) == 4: - live_key_list[3] = select_quality - else: - live_key_list.append(select_quality) + room_url = json_data['room_url'] - new_live_key = '_'.join(live_key_list) - base_url = re.sub(live_key, new_live_key, base_url) - extra = re.sub(live_key, new_live_key, extra) - time_at = int(time.time()) + 10800 - extra = re.sub(r"expires=[0-9]+&len=", f"expires={time_at}&len=", extra) + video_quality_options = { + "原画": '10000', + "蓝光": '400', + "超清": '250', + "高清": '150', + "标清": '80', + "流畅": '80' + } - m3u8_url = host + base_url + extra - result['is_live'] = True - result['record_url'] = m3u8_url # B站使用m3u8链接进行录制 - return result + select_quality = video_quality_options[video_quality] + play_url = get_bilibili_stream_data(room_url, qn=select_quality, platform='web', proxy_addr=proxy_addr, + cookies=bili_cookie) + return { + 'anchor_name': json_data['anchor_name'], + 'is_live': True, + 'record_url': play_url + } @trace_error_decorator @@ -773,7 +740,7 @@ def start_record(url_data: tuple, count_variable: int = -1): elif record_url.find("https://live.bilibili.com/") > -1: platform = 'B站直播' with semaphore: - json_data = get_bilibili_stream_data( + json_data = get_bilibili_room_info( url=record_url, proxy_addr=proxy_address, cookies=bili_cookie) port_info = get_bilibili_stream_url(json_data, record_quality) @@ -1898,4 +1865,4 @@ while True: first_run = False - time.sleep(3) \ No newline at end of file + time.sleep(3) diff --git a/spider.py b/spider.py index 5d623a3..a4666ec 100644 --- a/spider.py +++ b/spider.py @@ -4,7 +4,7 @@ Author: Hmily GitHub: https://github.com/ihmily Date: 2023-07-15 23:15:00 -Update: 2024-07-15 22:55:00 +Update: 2024-07-20 20:41:12 Copyright (c) 2023 by Hmily, All Rights Reserved. Function: Get live stream data. """ @@ -580,7 +580,7 @@ def get_yy_stream_data(url: str, proxy_addr: Union[str, None] = None, cookies: U @trace_error_decorator -def get_bilibili_stream_data(url: str, proxy_addr: Union[str, None] = None, cookies: Union[str, None] = None) -> \ +def get_bilibili_room_info(url: str, proxy_addr: Union[str, None] = None, cookies: Union[str, None] = None) -> \ Dict[str, Any]: headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0', @@ -590,31 +590,48 @@ def get_bilibili_stream_data(url: str, proxy_addr: Union[str, None] = None, cook if cookies: headers['Cookie'] = cookies - def get_data_from_api(rid: str) -> Dict[str, Any]: - api = f'https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo?room_id={rid}&no_playurl=0&mask=1&qn=0&platform=web&protocol=0,1&format=0,1,2&codec=0,1,2&dolby=5&panorama=1' - json_str = get_req(url=api, proxy_addr=proxy_addr, headers=headers) - return json.loads(json_str) - try: - html_str = get_req(url=url, proxy_addr=proxy_addr, headers=headers) - json_str = re.search('