mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 14:45:14 +00:00 
			
		
		
		
	| @@ -18,6 +18,7 @@ from ..utils import ( | ||||
|     float_or_none, | ||||
|     mimetype2ext, | ||||
|     parse_iso8601, | ||||
|     qualities, | ||||
|     traverse_obj, | ||||
|     parse_count, | ||||
|     smuggle_url, | ||||
| @@ -996,3 +997,88 @@ class BiliIntlSeriesIE(BiliIntlBaseIE): | ||||
|             self._entries(series_id), series_id, series_info.get('title'), series_info.get('description'), | ||||
|             categories=traverse_obj(series_info, ('styles', ..., 'title'), expected_type=str_or_none), | ||||
|             thumbnail=url_or_none(series_info.get('horizontal_cover')), view_count=parse_count(series_info.get('view'))) | ||||
| 
 | ||||
| 
 | ||||
| class BiliLiveIE(InfoExtractor): | ||||
|     _VALID_URL = r'https?://live.bilibili.com/(?P<id>\d+)' | ||||
| 
 | ||||
|     _TESTS = [{ | ||||
|         'url': 'https://live.bilibili.com/196', | ||||
|         'info_dict': { | ||||
|             'id': '33989', | ||||
|             'description': "周六杂谈回,其他时候随机游戏。 | \n录播:@下播型泛式录播组。 | \n直播通知群(全员禁言):666906670,902092584,59971⑧481 (功能一样,别多加)", | ||||
|             'ext': 'flv', | ||||
|             'title': "太空狼人杀联动,不被爆杀就算赢", | ||||
|             'thumbnail': "https://i0.hdslb.com/bfs/live/new_room_cover/e607bc1529057ef4b332e1026e62cf46984c314d.jpg", | ||||
|             'timestamp': 1650802769, | ||||
|         }, | ||||
|         'skip': 'not live' | ||||
|     }, { | ||||
|         'url': 'https://live.bilibili.com/196?broadcast_type=0&is_room_feed=1?spm_id_from=333.999.space_home.strengthen_live_card.click', | ||||
|         'only_matching': True | ||||
|     }] | ||||
| 
 | ||||
|     _FORMATS = { | ||||
|         80: {'format_id': 'low', 'format_note': '流畅'}, | ||||
|         150: {'format_id': 'high_res', 'format_note': '高清'}, | ||||
|         250: {'format_id': 'ultra_high_res', 'format_note': '超清'}, | ||||
|         400: {'format_id': 'blue_ray', 'format_note': '蓝光'}, | ||||
|         10000: {'format_id': 'source', 'format_note': '原画'}, | ||||
|         20000: {'format_id': '4K', 'format_note': '4K'}, | ||||
|         30000: {'format_id': 'dolby', 'format_note': '杜比'}, | ||||
|     } | ||||
| 
 | ||||
|     _quality = staticmethod(qualities(list(_FORMATS))) | ||||
| 
 | ||||
|     def _call_api(self, path, room_id, query): | ||||
|         api_result = self._download_json(f'https://api.live.bilibili.com/{path}', room_id, query=query) | ||||
|         if api_result.get('code') != 0: | ||||
|             raise ExtractorError(api_result.get('message') or 'Unable to download JSON metadata') | ||||
|         return api_result.get('data') or {} | ||||
| 
 | ||||
|     def _parse_formats(self, qn, fmt): | ||||
|         for codec in fmt.get('codec') or []: | ||||
|             if codec.get('current_qn') != qn: | ||||
|                 continue | ||||
|             for url_info in codec['url_info']: | ||||
|                 yield { | ||||
|                     'url': f'{url_info["host"]}{codec["base_url"]}{url_info["extra"]}', | ||||
|                     'ext': fmt.get('format_name'), | ||||
|                     'vcodec': codec.get('codec_name'), | ||||
|                     'quality': self._quality(qn), | ||||
|                     **self._FORMATS[qn], | ||||
|                 } | ||||
| 
 | ||||
|     def _real_extract(self, url): | ||||
|         room_id = self._match_id(url) | ||||
|         room_data = self._call_api('room/v1/Room/get_info', room_id, {'id': room_id}) | ||||
|         if room_data.get('live_status') == 0: | ||||
|             raise ExtractorError('Streamer is not live', expected=True) | ||||
| 
 | ||||
|         formats = [] | ||||
|         for qn in self._FORMATS.keys(): | ||||
|             stream_data = self._call_api('xlive/web-room/v2/index/getRoomPlayInfo', room_id, { | ||||
|                 'room_id': room_id, | ||||
|                 'qn': qn, | ||||
|                 'codec': '0,1', | ||||
|                 'format': '0,2', | ||||
|                 'mask': '0', | ||||
|                 'no_playurl': '0', | ||||
|                 'platform': 'web', | ||||
|                 'protocol': '0,1', | ||||
|             }) | ||||
|             for fmt in traverse_obj(stream_data, ('playurl_info', 'playurl', 'stream', ..., 'format', ...)) or []: | ||||
|                 formats.extend(self._parse_formats(qn, fmt)) | ||||
|         self._sort_formats(formats) | ||||
| 
 | ||||
|         return { | ||||
|             'id': room_id, | ||||
|             'title': room_data.get('title'), | ||||
|             'description': room_data.get('description'), | ||||
|             'thumbnail': room_data.get('user_cover'), | ||||
|             'timestamp': stream_data.get('live_time'), | ||||
|             'formats': formats, | ||||
|             'http_headers': { | ||||
|                 'Referer': url, | ||||
|             }, | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 HE7086
					HE7086